2019-04-17 12:06:00 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "esphome/core/component.h"
|
|
|
|
#include "esphome/core/automation.h"
|
|
|
|
#include "esphome/components/binary_sensor/binary_sensor.h"
|
2021-01-14 21:29:55 +01:00
|
|
|
#include "esphome/components/nfc/nfc_tag.h"
|
|
|
|
#include "esphome/components/nfc/nfc.h"
|
2022-04-13 02:26:55 +02:00
|
|
|
#include "esphome/components/nfc/automation.h"
|
2019-04-17 12:06:00 +02:00
|
|
|
|
2022-11-24 01:12:55 +01:00
|
|
|
#include <vector>
|
|
|
|
|
2019-04-17 12:06:00 +02:00
|
|
|
namespace esphome {
|
|
|
|
namespace pn532 {
|
|
|
|
|
2020-10-31 23:55:48 +01:00
|
|
|
static const uint8_t PN532_COMMAND_VERSION_DATA = 0x02;
|
|
|
|
static const uint8_t PN532_COMMAND_SAMCONFIGURATION = 0x14;
|
|
|
|
static const uint8_t PN532_COMMAND_RFCONFIGURATION = 0x32;
|
|
|
|
static const uint8_t PN532_COMMAND_INDATAEXCHANGE = 0x40;
|
|
|
|
static const uint8_t PN532_COMMAND_INLISTPASSIVETARGET = 0x4A;
|
|
|
|
|
2019-04-17 12:06:00 +02:00
|
|
|
class PN532BinarySensor;
|
|
|
|
|
2020-10-31 23:55:48 +01:00
|
|
|
class PN532 : public PollingComponent {
|
2019-04-17 12:06:00 +02:00
|
|
|
public:
|
|
|
|
void setup() override;
|
|
|
|
|
|
|
|
void dump_config() override;
|
|
|
|
|
|
|
|
void update() override;
|
|
|
|
float get_setup_priority() const override;
|
|
|
|
|
|
|
|
void loop() override;
|
|
|
|
|
|
|
|
void register_tag(PN532BinarySensor *tag) { this->binary_sensors_.push_back(tag); }
|
2022-04-13 02:26:55 +02:00
|
|
|
void register_ontag_trigger(nfc::NfcOnTagTrigger *trig) { this->triggers_ontag_.push_back(trig); }
|
|
|
|
void register_ontagremoved_trigger(nfc::NfcOnTagTrigger *trig) { this->triggers_ontagremoved_.push_back(trig); }
|
2021-01-14 21:29:55 +01:00
|
|
|
|
|
|
|
void add_on_finished_write_callback(std::function<void()> callback) {
|
|
|
|
this->on_finished_write_callback_.add(std::move(callback));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool is_writing() { return this->next_task_ != READ; };
|
|
|
|
|
|
|
|
void read_mode();
|
|
|
|
void clean_mode();
|
|
|
|
void format_mode();
|
|
|
|
void write_mode(nfc::NdefMessage *message);
|
2019-04-17 12:06:00 +02:00
|
|
|
|
|
|
|
protected:
|
2020-10-31 23:55:48 +01:00
|
|
|
void turn_off_rf_();
|
|
|
|
bool write_command_(const std::vector<uint8_t> &data);
|
2019-04-17 12:06:00 +02:00
|
|
|
bool read_ack_();
|
2021-02-05 23:02:20 +01:00
|
|
|
void send_nack_();
|
2019-04-17 12:06:00 +02:00
|
|
|
|
2020-10-31 23:55:48 +01:00
|
|
|
virtual bool write_data(const std::vector<uint8_t> &data) = 0;
|
|
|
|
virtual bool read_data(std::vector<uint8_t> &data, uint8_t len) = 0;
|
2021-02-05 23:02:20 +01:00
|
|
|
virtual bool read_response(uint8_t command, std::vector<uint8_t> &data) = 0;
|
2020-06-10 04:23:25 +02:00
|
|
|
|
2021-09-13 11:31:02 +02:00
|
|
|
std::unique_ptr<nfc::NfcTag> read_tag_(std::vector<uint8_t> &uid);
|
2021-01-14 21:29:55 +01:00
|
|
|
|
|
|
|
bool format_tag_(std::vector<uint8_t> &uid);
|
|
|
|
bool clean_tag_(std::vector<uint8_t> &uid);
|
|
|
|
bool write_tag_(std::vector<uint8_t> &uid, nfc::NdefMessage *message);
|
|
|
|
|
2021-09-13 11:31:02 +02:00
|
|
|
std::unique_ptr<nfc::NfcTag> read_mifare_classic_tag_(std::vector<uint8_t> &uid);
|
2021-01-14 21:29:55 +01:00
|
|
|
bool read_mifare_classic_block_(uint8_t block_num, std::vector<uint8_t> &data);
|
|
|
|
bool write_mifare_classic_block_(uint8_t block_num, std::vector<uint8_t> &data);
|
|
|
|
bool auth_mifare_classic_block_(std::vector<uint8_t> &uid, uint8_t block_num, uint8_t key_num, const uint8_t *key);
|
|
|
|
bool format_mifare_classic_mifare_(std::vector<uint8_t> &uid);
|
|
|
|
bool format_mifare_classic_ndef_(std::vector<uint8_t> &uid);
|
|
|
|
bool write_mifare_classic_tag_(std::vector<uint8_t> &uid, nfc::NdefMessage *message);
|
|
|
|
|
2021-09-13 11:31:02 +02:00
|
|
|
std::unique_ptr<nfc::NfcTag> read_mifare_ultralight_tag_(std::vector<uint8_t> &uid);
|
2021-01-14 21:29:55 +01:00
|
|
|
bool read_mifare_ultralight_page_(uint8_t page_num, std::vector<uint8_t> &data);
|
|
|
|
bool is_mifare_ultralight_formatted_();
|
|
|
|
uint16_t read_mifare_ultralight_capacity_();
|
|
|
|
bool find_mifare_ultralight_ndef_(uint8_t &message_length, uint8_t &message_start_index);
|
|
|
|
bool write_mifare_ultralight_page_(uint8_t page_num, std::vector<uint8_t> &write_data);
|
|
|
|
bool write_mifare_ultralight_tag_(std::vector<uint8_t> &uid, nfc::NdefMessage *message);
|
|
|
|
bool clean_mifare_ultralight_();
|
|
|
|
|
2019-04-17 12:06:00 +02:00
|
|
|
bool requested_read_{false};
|
|
|
|
std::vector<PN532BinarySensor *> binary_sensors_;
|
2022-04-13 02:26:55 +02:00
|
|
|
std::vector<nfc::NfcOnTagTrigger *> triggers_ontag_;
|
|
|
|
std::vector<nfc::NfcOnTagTrigger *> triggers_ontagremoved_;
|
2020-10-31 23:55:48 +01:00
|
|
|
std::vector<uint8_t> current_uid_;
|
2021-01-14 21:29:55 +01:00
|
|
|
nfc::NdefMessage *next_task_message_to_write_;
|
|
|
|
enum NfcTask {
|
|
|
|
READ = 0,
|
|
|
|
CLEAN,
|
|
|
|
FORMAT,
|
|
|
|
WRITE,
|
|
|
|
} next_task_{READ};
|
2019-04-17 12:06:00 +02:00
|
|
|
enum PN532Error {
|
|
|
|
NONE = 0,
|
|
|
|
WAKEUP_FAILED,
|
|
|
|
SAM_COMMAND_FAILED,
|
|
|
|
} error_code_{NONE};
|
2021-01-14 21:29:55 +01:00
|
|
|
CallbackManager<void()> on_finished_write_callback_;
|
2019-04-17 12:06:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class PN532BinarySensor : public binary_sensor::BinarySensor {
|
|
|
|
public:
|
2019-04-22 21:56:30 +02:00
|
|
|
void set_uid(const std::vector<uint8_t> &uid) { uid_ = uid; }
|
2019-04-17 12:06:00 +02:00
|
|
|
|
2020-10-31 23:55:48 +01:00
|
|
|
bool process(std::vector<uint8_t> &data);
|
2019-04-17 12:06:00 +02:00
|
|
|
|
|
|
|
void on_scan_end() {
|
|
|
|
if (!this->found_) {
|
|
|
|
this->publish_state(false);
|
|
|
|
}
|
|
|
|
this->found_ = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
std::vector<uint8_t> uid_;
|
|
|
|
bool found_{false};
|
|
|
|
};
|
|
|
|
|
2021-01-14 21:29:55 +01:00
|
|
|
class PN532OnFinishedWriteTrigger : public Trigger<> {
|
|
|
|
public:
|
|
|
|
explicit PN532OnFinishedWriteTrigger(PN532 *parent) {
|
|
|
|
parent->add_on_finished_write_callback([this]() { this->trigger(); });
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename... Ts> class PN532IsWritingCondition : public Condition<Ts...>, public Parented<PN532> {
|
2019-04-17 12:06:00 +02:00
|
|
|
public:
|
2021-01-14 21:29:55 +01:00
|
|
|
bool check(Ts... x) override { return this->parent_->is_writing(); }
|
2019-04-17 12:06:00 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace pn532
|
|
|
|
} // namespace esphome
|