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 
32 namespace lely {
33 namespace io {
34 
35 namespace detail {
36 
37 template <class F>
39  public:
40  CanRouterReadFrameWrapper(uint_least32_t id, CanFlag flags, F&& f)
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 
72 template <class F>
73 inline typename ::std::enable_if<
76 make_can_router_read_frame_wrapper(uint_least32_t id, CanFlag flags, F&& f) {
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>
93  CanRouterReadFrame(uint_least32_t id, CanFlag flags, F&& f)
95  id, static_cast<uint_least8_t>(flags),
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
116  get_executor() const noexcept {
117  return ev::Executor(task.exec);
118  }
119 
120  private:
121  ::std::function<Signature> func_;
122 };
123 
124 namespace detail {
125 
126 template <class F>
128  public:
131  auto read = io_can_rt_read_err_from_task(task);
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 
142 
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 
159 template <class F>
160 inline typename ::std::enable_if<
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>
181  auto read = io_can_rt_read_err_from_task(task);
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
200  get_executor() const noexcept {
201  return ev::Executor(task.exec);
202  }
203 
204  private:
205  ::std::function<Signature> func_;
206 };
207 
209 class 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
246  get_channel() const noexcept {
247  return CanChannelBase(io_can_rt_get_chan(*this));
248  }
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
259  submit_read_frame(uint_least32_t id, CanFlag flags, F&& f) {
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 
278  async_read_frame(uint_least32_t id, CanFlag flags,
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
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 
315  async_read_error(struct io_can_rt_read_err** pread_err = nullptr) {
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_
can_rt.h
io_can_rt_submit_read_msg
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
ev_exec_t
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
Definition: ev.h:29
lely::io::CanRouter::~CanRouter
~CanRouter()
Definition: can_rt.hpp:240
io_can_rt_destroy
void io_can_rt_destroy(io_can_rt_t *rt)
Destroys a CAN frame router.
Definition: can_rt.c:252
io_can_rt_get_dev
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
can_msg
A CAN or CAN FD format frame.
Definition: msg.h:87
io_can_rt
Definition: can_rt.c:64
io_can_rt_async_read_msg
ev_future_t * io_can_rt_async_read_msg(io_can_rt_t *rt, uint_least32_t id, uint_least8_t flags, struct io_can_rt_read_msg **pread_msg)
Submits an asynchronous CAN frame read operation to a CAN frame router and creates a future which bec...
Definition: can_rt.c:365
lely::io::detail::CanRouterReadErrorWrapper
Definition: can_rt.hpp:127
lely::io::CanRouter::CanRouter
CanRouter(io_can_chan_t *chan, ev_exec_t *exec)
Definition: can_rt.hpp:214
lely::io::CanRouter::async_shutdown
ev::Future< void, void > async_shutdown()
Definition: can_rt.hpp:323
lely::io::CanRouterReadError
A CAN error frame read operation suitable for use with a CAN frame router.
Definition: can_rt.hpp:173
lely::io::CanChannelBase
A reference to an abstract CAN channel.
Definition: can.hpp:430
can_err
A CAN error frame.
Definition: err.h:28
io_can_rt_read_msg::r
struct io_can_rt_read_msg_result r
The result of the read operation.
Definition: can_rt.h:71
lely::io::CanRouter::async_read_error
ev::Future< const can_err *, int > async_read_error(struct io_can_rt_read_err **pread_err=nullptr)
Definition: can_rt.hpp:315
lely::io::CanRouter::submit_read_frame
void submit_read_frame(uint_least32_t id, CanFlag flags, F &&f)
Definition: can_rt.hpp:259
io_can_rt_submit_read_err
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
lely::io::CanRouter::submit_read_error
void submit_read_error(struct io_can_rt_read_err &read_err) noexcept
Definition: can_rt.hpp:288
lely::io::CanRouter::cancel_read_frame
bool cancel_read_frame(struct io_can_rt_read_msg &read_msg) noexcept
Definition: can_rt.hpp:266
io_can_rt_create
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
io_can_rt_abort_read_err
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
lely::io::CanRouter::abort_read_frame
bool abort_read_frame(struct io_can_rt_read_msg &read_msg) noexcept
Definition: can_rt.hpp:272
io_can_rt_read_msg_result::msg
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
io_can_chan_t
const struct io_can_chan_vtbl *const io_can_chan_t
An abstract CAN channel.
Definition: can.h:59
lely::io::detail::CanRouterReadFrameWrapper
Definition: can_rt.hpp:38
io_can_rt_read_err_from_task
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
io_can_rt_read_msg::id
uint_least32_t id
The identifier of the CAN frame to be received.
Definition: can_rt.h:57
lely::io::Device
An abstract I/O device. This class is a wrapper around #io_dev_t*.
Definition: dev.hpp:35
lely::io::make_can_router_read_frame_wrapper
typename ::std::enable_if< compat::is_invocable< F, const can_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
lely::io::CanFlag
CanFlag
The error flags of a CAN bus, which are not mutually exclusive.
Definition: msg.hpp:33
io_can_rt_get_chan
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
lely::ev::Executor
An abstract task executor. This class is a wrapper around #ev_exec_t*.
Definition: exec.hpp:38
lely::compat::is_invocable
Determines whether F can be invoked with the arguments Args....
Definition: type_traits.hpp:206
lely::ev::Future
A future.
Definition: future.hpp:50
lely::io::CanRouter::abort_read_error
bool abort_read_error(struct io_can_rt_read_err &read_err) noexcept
Definition: can_rt.hpp:309
IO_CAN_RT_READ_ERR_INIT
#define IO_CAN_RT_READ_ERR_INIT(func)
The static initializer for io_can_rt_read_err.
Definition: can_rt.h:111
io_can_rt_read_err_result::err
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
can.hpp
lely::io::CanRouterReadFrame::CanRouterReadFrame
CanRouterReadFrame(uint_least32_t id, CanFlag flags, F &&f)
Constructs a CAN frame read operation with a completion task.
Definition: can_rt.hpp:93
io_can_rt_cancel_read_msg
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
lely::io::CanRouterReadFrame
A CAN frame read operation suitable for use with a CAN frame router.
Definition: can_rt.hpp:87
io_can_rt_async_read_err
ev_future_t * io_can_rt_async_read_err(io_can_rt_t *rt, struct io_can_rt_read_err **pread_err)
Submits an asynchronous CAN error frame read operation to a CAN frame router and creates a future whi...
Definition: can_rt.c:470
io_can_rt_cancel_read_err
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
lely::io::CanRouterReadError::get_executor
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
Definition: can_rt.hpp:200
io_can_rt_read_msg_from_task
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
io_can_rt_abort_read_msg
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
io_can_rt_read_err::task
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the read operation.
Definition: can_rt.h:105
io_can_rt_read_err::r
struct io_can_rt_read_err_result r
The result of the read operation.
Definition: can_rt.h:107
lely::io::CanRouter
A CAN frame rounter. This class is a wrapper around #io_can_rt_t*.
Definition: can_rt.hpp:209
lely::io::CanRouter::submit_read_frame
void submit_read_frame(struct io_can_rt_read_msg &read_msg) noexcept
Definition: can_rt.hpp:252
ev_task
An executable task.
Definition: task.h:41
lely::io::CanRouter::get_channel
CanChannelBase get_channel() const noexcept
Definition: can_rt.hpp:246
io_dev_t
const struct io_dev_vtbl *const io_dev_t
An abstract I/O device.
Definition: dev.h:35
lely::io::CanRouterReadFrame::get_executor
ev::Executor get_executor() const noexcept
Returns the executor to which the completion task is (to be) submitted.
Definition: can_rt.hpp:116
lely::io::CanRouter::cancel_read_error
bool cancel_read_error(struct io_can_rt_read_err &read_err) noexcept
Definition: can_rt.hpp:303
IO_CAN_RT_READ_MSG_INIT
#define IO_CAN_RT_READ_MSG_INIT(id, flags, func)
The static initializer for io_can_rt_read_msg.
Definition: can_rt.h:77
lely::canopen::make_error_code
::std::error_code make_error_code(SdoErrc e) noexcept
Creates an error code corresponding to an SDO abort code.
Definition: sdo_error.cpp:170
io_can_rt_async_shutdown
ev_future_t * io_can_rt_async_shutdown(io_can_rt_t *rt)
Shuts down a CAN frame router, cancels all pending operations and creates a (void) future which becom...
Definition: can_rt.c:495
lely::io::CanRouter::submit_read_error
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
io_can_rt_read_msg::task
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the read operation.
Definition: can_rt.h:69
io_can_rt_read_msg
A CAN frame read operation suitable for use with a CAN frame router.
Definition: can_rt.h:52
lely::io::CanRouterReadError::CanRouterReadError
CanRouterReadError(F &&f)
Constructs a CAN error frame read operation with a completion task.
Definition: can_rt.hpp:179
ev_task::exec
ev_exec_t * exec
A pointer to the executor to which the task is (to be) submitted.
Definition: task.h:43
io_can_rt_read_err
A CAN error frame read operation suitable for use with a CAN frame router.
Definition: can_rt.h:100
lely::io::CanRouter::async_read_frame
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
lely::io::make_can_router_read_error_wrapper
typename ::std::enable_if< compat::is_invocable< F, const can_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
io_can_rt_read_msg::flags
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