Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions components/pn532/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import automation
import esphome.codegen as cg
from esphome.components import nfc
import esphome.config_validation as cv
from esphome.const import (
CONF_ID,
CONF_ON_FINISHED_WRITE,
CONF_ON_TAG_REMOVED,
CONF_ON_TAG,
CONF_ON_TAG_REMOVED,
CONF_TRIGGER_ID,
)

Expand Down Expand Up @@ -55,7 +55,7 @@ def CONFIG_SCHEMA(conf):
if conf:
raise cv.Invalid(
"This component has been moved in 1.16, please see the docs for updated "
"instructions. https://esphome.io/components/binary_sensor/pn532.html"
"instructions. https://esphome.io/components/binary_sensor/pn532/"
)


Expand Down
36 changes: 16 additions & 20 deletions components/pn532/pn532.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,9 @@ namespace pn532 {
static const char *const TAG = "pn532";

void PN532::setup() {
ESP_LOGCONFIG(TAG, "Setting up PN532...");

// Get version data
if (!this->write_command_({PN532_COMMAND_VERSION_DATA})) {
ESP_LOGW(TAG, "Error sending version command, trying again...");
ESP_LOGW(TAG, "Error sending version command, trying again");
if (!this->write_command_({PN532_COMMAND_VERSION_DATA})) {
ESP_LOGE(TAG, "Error sending version command");
this->mark_failed();
Expand All @@ -33,8 +31,7 @@ void PN532::setup() {
this->mark_failed();
return;
}
ESP_LOGD(TAG, "Found chip PN5%02X", version_data[0]);
ESP_LOGD(TAG, "Firmware ver. %d.%d", version_data[1], version_data[2]);
ESP_LOGD(TAG, "Found chip PN5%02X, Firmware v%d.%d", version_data[0], version_data[1], version_data[2]);

if (!this->write_command_({
PN532_COMMAND_SAMCONFIGURATION,
Expand Down Expand Up @@ -168,11 +165,11 @@ void PN532::loop() {
}

uint8_t nfcid_length = read[5];
std::vector<uint8_t> nfcid(read.begin() + 6, read.begin() + 6 + nfcid_length);
if (read.size() < 6U + nfcid_length) {
if (nfcid_length > nfc::NFC_UID_MAX_LENGTH || read.size() < 6U + nfcid_length) {
// oops, pn532 returned invalid data
return;
}
nfc::NfcTagUid nfcid(read.begin() + 6, read.begin() + 6 + nfcid_length);

bool report = true;
for (auto *bin_sens : this->binary_sensors_) {
Expand All @@ -197,7 +194,8 @@ void PN532::loop() {
trigger->process(tag);

if (report) {
ESP_LOGD(TAG, "Found new tag '%s'", nfc::format_uid(nfcid).c_str());
char uid_buf[nfc::FORMAT_UID_BUFFER_SIZE];
ESP_LOGD(TAG, "Found new tag '%s'", nfc::format_uid_to(uid_buf, nfcid));
if (tag->has_ndef_message()) {
const auto &message = tag->get_ndef_message();
const auto &records = message->get_records();
Expand All @@ -208,21 +206,21 @@ void PN532::loop() {
}
}
} else if (next_task_ == CLEAN) {
ESP_LOGD(TAG, " Tag cleaning...");
ESP_LOGD(TAG, " Tag cleaning");
if (!this->clean_tag_(nfcid)) {
ESP_LOGE(TAG, " Tag was not fully cleaned successfully");
}
ESP_LOGD(TAG, " Tag cleaned!");
} else if (next_task_ == FORMAT) {
ESP_LOGD(TAG, " Tag formatting...");
ESP_LOGD(TAG, " Tag formatting");
if (!this->format_tag_(nfcid)) {
ESP_LOGE(TAG, "Error formatting tag as NDEF");
}
ESP_LOGD(TAG, " Tag formatted!");
} else if (next_task_ == WRITE) {
if (this->next_task_message_to_write_ != nullptr) {
ESP_LOGD(TAG, " Tag writing...");
ESP_LOGD(TAG, " Tag formatting...");
ESP_LOGD(TAG, " Tag writing");
ESP_LOGD(TAG, " Tag formatting");
if (!this->format_tag_(nfcid)) {
ESP_LOGE(TAG, " Tag could not be formatted for writing");
} else {
Expand Down Expand Up @@ -281,7 +279,7 @@ bool PN532::write_command_(const std::vector<uint8_t> &data) {
}

bool PN532::read_ack_() {
ESP_LOGV(TAG, "Reading ACK...");
ESP_LOGV(TAG, "Reading ACK");

std::vector<uint8_t> data;
if (!this->read_data(data, 6)) {
Expand Down Expand Up @@ -357,7 +355,7 @@ void PN532::turn_off_rf_() {
});
}

std::unique_ptr<nfc::NfcTag> PN532::read_tag_(std::vector<uint8_t> &uid) {
std::unique_ptr<nfc::NfcTag> PN532::read_tag_(nfc::NfcTagUid &uid) {
uint8_t type = nfc::guess_tag_type(uid.size());

if (type == nfc::TAG_TYPE_MIFARE_CLASSIC) {
Expand Down Expand Up @@ -392,7 +390,7 @@ void PN532::write_mode(nfc::NdefMessage *message) {
ESP_LOGD(TAG, "Waiting to write next tag");
}

bool PN532::clean_tag_(std::vector<uint8_t> &uid) {
bool PN532::clean_tag_(nfc::NfcTagUid &uid) {
uint8_t type = nfc::guess_tag_type(uid.size());
if (type == nfc::TAG_TYPE_MIFARE_CLASSIC) {
return this->format_mifare_classic_mifare_(uid);
Expand All @@ -403,7 +401,7 @@ bool PN532::clean_tag_(std::vector<uint8_t> &uid) {
return false;
}

bool PN532::format_tag_(std::vector<uint8_t> &uid) {
bool PN532::format_tag_(nfc::NfcTagUid &uid) {
uint8_t type = nfc::guess_tag_type(uid.size());
if (type == nfc::TAG_TYPE_MIFARE_CLASSIC) {
return this->format_mifare_classic_ndef_(uid);
Expand All @@ -414,7 +412,7 @@ bool PN532::format_tag_(std::vector<uint8_t> &uid) {
return false;
}

bool PN532::write_tag_(std::vector<uint8_t> &uid, nfc::NdefMessage *message) {
bool PN532::write_tag_(nfc::NfcTagUid &uid, nfc::NdefMessage *message) {
uint8_t type = nfc::guess_tag_type(uid.size());
if (type == nfc::TAG_TYPE_MIFARE_CLASSIC) {
return this->write_mifare_classic_tag_(uid, message);
Expand All @@ -425,8 +423,6 @@ bool PN532::write_tag_(std::vector<uint8_t> &uid, nfc::NdefMessage *message) {
return false;
}

float PN532::get_setup_priority() const { return setup_priority::DATA; }

void PN532::dump_config() {
ESP_LOGCONFIG(TAG, "PN532:");
switch (this->error_code_) {
Expand All @@ -447,7 +443,7 @@ void PN532::dump_config() {
}
}

bool PN532BinarySensor::process(std::vector<uint8_t> &data) {
bool PN532BinarySensor::process(const nfc::NfcTagUid &data) {
if (data.size() != this->uid_.size())
return false;

Expand Down
39 changes: 19 additions & 20 deletions components/pn532/pn532.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,9 @@ class PN532 : public PollingComponent {
void dump_config() override;

void update() override;
float get_setup_priority() const override;

void loop() override;
void on_shutdown() override { powerdown(); }
void on_powerdown() override { powerdown(); }

void register_tag(PN532BinarySensor *tag) { this->binary_sensors_.push_back(tag); }
void register_ontag_trigger(nfc::NfcOnTagTrigger *trig) { this->triggers_ontag_.push_back(trig); }
Expand Down Expand Up @@ -69,36 +68,36 @@ class PN532 : public PollingComponent {
virtual bool read_data(std::vector<uint8_t> &data, uint8_t len) = 0;
virtual bool read_response(uint8_t command, std::vector<uint8_t> &data) = 0;

std::unique_ptr<nfc::NfcTag> read_tag_(std::vector<uint8_t> &uid);
std::unique_ptr<nfc::NfcTag> read_tag_(nfc::NfcTagUid &uid);

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);
bool format_tag_(nfc::NfcTagUid &uid);
bool clean_tag_(nfc::NfcTagUid &uid);
bool write_tag_(nfc::NfcTagUid &uid, nfc::NdefMessage *message);

std::unique_ptr<nfc::NfcTag> read_mifare_classic_tag_(std::vector<uint8_t> &uid);
std::unique_ptr<nfc::NfcTag> read_mifare_classic_tag_(nfc::NfcTagUid &uid);
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);
bool write_mifare_classic_block_(uint8_t block_num, const uint8_t *data, size_t len);
bool auth_mifare_classic_block_(nfc::NfcTagUid &uid, uint8_t block_num, uint8_t key_num, const uint8_t *key);
bool format_mifare_classic_mifare_(nfc::NfcTagUid &uid);
bool format_mifare_classic_ndef_(nfc::NfcTagUid &uid);
bool write_mifare_classic_tag_(nfc::NfcTagUid &uid, nfc::NdefMessage *message);

std::unique_ptr<nfc::NfcTag> read_mifare_ultralight_tag_(std::vector<uint8_t> &uid);
std::unique_ptr<nfc::NfcTag> read_mifare_ultralight_tag_(nfc::NfcTagUid &uid);
bool read_mifare_ultralight_bytes_(uint8_t start_page, uint16_t num_bytes, std::vector<uint8_t> &data);
bool is_mifare_ultralight_formatted_(const std::vector<uint8_t> &page_3_to_6);
uint16_t read_mifare_ultralight_capacity_();
bool find_mifare_ultralight_ndef_(const std::vector<uint8_t> &page_3_to_6, 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 write_mifare_ultralight_page_(uint8_t page_num, const uint8_t *write_data, size_t len);
bool write_mifare_ultralight_tag_(nfc::NfcTagUid &uid, nfc::NdefMessage *message);
bool clean_mifare_ultralight_();

bool updates_enabled_{true};
bool requested_read_{false};
std::vector<PN532BinarySensor *> binary_sensors_;
std::vector<nfc::NfcOnTagTrigger *> triggers_ontag_;
std::vector<nfc::NfcOnTagTrigger *> triggers_ontagremoved_;
std::vector<uint8_t> current_uid_;
nfc::NfcTagUid current_uid_;
nfc::NdefMessage *next_task_message_to_write_;
uint32_t rd_start_time_{0};
enum PN532ReadReady rd_ready_ { WOULDBLOCK };
Expand All @@ -118,9 +117,9 @@ class PN532 : public PollingComponent {

class PN532BinarySensor : public binary_sensor::BinarySensor {
public:
void set_uid(const std::vector<uint8_t> &uid) { uid_ = uid; }
void set_uid(const nfc::NfcTagUid &uid) { uid_ = uid; }

bool process(std::vector<uint8_t> &data);
bool process(const nfc::NfcTagUid &data);

void on_scan_end() {
if (!this->found_) {
Expand All @@ -130,7 +129,7 @@ class PN532BinarySensor : public binary_sensor::BinarySensor {
}

protected:
std::vector<uint8_t> uid_;
nfc::NfcTagUid uid_;
bool found_{false};
};

Expand All @@ -143,7 +142,7 @@ class PN532OnFinishedWriteTrigger : public Trigger<> {

template<typename... Ts> class PN532IsWritingCondition : public Condition<Ts...>, public Parented<PN532> {
public:
bool check(Ts... x) override { return this->parent_->is_writing(); }
bool check(const Ts &...x) override { return this->parent_->is_writing(); }
};

} // namespace pn532
Expand Down
Loading