Program Listing for File controller.hpp

Return to documentation for file (libspookyaction/include/pn532/controller.hpp)

//
// Created by Pietro Saccardi on 20/12/2020.
//

#ifndef PN532_CONTROLLER_HPP
#define PN532_CONTROLLER_HPP

#include <mlab/result.hpp>
#include <mutex>
#include <pn532/bits.hpp>
#include <pn532/channel.hpp>
#include <pn532/data.hpp>
#include <pn532/msg.hpp>

namespace pn532 {
    using namespace std::chrono_literals;
    static constexpr ms default_timeout = 1s;
    static constexpr ms long_timeout = 3s;
    using namespace mlab_literals;

    class controller : public std::enable_shared_from_this<controller> {
        std::recursive_timed_mutex _mtx;

    public:
        static const std::vector<target_type> poll_all_targets;

        static constexpr auto max_supported_targets = bits::max_num_targets;

        explicit controller(std::shared_ptr<channel> chn);

        controller(controller const &) = delete;

        controller(controller &&) = delete;

        controller &operator=(controller const &) = delete;

        controller &operator=(controller &&) = delete;

        [[nodiscard]] result<bool> diagnose_rom(ms timeout = long_timeout);

        [[nodiscard]] result<bool> diagnose_ram(ms timeout = long_timeout);

        [[nodiscard]] result<bool> diagnose_attention_req_or_card_presence(ms timeout = long_timeout);

        [[nodiscard]] result<bool> diagnose_comm_line(ms timeout = long_timeout);

        [[nodiscard]] result<unsigned, unsigned> diagnose_poll_target(bool slow = true, bool fast = true, ms timeout = long_timeout);

        [[nodiscard]] result<> diagnose_echo_back(ms reply_delay, std::uint8_t tx_mode, std::uint8_t rx_mode, ms timeout = long_timeout);

        [[nodiscard]] result<bool> diagnose_self_antenna(low_current_thr low_threshold, high_current_thr high_threshold, ms timeout = long_timeout);

        [[nodiscard]] result<firmware_version> get_firmware_version(ms timeout = default_timeout);

        [[nodiscard]] result<general_status> get_general_status(ms timeout = default_timeout);

        [[nodiscard]] result<std::vector<uint8_t>> read_registers(std::vector<reg::addr> const &addresses, ms timeout = default_timeout);

        inline result<uint8_t> read_register(reg::addr const &addr, ms timeout = default_timeout);

        result<> write_registers(std::vector<std::pair<reg::addr, std::uint8_t>> const &addr_value_pairs, ms timeout = default_timeout);

        inline result<> write_register(reg::addr const &addr, std::uint8_t val, ms timeout = default_timeout);

        [[nodiscard]] result<gpio_status> read_gpio(ms timeout = default_timeout);

        result<> write_gpio(gpio_status const &status, bool write_p3 = true, bool write_p7 = true, ms timeout = default_timeout);

        result<> set_gpio_pin(gpio_port loc, std::uint8_t pin_idx, bool value, ms timeout = default_timeout);

        result<> set_serial_baud_rate(serial_baudrate br, ms timeout = default_timeout);

        result<> sam_configuration(sam_mode mode, ms sam_timeout, bool controller_drives_irq = true, ms timeout = default_timeout);

        result<> set_parameters(parameters const &parms, ms timeout = default_timeout);

        result<rf_status> power_down(std::vector<wakeup_source> const &wakeup_sources, bool generate_irq, ms timeout = default_timeout);
        result<rf_status> power_down(std::vector<wakeup_source> const &wakeup_sources, ms timeout = default_timeout);
        [[nodiscard]] bool init_and_test();
        result<> rf_configuration_field(bool auto_rfca, bool rf_on, ms timeout = default_timeout);

        result<> rf_configuration_timings(rf_timeout atr_res_timeout = rf_timeout::ms_102_4, rf_timeout retry_timeout = rf_timeout::ms_51_2, ms timeout = default_timeout);

        result<> rf_configuration_retries(infbyte comm_retries = 0_b, ms timeout = default_timeout);

        result<> rf_configuration_retries(infbyte atr_retries, infbyte psl_retries, infbyte passive_activation_retries = infty, ms timeout = default_timeout);

        result<> rf_configuration_analog_106kbps_typea(reg::ciu_106kbps_typea const &config, ms timeout = default_timeout);

        result<> rf_configuration_analog_212_424kbps(reg::ciu_212_424kbps const &config, ms timeout = default_timeout);

        result<> rf_configuration_analog_typeb(reg::ciu_typeb const &config, ms timeout = default_timeout);

        result<> rf_configuration_analog_iso_iec_14443_4(reg::ciu_iso_iec_14443_4 const &config, ms timeout = default_timeout);

        result<> rf_regulation_test(rf_test_mode mode, ms timeout = default_timeout);

        template <class T, class = typename std::enable_if<not std::is_same_v<bin_data, typename std::decay_t<T>::type>>::type>
        [[nodiscard]] result<rf_status, bin_data> initiator_data_exchange(std::uint8_t target_logical_index, T &&data, ms timeout = default_timeout);

        [[nodiscard]] result<rf_status, bin_data> initiator_data_exchange(std::uint8_t target_logical_index, bin_data const &data, ms timeout = default_timeout);

        result<rf_status> initiator_select(std::uint8_t target_logical_index, ms timeout = default_timeout);

        result<rf_status> initiator_deselect(std::uint8_t target_logical_index, ms timeout = default_timeout);

        result<rf_status> initiator_release(std::uint8_t target_logical_index, ms timeout = default_timeout);

        result<rf_status> initiator_psl(std::uint8_t target_logical_index, baudrate in_to_trg, baudrate trg_to_in, ms timeout = default_timeout);

        [[nodiscard]] result<std::vector<target_kbps106_typea>> initiator_list_passive_kbps106_typea(std::uint8_t max_targets = max_supported_targets, ms timeout = long_timeout);

        [[nodiscard]] result<std::vector<target_kbps106_typea>> initiator_list_passive_kbps106_typea(nfcid_1t uid, std::uint8_t max_targets = 1, ms timeout = long_timeout);
        [[nodiscard]] result<std::vector<target_kbps106_typea>> initiator_list_passive_kbps106_typea(nfcid_2t uid, std::uint8_t max_targets = 1, ms timeout = long_timeout);
        [[nodiscard]] result<std::vector<target_kbps106_typea>> initiator_list_passive_kbps106_typea(nfcid_3t uid, std::uint8_t max_targets = 1, ms timeout = long_timeout);

        [[nodiscard]] result<std::vector<target_kbps106_typeb>> initiator_list_passive_kbps106_typeb(
                std::uint8_t application_family_id, polling_method method = polling_method::timeslot,
                std::uint8_t max_targets = max_supported_targets, ms timeout = long_timeout);

        [[nodiscard]] result<std::vector<target_kbps212_felica>> initiator_list_passive_kbps212_felica(
                std::array<std::uint8_t, 5> const &payload, std::uint8_t max_targets = max_supported_targets,
                ms timeout = long_timeout);

        [[nodiscard]] result<std::vector<target_kbps424_felica>> initiator_list_passive_kbps424_felica(
                std::array<std::uint8_t, 5> const &payload, std::uint8_t max_targets = max_supported_targets,
                ms timeout = long_timeout);

        [[nodiscard]] result<std::vector<target_kbps106_jewel_tag>> initiator_list_passive_kbps106_jewel_tag(ms timeout = long_timeout);

        result<rf_status, atr_res_info> initiator_activate_target(std::uint8_t target_logical_index, nfcid_3t const &nfcid, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<rf_status, atr_res_info> initiator_activate_target(std::uint8_t target_logical_index, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<rf_status, atr_res_info> initiator_activate_target(std::uint8_t target_logical_index, nfcid_3t const &nfcid, ms timeout = default_timeout);
        result<rf_status, atr_res_info> initiator_activate_target(std::uint8_t target_logical_index, ms timeout = default_timeout);
        [[nodiscard]] result<std::vector<any_poll_target>> initiator_auto_poll(
                std::vector<target_type> const &types_to_poll = poll_all_targets,
                infbyte polls_per_type = 3_b, poll_period period = poll_period::ms_150, ms timeout = long_timeout);

        [[nodiscard]] result<rf_status, bin_data> initiator_communicate_through(bin_data raw_data, ms timeout = default_timeout);

        result<jump_dep_psl> initiator_jump_for_dep_active(baudrate speed, nfcid_3t const &nfcid, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_active(baudrate speed, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_active(baudrate speed, nfcid_3t const &nfcid, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_active(baudrate speed, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_passive_106kbps(nfcid_1t target_id, nfcid_3t const &nfcid, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_passive_106kbps(nfcid_1t target_id, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_passive_106kbps(nfcid_1t target_id, nfcid_3t const &nfcid, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_passive_106kbps(nfcid_1t target_id, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_passive_106kbps(nfcid_3t const &nfcid, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_passive_106kbps(std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_passive_106kbps(nfcid_3t const &nfcid, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_passive_106kbps(ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_passive_212kbps(std::array<std::uint8_t, 5> const &payload, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_passive_212kbps(std::array<std::uint8_t, 5> const &payload, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_passive_424kbps(std::array<std::uint8_t, 5> const &payload, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_dep_passive_424kbps(std::array<std::uint8_t, 5> const &payload, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_active(baudrate speed, nfcid_3t const &nfcid, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_active(baudrate speed, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_active(baudrate speed, nfcid_3t const &nfcid, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_active(baudrate speed, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_passive_106kbps(nfcid_3t const &nfcid, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_passive_106kbps(std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_passive_106kbps(nfcid_3t const &nfcid, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_passive_106kbps(ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_passive_106kbps(nfcid_1t target_id, nfcid_3t const &nfcid, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_passive_106kbps(nfcid_1t target_id, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_passive_106kbps(nfcid_1t target_id, nfcid_3t const &nfcid, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_passive_106kbps(nfcid_1t target_id, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_passive_212kbps(std::array<std::uint8_t, 5> const &payload, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_passive_212kbps(std::array<std::uint8_t, 5> const &payload, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_passive_424kbps(std::array<std::uint8_t, 5> const &payload, std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);
        result<jump_dep_psl> initiator_jump_for_psl_passive_424kbps(std::array<std::uint8_t, 5> const &payload, ms timeout = default_timeout);
        [[nodiscard]] result<status_as_target> target_get_target_status(ms timeout = default_timeout);

        [[nodiscard]] result<activation_as_target> target_init_as_target(
                bool picc_only, bool dep_only, bool passive_only, mifare_params const &mifare,
                felica_params const &felica, nfcid_3t const &nfcid,
                std::vector<std::uint8_t> const &general_info = {},
                std::vector<std::uint8_t> const &historical_bytes = {}, ms timeout = default_timeout);

        result<rf_status> target_set_general_bytes(std::vector<std::uint8_t> const &general_info, ms timeout = default_timeout);

        [[nodiscard]] result<rf_status, bin_data> target_get_data(ms timeout = default_timeout);

        result<rf_status> target_set_data(std::vector<std::uint8_t> const &data, ms timeout = default_timeout);

        result<rf_status> target_set_metadata(std::vector<std::uint8_t> const &data, ms timeout = default_timeout);

        [[nodiscard]] result<rf_status, bin_data> target_get_initiator_command(ms timeout = default_timeout);

        result<rf_status> target_response_to_initiator(std::vector<std::uint8_t> const &data, ms timeout = default_timeout);
    private:
        std::shared_ptr<channel> _channel;

        [[nodiscard]] inline channel &chn() const;

        [[nodiscard]] static std::uint8_t get_target(command_code cmd, std::uint8_t target_logical_index, bool expect_more_data);

        template <baudrate_modulation BrMd>
        result<std::vector<target<BrMd>>> initiator_list_passive(std::uint8_t max_targets, bin_data const &initiator_data, ms timeout);
    };

}// namespace pn532


namespace pn532 {

    channel &controller::chn() const { return *_channel; }

    result<uint8_t> controller::read_register(reg::addr const &addr, ms timeout) {
        if (const auto res_cmd = read_registers({addr}, timeout); res_cmd) {
            return res_cmd->at(0);
        } else {
            return res_cmd.error();
        }
    }

    result<> controller::write_register(reg::addr const &addr, std::uint8_t val, ms timeout) {
        return write_registers({{addr, val}}, timeout);
    }

    template <class T, class>
    result<rf_status, bin_data> controller::initiator_data_exchange(std::uint8_t target_logical_index, T &&data, ms timeout) {
        static bin_data buffer{};
        buffer.clear();
        buffer << std::forward<T>(data);
        return initiator_data_exchange(target_logical_index, buffer, timeout);
    }

}// namespace pn532


#endif//PN532_CONTROLLER_HPP