.. _program_listing_file_libspookyaction_include_pn532_scanner.hpp: Program Listing for File scanner.hpp ==================================== |exhale_lsh| :ref:`Return to documentation for file ` (``libspookyaction/include/pn532/scanner.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // // Created by spak on 1/18/23. // #ifndef PN532_SCANNER_HPP #define PN532_SCANNER_HPP #include namespace pn532 { class scanner; enum struct post_interaction { reject, release, retain, abort }; 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; }; struct scanner_responder { virtual void on_activation(scanner &scanner, scanned_target const &target) {} virtual void on_release(scanner &scanner, scanned_target const &target) {} virtual void on_leaving_rf(scanner &scanner, scanned_target const &target) {} virtual void on_failed_scan(scanner &scanner, channel_error err) {} [[nodiscard]] virtual std::vector get_scan_target_types(scanner &scanner) const { return controller::poll_all_targets; } [[nodiscard]] virtual bool should_interact(scanner &scanner, scanned_target const &target) const { return true; } [[nodiscard]] virtual post_interaction interact(scanner &scanner, scanned_target const &target) { return post_interaction::reject; } virtual ~scanner_responder() = default; }; class scanner { std::shared_ptr _ctrl = nullptr; ms _timeout = 5s; bool _stop = false; std::vector _rejection_list{}; std::vector _in_rf{}; void update_rejection_list(scanner_responder &responder); void update_in_rf_list(std::vector const &targets); [[nodiscard]] bool is_in_rejection_list(scanned_target const &target) const; public: scanner() = default; explicit scanner(std::shared_ptr ctrl, ms max_scan_interval = 5s); scanner(scanner const &) = delete; scanner &operator=(scanner const &) = delete; scanner(scanner &&) noexcept = default; scanner &operator=(scanner &&) noexcept = default; [[nodiscard]] inline std::vector const &in_rf() const; [[nodiscard]] inline ms max_scan_interval() const; inline void set_max_scan_interval(ms timeout); void loop(scanner_responder &responder, bool init_and_test = true); [[nodiscard]] controller &ctrl(); [[nodiscard]] controller const &ctrl() const; void stop(); }; }// namespace pn532 namespace pn532 { ms scanner::max_scan_interval() const { return _timeout; } void scanner::set_max_scan_interval(ms timeout) { _timeout = timeout; } std::vector const &scanner::in_rf() const { return _in_rf; } 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)); } } }// namespace pn532 #endif//PN532_SCANNER_HPP