Class pn532::comm_operation
Defined in File channel.hpp
Class Documentation
-
class comm_operation
Class managing the correct firing of the events in channel.
This class is a RAII wrapper that fires the correct events at construction and destruction. It holds the transmission result obtained so far (or the corresponding error), in such a way that it can pass it to channel::on_receive_complete or channel::on_send_complete. Use the passthrough methods comm_operation::update to record results or errors, as in the example below. Use the comm_operation::ok accessor to check whether the channel::on_receive_prepare or channel::on_send_prepare events were successful before calling any lower level function.
using namespace std::chrono_literals; // In a subclass of channel result<any_frame> chn_subclass::custom_receive_frame() { // Create a comm_operation alive within the scope of the if. // This fires on_receive_prepare, and test with ::ok() whether it succeeded. if (comm_operation op{*this, comm_dir::receive, 10ms}; op.ok()) { // Able to receive, prepare buffer mlab::bin_data buffer{mlab::prealloc(100)}; // Make sure to test whether the communication succeeded if (const auto result_comm = raw_receive(buffer.view(), 10ms); result_comm) { // Success, attempt parsing mlab::bin_stream s{buffer}; frame_id fid{}; s >> fid; if (s.bad()) { // Could not parse the frame, update the comm_operation and return return op.update(error::malformed); } // Extract the frame any_frame f{}; std::tie(s, fid) >> f; if (s.bad()) { // Could not parse the frame, update the comm_operation and return return op.update(error::malformed); } // Nice! Parsed. Update the operation and return the frame return op.update(std::move(f)); } else { // Failure, update the comm_opeation and return the error from raw_receive return op.update(result_comm.error()); } } else { // Receive preparation failed, return the error collected into comm_operation return op.error(); } }
using namespace std::chrono_literals; // In some subclass of channel that requires sending data to wake bool chn_subclass::wake() { // Create a comm_operation alive within the scope of the if. // This fires on_send_prepare, and test with ::ok() whether it succeeded. if (comm_operation op{*this, comm_dir::send, 10ms}; op.ok()) { // Attempt sending data; use the result to update the comm operation // and passthrough. An explicit cast to bool is required here. return bool(op.update(raw_send({0x55, 0x55, 0x55}, 10ms))); } else { return false; } }
Note
Subclasses should never directly call any of channel::on_receive_prepare, channel::on_receive_complete, channel::on_send_prepare, channel::on_send_complete. These are managed by this class.
Warning
Always call channel::raw_send and channel::raw_receive with one such class in scope (otherwise the events will not be fired and the class may not be in the correct state).
Collect and update methods
These methods collect a result, an error, or a boolean representing success and store it inside the class. Moreover, they return whatever was passed to them (in the form of result or in form of channel_error), in such a way that the user can directly pass it through in a
return
statement. The updated result is used in the call to channel::on_receive_complete and channel::on_send_complete.comm_operation op{...}; // ... return op.update(raw_send(...));
-
inline channel_error update(channel_error e)
Stores an error state from an explicit error code.
- Parameters:
e – Error code.
- Returns:
The same error code
e
.
-
inline result update(bool operation_result)
Stores a success or timeout state from a boolean.
- Parameters:
operation_result – True if the operation succeded, false if it timed out.
- Returns:
mlab::result_success
or channel_error::timeout, depending onoperation_result
.
Public Functions
-
comm_operation(channel &owner, comm_dir event, ms timeout)
Calls channel::on_receive_prepare or channel::on_send_prepare and stores the outcome.
See also
- Parameters:
owner – The target class for calling channel::on_receive_prepare or channel::on_send_prepare.
event – Chooses between channel::on_receive_prepare, channel::on_receive_complete and channel::on_send_prepare, channel::on_send_complete.
timeout – Timeout to pass to channel::on_receive_prepare or channel::on_send_prepare.
-
~comm_operation()
Calls channel::on_receive_complete or channel::on_send_complete with the internally stored result.
-
inline bool ok() const
Tests whether the operation contains an error or not. The main usage of this is to test whether the channel::on_receive_prepare and channel::on_send_prepare events have succeeded; however it will also return false if e.g. update has been called with a failed result.
// Fire the on_receive_prepare event. if (comm_operation op{*this, comm_operation::receive, 10ms}; op.ok()) { // Do stuff } else { // Preparation failed }
- Returns:
True if an only if so far all the operations succeeded.
-
inline channel_error error() const
Error currently stored in this operation.
Note
This calls
mlab::result::error
; if the result is not an error, it is not possible to call this method, therefore test first with ok that this comm_operation contains in fact an error code.- Returns:
The error code of the currently stored result.
-
inline channel_error update(channel_error e)