Program Listing for File data.hpp
↰ Return to documentation for file (libspookyaction/include/pn532/data.hpp
)
//
// Created by Pietro Saccardi on 22/12/2020.
//
#ifndef PN532_DATA_HPP
#define PN532_DATA_HPP
#include <mlab/bin_data.hpp>
#include <mlab/result.hpp>
#include <pn532/bits.hpp>
#include <pn532/log.h>
#include <pn532/msg.hpp>
namespace pn532 {
using target_kbps106_typea = target<baudrate_modulation::kbps106_iso_iec_14443_typea>;
using target_kbps212_felica = target<baudrate_modulation::kbps212_felica>;
using target_kbps424_felica = target<baudrate_modulation::kbps424_felica>;
using target_kbps106_typeb = target<baudrate_modulation::kbps106_iso_iec_14443_3_typeb>;
using target_kbps106_jewel_tag = target<baudrate_modulation::kbps106_innovision_jewel_tag>;
struct infty_t {
};
static constexpr infty_t infty{};
template <class Integral>
struct with_inf {
static_assert(std::is_integral_v<Integral> and not std::is_same_v<Integral, bool>);
Integral v = Integral{};
with_inf() = default;
inline with_inf(infty_t) : v{std::numeric_limits<Integral>::max()} {}
inline with_inf(Integral n) : v{n} {}
with_inf(bool) = delete;
inline operator Integral() const { return v; }
inline with_inf &operator=(infty_t) {
v = std::numeric_limits<Integral>::max();
return *this;
}
inline bool operator==(infty_t) const { return v == std::numeric_limits<Integral>::max(); }
inline bool operator!=(infty_t) const { return v != std::numeric_limits<Integral>::max(); }
};
using infbyte = with_inf<std::uint8_t>;
template <target_type Type>
struct poll_target : public target<baudrate_modulation_of(Type)> {
};
struct poll_target_with_atr {
atr_res_info atr_info;
};
template <baudrate_modulation BrMd>
struct poll_target_dep_passive : public target<BrMd>, public poll_target_with_atr {
};
template <>
struct poll_target<target_type::dep_passive_106kbps> : public poll_target_dep_passive<
baudrate_modulation_of(target_type::dep_passive_106kbps)> {
};
template <>
struct poll_target<target_type::dep_passive_212kbps> : public poll_target_dep_passive<
baudrate_modulation_of(target_type::dep_passive_212kbps)> {
};
template <>
struct poll_target<target_type::dep_passive_424kbps> : public poll_target_dep_passive<
baudrate_modulation_of(target_type::dep_passive_424kbps)> {
};
template <>
struct poll_target<target_type::dep_active_106kbps> : public poll_target_with_atr {
};
template <>
struct poll_target<target_type::dep_active_212kbps> : public poll_target_with_atr {
};
template <>
struct poll_target<target_type::dep_active_424kbps> : public poll_target_with_atr {
};
class any_poll_target : public mlab::any_of<target_type, poll_target> {
public:
using mlab::any_of<target_type, poll_target>::any_of;
explicit any_poll_target(enum_type) = delete;
};
enum struct gpio_port {
p3,
p7,
i0i1
};
struct firmware_version {
std::uint8_t ic;
std::uint8_t version;
std::uint8_t revision;
bool iso_18092;
bool iso_iec_14443_typea;
bool iso_iec_14443_typeb;
};
struct rf_status {
bool nad_present;
bool expect_more_info;
internal_error_code error;
inline explicit operator bool() const;
};
struct parameters {
bool use_nad_data;
bool use_did_data;
bool auto_generate_atr_res;
bool auto_generate_rats;
bool enable_iso_14443_4_picc_emulation;
bool remove_pre_post_amble;
};
struct general_status_target {
std::uint8_t logical_index;
baudrate baudrate_rx;
baudrate baudrate_tx;
modulation modulation_type;
};
struct general_status_sam {
bool neg_pulse_on_clad_line;
bool detected_rf_field_off;
bool timeout_after_sig_act_irq;
bool clad_line_high;
};
struct general_status {
internal_error_code last_error;
bool rf_field_present;
std::vector<general_status_target> targets;
general_status_sam sam;
};
struct status_as_target {
nfcip1_picc_status status;
baudrate initiator_speed;
baudrate target_speed;
};
struct jump_dep_psl {
rf_status status{};
std::uint8_t target_logical_index{};
atr_res_info atr_info;
};
struct mifare_params {
std::array<std::uint8_t, 2> sens_res;
std::array<std::uint8_t, 3> nfcid_1t;
std::uint8_t sel_res;
};
struct felica_params {
std::array<std::uint8_t, 8> nfcid_2t;
std::array<std::uint8_t, 8> pad;
std::array<std::uint8_t, 2> syst_code;
};
struct activation_as_target_mode {
baudrate speed;
bool iso_iec_14443_4_picc;
bool dep;
framing_as_target framing_type;
};
struct activation_as_target {
activation_as_target_mode mode;
std::vector<std::uint8_t> initiator_command;
};
class gpio_status {
private:
std::uint8_t _p3_mask = 0x00;
std::uint8_t _p7_mask = 0x00;
std::uint8_t _i0i1_mask = 0x00;
public:
gpio_status() = default;
inline gpio_status(std::uint8_t p3_mask, std::uint8_t p7_mask, std::uint8_t i0i1_mask);
[[nodiscard]] inline std::uint8_t mask(gpio_port loc) const;
inline void set_mask(gpio_port loc, std::uint8_t mask);
[[nodiscard]] inline bool operator[](std::pair<gpio_port, std::uint8_t> const &gpio_idx) const;
inline mlab::bit_ref operator[](std::pair<gpio_port, std::uint8_t> const &gpio_idx);
};
}// namespace pn532
namespace mlab {
#ifndef DOXYGEN_SHOULD_SKIP_THIS
bin_data &operator<<(bin_data &bd, pn532::reg::ciu_212_424kbps const ®);
bin_data &operator<<(bin_data &bd, pn532::reg::ciu_106kbps_typea const ®);
bin_data &operator<<(bin_data &bd, pn532::reg::ciu_typeb const ®);
bin_data &operator<<(bin_data &bd, pn532::reg::ciu_iso_iec_14443_4_at_baudrate const ®);
bin_data &operator<<(bin_data &bd, pn532::reg::ciu_iso_iec_14443_4 const ®);
bin_data &operator<<(bin_data &bd, pn532::nfcid_2t const &uid);
bin_data &operator<<(bin_data &bd, pn532::nfcid_3t const &uid);
bin_data &operator<<(bin_data &bd, pn532::bits::reg_antenna_detector const &r);
bin_data &operator<<(bin_data &s, pn532::parameters const &p);
bin_data &operator<<(bin_data &s, std::vector<pn532::wakeup_source> const &vws);
bin_data &operator<<(bin_data &s, pn532::mifare_params const &p);
bin_data &operator<<(bin_data &s, pn532::felica_params const &p);
template <pn532::baudrate_modulation BrMd>
bin_stream &operator>>(bin_stream &s, std::vector<pn532::target<BrMd>> &targets);
bin_stream &operator>>(bin_stream &s, pn532::poll_target<pn532::target_type::dep_passive_106kbps> &entry);
template <pn532::target_type Type>
bin_stream &operator>>(bin_stream &s, pn532::poll_target<Type> &entry);
bin_stream &operator>>(bin_stream &s, pn532::any_poll_target &t);
bin_stream &operator>>(bin_stream &s, std::vector<pn532::any_poll_target> &targets);
bin_stream &operator>>(bin_stream &s, std::pair<pn532::rf_status, bin_data> &status_data_pair);
bin_stream &operator>>(bin_stream &s, pn532::rf_status &status);
bin_stream &operator>>(bin_stream &s, pn532::gpio_status &gpio);
bin_stream &operator>>(bin_stream &s, pn532::firmware_version &fw);
bin_stream &operator>>(bin_stream &s, pn532::general_status &gs);
bin_stream &operator>>(bin_stream &s, pn532::general_status_target &ts);
bin_stream &operator>>(bin_stream &s, pn532::target_kbps106_typea &target);
bin_stream &operator>>(bin_stream &s, pn532::target_kbps212_felica &target);
bin_stream &operator>>(bin_stream &s, pn532::target_kbps424_felica &target);
bin_stream &operator>>(bin_stream &s, pn532::target_kbps106_typeb &target);
bin_stream &operator>>(bin_stream &s, pn532::target_kbps106_jewel_tag &target);
bin_stream &operator>>(bin_stream &s, pn532::atr_res_info &atr_res);
bin_stream &operator>>(bin_stream &s, std::pair<pn532::rf_status, pn532::atr_res_info> &status_atr_res);
bin_stream &operator>>(bin_stream &s, pn532::bits::reg_antenna_detector &r);
bin_stream &operator>>(bin_stream &s, pn532::jump_dep_psl &r);
bin_stream &operator>>(bin_stream &s, pn532::general_status_sam &sams);
bin_stream &operator>>(bin_stream &s, pn532::status_as_target &st);
bin_stream &operator>>(bin_stream &s, pn532::activation_as_target_mode &mt);
bin_stream &operator>>(bin_stream &s, pn532::activation_as_target &mt);
#endif
}// namespace mlab
namespace pn532 {
rf_status::operator bool() const {
return error == internal_error_code::none;
}
bool gpio_status::operator[](std::pair<gpio_port, std::uint8_t> const &gpio_idx) const {
switch (gpio_idx.first) {
case gpio_port::p3:
return 0 != (_p3_mask & (1 << gpio_idx.second));
case gpio_port::p7:
return 0 != (_p7_mask & (1 << gpio_idx.second));
case gpio_port::i0i1:
return 0 != (_i0i1_mask & (1 << gpio_idx.second));
}
}
mlab::bit_ref gpio_status::operator[](std::pair<gpio_port, std::uint8_t> const &gpio_idx) {
static std::uint8_t _garbage = 0x00;
switch (gpio_idx.first) {
case gpio_port::p3:
return mlab::bit_ref{_p3_mask, gpio_idx.second, bits::gpio_p3_pin_mask};
case gpio_port::p7:
return mlab::bit_ref{_p7_mask, gpio_idx.second, bits::gpio_p7_pin_mask};
case gpio_port::i0i1:
return mlab::bit_ref{_i0i1_mask, gpio_idx.second, bits::gpio_i0i1_pin_mask};
}
return mlab::bit_ref{_garbage, gpio_idx.second, 0xff};
}
gpio_status::gpio_status(std::uint8_t p3_mask, std::uint8_t p7_mask, std::uint8_t i0i1_mask) : _p3_mask{p3_mask}, _p7_mask{p7_mask}, _i0i1_mask{i0i1_mask} {}
inline std::uint8_t gpio_status::mask(gpio_port loc) const {
switch (loc) {
case gpio_port::p3:
return _p3_mask;
case gpio_port::p7:
return _p7_mask;
case gpio_port::i0i1:
return _i0i1_mask;
}
return 0x00;
}
void gpio_status::set_mask(gpio_port loc, std::uint8_t mask) {
switch (loc) {
case gpio_port::p3:
_p3_mask = mask & bits::gpio_p3_pin_mask;
break;
case gpio_port::p7:
_p7_mask = mask & bits::gpio_p7_pin_mask;
break;
case gpio_port::i0i1:
_i0i1_mask = mask & bits::gpio_i0i1_pin_mask;
break;
}
}
}// namespace pn532
namespace mlab {
template <pn532::baudrate_modulation BrMd>
bin_stream &operator>>(bin_stream &s, std::vector<pn532::target<BrMd>> &targets) {
if (s.remaining() < 1) {
PN532_LOGE("Parsing vector<target<%s>>: not enough data.", pn532::to_string(BrMd));
s.set_bad();
return s;
}
const auto num_targets = s.pop();
if (num_targets > pn532::bits::max_num_targets) {
PN532_LOGW("Parsing vector<target<%s>>: found %u targets, which is more than the number of supported targets %u.",
pn532::to_string(BrMd), num_targets, pn532::bits::max_num_targets);
}
targets.resize(num_targets);
for (auto &target : targets) {
if (not s.good()) {
break;
}
s >> target;
}
return s;
}
template <pn532::target_type Type>
bin_stream &operator>>(bin_stream &s, pn532::poll_target<Type> &entry) {
static constexpr pn532::baudrate_modulation BrMod = pn532::baudrate_modulation_of(Type);
if constexpr (std::is_base_of_v<pn532::target<BrMod>, pn532::poll_target<Type>>) {
s >> static_cast<pn532::target<BrMod> &>(entry);
}
if constexpr (std::is_base_of_v<pn532::poll_target_with_atr, pn532::poll_target<Type>>) {
s >> static_cast<pn532::poll_target_with_atr &>(entry).atr_info;
}
return s;
}
}// namespace mlab
#endif//PN532_DATA_HPP