.. _program_listing_file_libspookyaction_include_pn532_helper.hpp: Program Listing for File helper.hpp =================================== |exhale_lsh| :ref:`Return to documentation for file ` (``libspookyaction/include/pn532/helper.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // // Created by spak on 1/18/23. // #ifndef PN532_SCAN_HELPER_HPP #define PN532_SCAN_HELPER_HPP #include namespace pn532::helper { struct scanned_target { std::uint8_t index = std::numeric_limits::max(); target_type type = target_type::generic_passive_106kbps; std::vector nfcid{}; scanned_target() = default; template scanned_target(std::uint8_t index_, poll_target const &entry); scanned_target(std::uint8_t index_, any_poll_target const &entry); [[nodiscard]] bool operator==(scanned_target const &other) const; [[nodiscard]] bool operator!=(scanned_target const &other) const; [[nodiscard]] bool operator<(scanned_target const &other) const; [[nodiscard]] bool operator>(scanned_target const &other) const; [[nodiscard]] bool operator<=(scanned_target const &other) const; [[nodiscard]] bool operator>=(scanned_target const &other) const; [[nodiscard]] inline explicit operator bool() const noexcept; }; struct autorelease_target : scanned_target { std::weak_ptr ctrl = {}; autorelease_target() = default; inline autorelease_target(std::shared_ptr const &ctrl_, scanned_target target_); template autorelease_target(std::shared_ptr const &ctrl_, std::uint8_t index_, poll_target const &entry); inline autorelease_target(std::shared_ptr const &ctrl_, std::uint8_t index_, any_poll_target const &entry); inline result release(ms timeout = default_timeout); inline ~autorelease_target(); }; [[nodiscard]] result scan( std::shared_ptr const &ctrl, scanned_target const &skip_prev_target = scanned_target{}, std::vector const &targets = controller::poll_all_targets, ms timeout = long_timeout); }// namespace pn532::helper namespace pn532::helper { template scanned_target::scanned_target(std::uint8_t index_, poll_target const &entry) : index{index_}, type{Type} { static constexpr auto BM = baudrate_modulation_of(Type); if constexpr (std::is_base_of_v, poll_target>) { // Obtain NFCID3t from the atr_res_info, and the index from the target bit index = entry.logical_index; nfcid.resize(entry.atr_info.nfcid.size()); std::copy(std::begin(entry.atr_info.nfcid), std::end(entry.atr_info.nfcid), std::begin(nfcid)); } else if constexpr (std::is_base_of_v, poll_target>) { // Obtain the logical index from the target bit, and then differentiate index = entry.logical_index; if constexpr (BM == baudrate_modulation::kbps106_iso_iec_14443_typea) { nfcid = entry.nfcid; } else if constexpr (BM == baudrate_modulation::kbps212_felica or BM == baudrate_modulation::kbps424_felica) { nfcid.resize(entry.nfcid_2t.size()); std::copy(std::begin(entry.nfcid_2t), std::end(entry.nfcid_2t), std::begin(nfcid)); } else if constexpr (BM == baudrate_modulation::kbps106_iso_iec_14443_3_typeb) { // Slice off the PUPI (Pseudo-Unique PICC Identifier) out of the atqb response if (entry.atqb_response.size() >= 5) { nfcid.resize(4); std::copy_n(std::begin(entry.atqb_response) + 1, 4, std::begin(nfcid)); } else { // Just use the whole atqb response nfcid.resize(entry.atqb_response.size()); std::copy(std::begin(entry.atqb_response), std::end(entry.atqb_response), std::begin(nfcid)); } } else if constexpr (BM == baudrate_modulation::kbps106_innovision_jewel_tag) { // Use jewel id nfcid.resize(entry.jewel_id.size()); std::copy(std::begin(entry.jewel_id), std::end(entry.jewel_id), std::begin(nfcid)); } } else { static_assert(std::is_base_of_v>); // Obtain NFCID3t from the atr_res_info, we cannot do anything about the index nfcid.resize(entry.atr_info.nfcid.size()); std::copy(std::begin(entry.atr_info.nfcid), std::end(entry.atr_info.nfcid), std::begin(nfcid)); } } inline scanned_target::operator bool() const noexcept { return index < std::numeric_limits::max(); } template autorelease_target::autorelease_target(std::shared_ptr const &ctrl_, std::uint8_t index_, poll_target const &entry) : scanned_target{index_, entry}, ctrl{ctrl_->weak_from_this()} {} autorelease_target::autorelease_target(std::shared_ptr const &ctrl_, std::uint8_t index_, any_poll_target const &entry) : scanned_target{index_, entry}, ctrl{ctrl_->weak_from_this()} {} autorelease_target::autorelease_target(std::shared_ptr const &ctrl_, scanned_target target_) : scanned_target{std::move(target_)}, ctrl{ctrl_->weak_from_this()} {} result autorelease_target::release(ms timeout) { if (index < std::numeric_limits::max()) { if (const auto ctrl_strong_ref = ctrl.lock(); ctrl_strong_ref) { auto r = ctrl_strong_ref->initiator_release(index); if (r) { // Done, the weak ref can be destroyed ctrl = {}; } return r; } return channel_error::app_error; } return channel_error::malformed; } autorelease_target::~autorelease_target() { release(); } }// namespace pn532::helper #endif//PN532_SCAN_HELPER_HPP