16static std::unique_ptr<nfc::NdefMessage> build_uri_message(
const std::string &uri,
17 const bool include_android_app_record) {
18 auto ndef_message = make_unique<nfc::NdefMessage>();
20 ndef_message->add_uri_record(uri);
22 if (include_android_app_record) {
23 auto ext_record = make_unique<nfc::NdefRecord>();
24 ext_record->set_tnf(nfc::TNF_EXTERNAL_TYPE);
25 ext_record->set_type(nfc::HA_TAG_ID_EXT_RECORD_TYPE);
26 ext_record->set_payload(nfc::HA_TAG_ID_EXT_RECORD_PAYLOAD);
27 ndef_message->add_record(std::move(ext_record));
40 LOG_PIN(
" IRQ pin: ", this->
irq_pin_);
41 LOG_PIN(
" VEN pin: ", this->
ven_pin_);
54 auto encoded =
message->encode();
55 if (encoded.size() > CARD_EMU_T4T_MAX_NDEF_SIZE) {
56 ESP_LOGE(TAG,
"Tag emulation message too long: %zu > %u bytes", encoded.size(), CARD_EMU_T4T_MAX_NDEF_SIZE);
60 for (
const uint8_t
byte : encoded) {
63 ESP_LOGD(TAG,
"Tag emulation message set");
79 ESP_LOGD(TAG,
"Tag emulation disabled");
84 ESP_LOGE(TAG,
"No NDEF message is set; tag emulation cannot be enabled");
91 ESP_LOGD(TAG,
"Tag emulation enabled");
99 ESP_LOGD(TAG,
"Tag polling disabled");
107 ESP_LOGD(TAG,
"Tag polling enabled");
112 ESP_LOGD(TAG,
"Waiting to read next tag");
117 ESP_LOGD(TAG,
"Waiting to clean next tag");
122 ESP_LOGD(TAG,
"Waiting to format next tag");
127 ESP_LOGW(TAG,
"Message to write must be set before setting write mode");
132 ESP_LOGD(TAG,
"Waiting to write next tag");
137 ESP_LOGD(TAG,
"Message to write has been set");
145 std::vector<uint8_t> &result) {
146 auto test_oid = TEST_PRBS_OID;
154 test_oid = TEST_ANTENNA_OID;
158 test_oid = TEST_GET_REGISTER_OID;
163 ESP_LOGD(TAG,
"Exiting test mode");
165 return nfc::STATUS_OK;
168 if (this->
reset_core_(
true,
true) != nfc::STATUS_OK) {
169 ESP_LOGE(TAG,
"Failed to reset NCI core");
172 return nfc::STATUS_FAILED;
177 ESP_LOGE(TAG,
"Failed to initialise NCI core");
180 return nfc::STATUS_FAILED;
186 nfc::NciMessage tx(nfc::NCI_PKT_MT_CTRL_COMMAND, nfc::NCI_PROPRIETARY_GID, test_oid, data);
188 ESP_LOGW(TAG,
"Starting test mode, OID 0x%02X", test_oid);
191 if (
status != nfc::STATUS_OK) {
192 ESP_LOGE(TAG,
"Failed to start test mode, OID 0x%02X", test_oid);
198 result.assign(payload.begin() + std::min<size_t>(1, payload.size()), payload.end());
199 if (!result.empty()) {
200 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
212 delay(NFCC_RESET_DELAY);
214 delay(NFCC_RESET_DELAY);
216 delay(NFCC_INIT_TIMEOUT);
220 nfc::NciMessage tx(nfc::NCI_PKT_MT_CTRL_COMMAND, nfc::NCI_CORE_GID, nfc::NCI_CORE_RESET_OID,
221 {(uint8_t) reset_config});
223 if (this->
transceive_(tx, rx, NFCC_INIT_TIMEOUT) != nfc::STATUS_OK) {
224 ESP_LOGE(TAG,
"Error sending reset command");
225 return nfc::STATUS_FAILED;
229 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
238 nfc::NciMessage tx(nfc::NCI_PKT_MT_CTRL_COMMAND, nfc::NCI_CORE_GID, nfc::NCI_CORE_INIT_OID);
241 ESP_LOGE(TAG,
"Error sending initialise command");
242 return nfc::STATUS_FAILED;
246 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
248 return nfc::STATUS_FAILED;
256 nfc::NciMessage tx(nfc::NCI_PKT_MT_CTRL_COMMAND, nfc::NCI_PROPRIETARY_GID, nfc::NCI_CORE_SET_CONFIG_OID);
259 ESP_LOGE(TAG,
"Error enabling proprietary extensions");
260 return nfc::STATUS_FAILED;
263 tx.
set_message(nfc::NCI_PKT_MT_CTRL_COMMAND, nfc::NCI_CORE_GID, nfc::NCI_CORE_SET_CONFIG_OID, this->
pmu_config());
266 ESP_LOGE(TAG,
"Error sending PMU config");
267 return nfc::STATUS_FAILED;
274 std::span<const uint8_t> core_config = CORE_CONFIG_SOLO;
278 core_config = CORE_CONFIG_RW_CE;
283 nfc::NciMessage tx(nfc::NCI_PKT_MT_CTRL_COMMAND, nfc::NCI_CORE_GID, nfc::NCI_CORE_SET_CONFIG_OID, core_config);
286 ESP_LOGW(TAG,
"Error sending core config");
287 return nfc::STATUS_FAILED;
290 return nfc::STATUS_OK;
299 return nfc::STATUS_FAILED;
306 ESP_LOGV(TAG,
"Failed to refresh core config");
307 return nfc::STATUS_FAILED;
311 return nfc::STATUS_OK;
316 nfc::NciMessage tx(nfc::NCI_PKT_MT_CTRL_COMMAND, nfc::RF_GID, nfc::RF_DISCOVER_MAP_OID,
317 {
sizeof(RF_DISCOVER_MAP_CONFIG) / 3});
318 tx.
append(RF_DISCOVER_MAP_CONFIG);
320 if (this->
transceive_(tx, rx, NFCC_INIT_TIMEOUT) != nfc::STATUS_OK) {
321 ESP_LOGE(TAG,
"Error sending discover map poll config");
322 return nfc::STATUS_FAILED;
324 return nfc::STATUS_OK;
329 nfc::NciMessage tx(nfc::NCI_PKT_MT_CTRL_COMMAND, nfc::RF_GID, nfc::RF_SET_LISTEN_MODE_ROUTING_OID,
332 if (this->
transceive_(tx, rx, NFCC_INIT_TIMEOUT) != nfc::STATUS_OK) {
333 ESP_LOGE(TAG,
"Error setting listen mode routing config");
334 return nfc::STATUS_FAILED;
336 return nfc::STATUS_OK;
340 std::span<const uint8_t> rf_discovery_config = RF_DISCOVERY_CONFIG;
343 rf_discovery_config = RF_DISCOVERY_POLL_CONFIG;
345 rf_discovery_config = RF_DISCOVERY_LISTEN_CONFIG;
349 nfc::NciMessage tx(nfc::NCI_PKT_MT_CTRL_COMMAND, nfc::RF_GID, nfc::RF_DISCOVER_OID,
350 {
static_cast<uint8_t
>(rf_discovery_config.size())});
351 for (
const uint8_t mode_tech : rf_discovery_config) {
352 tx.append({mode_tech, 0x01});
359 case nfc::DISCOVERY_ALREADY_STARTED:
360 case nfc::DISCOVERY_TARGET_ACTIVATION_FAILED:
361 case nfc::DISCOVERY_TEAR_DOWN:
362 return nfc::STATUS_OK;
365 ESP_LOGE(TAG,
"Error starting discovery");
366 return nfc::STATUS_FAILED;
370 return nfc::STATUS_OK;
377 nfc::NciMessage tx(nfc::NCI_PKT_MT_CTRL_COMMAND, nfc::RF_GID, nfc::RF_DEACTIVATE_OID, {
type});
389 ESP_LOGW(TAG,
"No cached tags to select");
403 uint8_t
interface = nfc::INTF_FRAME;
404 if (endpoint.protocol == nfc::PROT_ISODEP) {
405 interface = nfc::INTF_ISODEP;
406 }
else if (endpoint.protocol == nfc::PROT_MIFARE) {
407 interface = nfc::INTF_TAGCMD;
410 nfc::NciMessage tx(nfc::NCI_PKT_MT_CTRL_COMMAND, nfc::RF_GID, nfc::RF_DISCOVER_SELECT_OID,
411 {endpoint.id, endpoint.protocol, interface});
414 ESP_LOGE(TAG,
"Error selecting endpoint");
422 case nfc::PROT_MIFARE:
423 ESP_LOGV(TAG,
"Reading Mifare classic");
427 ESP_LOGV(TAG,
"Reading Mifare ultralight");
431 ESP_LOGV(TAG,
"Reading protocol 0x%02X is not supported", protocol);
434 return nfc::STATUS_FAILED;
439 case nfc::PROT_MIFARE:
446 ESP_LOGE(TAG,
"Unsupported tag for cleaning");
449 return nfc::STATUS_FAILED;
454 case nfc::PROT_MIFARE:
461 ESP_LOGE(TAG,
"Unsupported tag for formatting");
464 return nfc::STATUS_FAILED;
468 std::shared_ptr<nfc::NdefMessage> &
message) {
470 case nfc::PROT_MIFARE:
477 ESP_LOGE(TAG,
"Unsupported tag for writing");
480 return nfc::STATUS_FAILED;
484 if (mode_tech != (nfc::MODE_POLL | nfc::TECH_PASSIVE_NFCA)) {
488 if (rf_tech_params.size() < 3) {
489 ESP_LOGE(TAG,
"NFC-A parameters too short");
492 const uint8_t uid_length = rf_tech_params[2];
493 if (uid_length == 0 || uid_length > nfc::NFC_UID_MAX_LENGTH || rf_tech_params.size() < 3u + uid_length) {
494 ESP_LOGE(TAG,
"Invalid UID length: %u", uid_length);
497 uid.
assign(rf_tech_params.begin() + 3, rf_tech_params.begin() + 3 + uid_length);
502 if (protocol == nfc::PROT_MIFARE) {
503 return make_unique<nfc::NfcTag>(uid, nfc::MIFARE_CLASSIC);
505 if (protocol == nfc::PROT_T2T) {
506 return make_unique<nfc::NfcTag>(uid, nfc::NFC_FORUM_TYPE_2);
508 return make_unique<nfc::NfcTag>(uid);
513 if (tag_loc.has_value()) {
514 ESP_LOGVV(TAG,
"Tag cache updated");
515 return tag_loc.value();
524 ESP_LOGW(TAG,
"Tag cache full; dropping the tag seen longest ago");
530 .protocol = protocol,
531 .trig_called =
false};
532 ESP_LOGVV(TAG,
"Tag added to cache");
540 bool uid_match = (uid.
size() == existing_tag_uid.size());
543 for (
size_t i = 0; i < uid.
size(); i++) {
544 uid_match &= (uid[i] == existing_tag_uid[i]);
567#ifdef PN71XX_ON_TAG_REMOVED_TRIGGER_COUNT
572#ifdef NFC_TAG_LISTENER_COUNT
577 char uid_buf[nfc::FORMAT_UID_BUFFER_SIZE];
592 if (this->
reset_core_(
true,
true) != nfc::STATUS_OK) {
593 ESP_LOGE(TAG,
"Failed to reset NCI core");
603 ESP_LOGE(TAG,
"Failed to initialise NCI core");
613 ESP_LOGE(TAG,
"Failed to send initial config");
624 ESP_LOGE(TAG,
"Failed to set discover map");
634 ESP_LOGE(TAG,
"Failed to set listen mode routing");
656 ESP_LOGV(TAG,
"Failed to start discovery");
683 ESP_LOGW(TAG,
"Timed out waiting for notification in state %u; resetting NFCC", (uint8_t) this->
nci_state_);
701 ESP_LOGVV(TAG,
"nci_fsm_set_state_(%u)", (uint8_t) new_state);
709 ESP_LOGVV(TAG,
"nci_fsm_set_error_state_(%u); error_count_ = %u", (uint8_t) new_state, this->
error_count_);
714 ESP_LOGE(TAG,
"Too many initialization failures -- check device connections");
718 ESP_LOGW(TAG,
"Too many errors transitioning to state %u; resetting NFCC", (uint8_t) this->
nci_state_error_);
727 if (this->
read_nfcc(rx, NFCC_DEFAULT_TIMEOUT) != nfc::STATUS_OK) {
732 case nfc::NCI_PKT_MT_CTRL_NOTIFICATION:
733 if (rx.
get_gid() == nfc::RF_GID) {
735 case nfc::RF_INTF_ACTIVATED_OID:
736 ESP_LOGVV(TAG,
"RF_INTF_ACTIVATED_OID");
740 case nfc::RF_DISCOVER_OID:
741 ESP_LOGVV(TAG,
"RF_DISCOVER_OID");
745 case nfc::RF_DEACTIVATE_OID:
746 ESP_LOGVV(TAG,
"RF_DEACTIVATE_OID: type: 0x%02X, reason: 0x%02X", rx.
get_message()[3], rx.
get_message()[4]);
751 ESP_LOGV(TAG,
"Unimplemented RF OID received: 0x%02X", rx.
get_oid());
753 }
else if (rx.
get_gid() == nfc::NCI_CORE_GID) {
755 case nfc::NCI_CORE_GENERIC_ERROR_OID:
756 ESP_LOGV(TAG,
"NCI_CORE_GENERIC_ERROR_OID:");
758 case nfc::DISCOVERY_ALREADY_STARTED:
759 ESP_LOGV(TAG,
" DISCOVERY_ALREADY_STARTED");
762 case nfc::DISCOVERY_TARGET_ACTIVATION_FAILED:
764 ESP_LOGV(TAG,
" DISCOVERY_TARGET_ACTIVATION_FAILED");
776 case nfc::DISCOVERY_TEAR_DOWN:
777 ESP_LOGV(TAG,
" DISCOVERY_TEAR_DOWN");
787 ESP_LOGV(TAG,
"Unimplemented NCI Core OID received: 0x%02X", rx.
get_oid());
790 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
795 case nfc::NCI_PKT_MT_CTRL_RESPONSE: {
796 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
797 ESP_LOGV(TAG,
"Unimplemented GID: 0x%02X OID: 0x%02X Full response: %s", rx.
get_gid(), rx.
get_oid(),
802 case nfc::NCI_PKT_MT_CTRL_COMMAND: {
803 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
808 case nfc::NCI_PKT_MT_DATA:
813 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
821 uint8_t discovery_id = rx.
get_message_byte(nfc::RF_INTF_ACTIVATED_NTF_DISCOVERY_ID);
822 uint8_t
interface = rx.get_message_byte(nfc::RF_INTF_ACTIVATED_NTF_INTERFACE);
823 uint8_t protocol = rx.get_message_byte(nfc::RF_INTF_ACTIVATED_NTF_PROTOCOL);
824 uint8_t mode_tech = rx.get_message_byte(nfc::RF_INTF_ACTIVATED_NTF_MODE_TECH);
825 uint8_t max_size = rx.get_message_byte(nfc::RF_INTF_ACTIVATED_NTF_MAX_SIZE);
827 ESP_LOGVV(TAG, "Endpoint activated -- interface: 0x%02X, protocol: 0x%02X, mode&tech: 0x%02X, max payload: %u",
828 interface, protocol, mode_tech, max_size);
830 if (mode_tech & nfc::MODE_LISTEN_MASK) {
831 ESP_LOGVV(TAG,
"Tag activated in listen mode");
832 this->nci_fsm_set_state_(NCIState::RFST_LISTEN_ACTIVE);
837 if (rx.
get_message().
size() < nfc::RF_INTF_ACTIVATED_NTF_RF_TECH_PARAMS) {
838 ESP_LOGE(TAG,
"RF_INTF_ACTIVATED_NTF too short");
845 std::span<const uint8_t>(rx.
get_message()).subspan(nfc::RF_INTF_ACTIVATED_NTF_RF_TECH_PARAMS),
847 ESP_LOGE(TAG,
"Could not build tag");
850 working_endpoint.id = discovery_id;
851 working_endpoint.protocol = protocol;
856 ESP_LOGD(TAG,
" Tag cleaning");
857 if (this->
clean_endpoint_(working_endpoint.protocol) != nfc::STATUS_OK) {
858 ESP_LOGE(TAG,
" Tag cleaning incomplete");
860 ESP_LOGD(TAG,
" Tag cleaned!");
864 ESP_LOGD(TAG,
" Tag formatting");
866 ESP_LOGE(TAG,
"Error formatting tag as NDEF");
868 ESP_LOGD(TAG,
" Tag formatted!");
873 ESP_LOGD(TAG,
" Tag writing\n"
876 ESP_LOGE(TAG,
" Tag could not be formatted for writing");
878 ESP_LOGD(TAG,
" Writing NDEF data");
879 if (this->
write_endpoint_(working_endpoint.protocol, working_endpoint.tag->get_uid(),
880 this->next_task_message_to_write_) != nfc::STATUS_OK) {
881 ESP_LOGE(TAG,
" Failed to write message to tag");
883 ESP_LOGD(TAG,
" Finished writing NDEF data");
892 if (!working_endpoint.trig_called) {
893 char uid_buf[nfc::FORMAT_UID_BUFFER_SIZE];
894 ESP_LOGI(TAG,
"Read tag type %s with UID %s", working_endpoint.tag->get_tag_type().c_str(),
896 if (this->
read_endpoint_data_(working_endpoint.protocol, *working_endpoint.tag) != nfc::STATUS_OK) {
897 ESP_LOGW(TAG,
" Unable to read NDEF record(s)");
898 }
else if (working_endpoint.tag->has_ndef_message()) {
899 const auto &
message = working_endpoint.tag->get_ndef_message();
900 const auto &records =
message->get_records();
901 ESP_LOGD(TAG,
" NDEF record(s):");
902 for (
const auto &record : records) {
903 ESP_LOGD(TAG,
" %s - %s", record->get_type().c_str(), record->get_payload().c_str());
906 ESP_LOGW(TAG,
" No NDEF records found");
908#ifdef PN71XX_ON_TAG_TRIGGER_COUNT
910 trigger->process(working_endpoint.tag);
913#ifdef NFC_TAG_LISTENER_COUNT
915 listener->tag_on(*working_endpoint.tag);
918 working_endpoint.trig_called =
true;
923 working_endpoint.last_seen =
millis();
924 if (working_endpoint.protocol == nfc::PROT_MIFARE) {
938 ESP_LOGE(TAG,
"RF_DISCOVER_NTF too short");
941 const uint8_t protocol = rx.
get_message_byte(nfc::RF_DISCOVER_NTF_PROTOCOL);
944 std::span<const uint8_t>(rx.
get_message()).subspan(nfc::RF_DISCOVER_NTF_RF_TECH_PARAMS), uid)) {
945 ESP_LOGE(TAG,
"Could not build tag!");
949 endpoint.protocol = protocol;
954 if (ntf[ntf.size() - 1] != nfc::RF_DISCOVER_NTF_NT_MORE) {
964 case nfc::DEACTIVATION_TYPE_DISCOVERY:
968 case nfc::DEACTIVATION_TYPE_IDLE:
972 case nfc::DEACTIVATION_TYPE_SLEEP:
973 case nfc::DEACTIVATION_TYPE_SLEEP_AF:
989 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
995 if (ndef_response.
empty()) {
1001 if (this->
transceive_(tx, rx, NFCC_DEFAULT_TIMEOUT,
false) != nfc::STATUS_OK) {
1002 ESP_LOGE(TAG,
"Sending reply for card emulation failed");
1009 const uint16_t ndef_msg_size = ndef_message.
size();
1010 const uint32_t file_size = ndef_msg_size + 2;
1016 for (
uint32_t i = offset; i < offset + static_cast<uint32_t>(
length); i++) {
1018 ndef_response.
push_back(ndef_msg_size >> 8);
1019 }
else if (i == 1) {
1020 ndef_response.
push_back(ndef_msg_size & 0xFF);
1022 ndef_response.
push_back(ndef_message[i - 2]);
1026 ESP_LOGD(TAG,
"NDEF message sent");
1033 ndef_response.
clear();
1035 ESP_LOGE(TAG,
"No NDEF message is set; tag emulation not possible");
1038 if (response.size() < nfc::NCI_PKT_HEADER_SIZE) {
1042 const auto apdu_begin = response.begin() + nfc::NCI_PKT_HEADER_SIZE;
1043 const size_t apdu_size = response.size() - nfc::NCI_PKT_HEADER_SIZE;
1044 auto apdu_is = [&](
const uint8_t *cmd,
size_t cmd_size) {
1045 return apdu_size == cmd_size && std::equal(apdu_begin, response.end(), cmd);
1047 auto apdu_starts_with = [&](
const uint8_t *cmd,
size_t cmd_size) {
1048 return apdu_size >= cmd_size && std::equal(cmd, cmd + cmd_size, apdu_begin);
1050 auto append = [&](std::span<const uint8_t> bytes) {
1051 for (
const uint8_t
byte : bytes) {
1057 if (apdu_is(CARD_EMU_T4T_APP_SELECT,
sizeof(CARD_EMU_T4T_APP_SELECT)) ||
1058 apdu_is(CARD_EMU_T4T_APP_SELECT,
sizeof(CARD_EMU_T4T_APP_SELECT) - 1)) {
1059 ESP_LOGVV(TAG,
"CARD_EMU_NDEF_APP_SELECTED");
1062 }
else if (apdu_is(CARD_EMU_T4T_CC_SELECT,
sizeof(CARD_EMU_T4T_CC_SELECT))) {
1064 ESP_LOGVV(TAG,
"CARD_EMU_CC_SELECTED");
1068 }
else if (apdu_is(CARD_EMU_T4T_NDEF_SELECT,
sizeof(CARD_EMU_T4T_NDEF_SELECT))) {
1069 ESP_LOGVV(TAG,
"CARD_EMU_NDEF_SELECTED");
1072 }
else if (apdu_starts_with(CARD_EMU_T4T_READ,
sizeof(CARD_EMU_T4T_READ)) && apdu_size == 5) {
1074 const uint16_t offset = (apdu_begin[2] << 8) | apdu_begin[3];
1075 const uint8_t
length = apdu_begin[4];
1077 ESP_LOGVV(TAG,
"CARD_EMU_T4T_READ with CARD_EMU_CC_SELECTED");
1078 if (offset +
static_cast<uint32_t>(
length) <=
sizeof(CARD_EMU_T4T_CC)) {
1079 append(std::span<const uint8_t>(CARD_EMU_T4T_CC).subspan(offset,
length));
1083 ESP_LOGVV(TAG,
"CARD_EMU_T4T_READ with CARD_EMU_NDEF_SELECTED");
1086 }
else if (apdu_starts_with(CARD_EMU_T4T_WRITE,
sizeof(CARD_EMU_T4T_WRITE)) && apdu_size >= 5) {
1088 const uint8_t
length = apdu_begin[4];
1090 ESP_LOGVV(TAG,
"CARD_EMU_T4T_WRITE");
1091 char write_buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
1092 ESP_LOGD(TAG,
"Received %u-byte NDEF message: %s",
length,
1099 append(CARD_EMU_T4T_OK);
1101 ndef_response.
clear();
1102 append(CARD_EMU_T4T_NOK);
1108 const bool expect_notification) {
1109 char buf[nfc::FORMAT_BYTES_BUFFER_SIZE];
1113 uint8_t attempts = 0;
1114 while (this->
write_nfcc(tx) != nfc::STATUS_OK) {
1115 if (++attempts >= NFCC_MAX_COMM_FAILS) {
1116 ESP_LOGE(TAG,
"Error sending message");
1117 return nfc::STATUS_FAILED;
1119 delay(NFCC_WRITE_RETRY_DELAY);
1127 for (uint8_t i = 0; i < NFCC_MAX_COMM_FAILS; i++) {
1128 if (this->
read_nfcc(rx, timeout) != nfc::STATUS_OK) {
1129 ESP_LOGW(TAG,
"Error receiving response");
1130 return nfc::STATUS_FAILED;
1137 ESP_LOGW(TAG,
"Discarding message received while waiting for response: %s",
1144 return nfc::STATUS_FAILED;
1154 if (this->
read_nfcc(rx, timeout) != nfc::STATUS_OK) {
1155 ESP_LOGW(TAG,
"Error receiving credit notification");
1156 return nfc::STATUS_FAILED;
1162 return nfc::STATUS_FAILED;
1165 if (expect_notification) {
1167 if (this->
read_nfcc(rx, timeout) != nfc::STATUS_OK) {
1168 ESP_LOGE(TAG,
"Error receiving data from endpoint");
1169 return nfc::STATUS_FAILED;
1174 return nfc::STATUS_OK;
1178 auto start_time =
millis();
1180 while (
millis() - start_time < timeout) {
1182 return nfc::STATUS_OK;
1185 return nfc::STATUS_FAILED;
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
void mark_failed()
Mark this component as failed.
void push_back(const T &value)
Add element without bounds checking Caller must ensure sufficient capacity was allocated via init() S...
virtual void digital_write(bool value)=0
virtual bool digital_read()=0
void push_back(const T &value)
static constexpr size_t capacity()
void assign(InputIt first, InputIt last)
One NCI packet, held in a fixed buffer so building and reading messages never allocates.
bool message_type_is(uint8_t message_type) const
bool simple_status_response_is(uint8_t response) const
uint8_t get_message_byte(uint8_t offset) const
bool gid_is(uint8_t gid) const
bool message_length_is(uint8_t message_length, bool recompute=false)
std::span< const uint8_t > get_payload() const
The payload bytes that follow the header.
void set_message(uint8_t message_type, std::span< const uint8_t > payload)
uint8_t get_simple_status_response() const
bool oid_is(uint8_t oid) const
uint8_t get_message_type() const
void append(std::span< const uint8_t > data)
Appends bytes to the payload; bytes that do not fit are dropped.
StaticVector< NfcTagListener *, NFC_TAG_LISTENER_COUNT > tag_listeners_
uint8_t write_mifare_classic_tag_(const std::shared_ptr< nfc::NdefMessage > &message)
void set_tag_emulation_off()
StaticVector< DiscoveredEndpoint, MAX_DISCOVERED_ENDPOINTS > discovered_endpoint_
uint8_t set_test_mode(TestMode test_mode, const std::vector< uint8_t > &data, std::vector< uint8_t > &result)
bool core_config_is_solo_
StaticVector< nfc::NfcOnTagTrigger *, PN71XX_ON_TAG_TRIGGER_COUNT > triggers_ontag_
uint8_t wait_for_irq_(uint16_t timeout=NFCC_DEFAULT_TIMEOUT, bool pin_state=true)
virtual void prepare_reset()
Chip hooks Called before the NFCC is reset, e.g.
uint32_t last_nci_state_change_
uint8_t write_mifare_ultralight_tag_(nfc::NfcTagUid &uid, const std::shared_ptr< nfc::NdefMessage > &message)
uint8_t send_core_config_()
uint8_t stop_discovery_()
void process_message_()
parse & process incoming messages from the NFCC
StaticVector< nfc::NfcOnTagTrigger *, PN71XX_ON_TAG_REMOVED_TRIGGER_COUNT > triggers_ontagremoved_
size_t find_or_add_tag_(uint8_t protocol, const nfc::NfcTagUid &uid)
Finds a cached endpoint by UID, or caches a new one, evicting the entry seen longest ago if the cache...
uint8_t transceive_(nfc::NciMessage &tx, nfc::NciMessage &rx, uint16_t timeout=NFCC_DEFAULT_TIMEOUT, bool expect_notification=true)
std::unique_ptr< nfc::NfcTag > build_tag_(uint8_t protocol, const nfc::NfcTagUid &uid)
uint8_t deactivate_(uint8_t type, uint16_t timeout=NFCC_DEFAULT_TIMEOUT)
void set_tag_emulation_message(const std::shared_ptr< nfc::NdefMessage > &message)
uint8_t set_discover_map_()
void nci_fsm_set_state_(NCIState new_state)
set new controller state
uint8_t clean_mifare_ultralight_()
void nci_fsm_transition_()
advance controller state as required
optional< size_t > find_tag_uid_(const nfc::NfcTagUid &uid)
uint8_t send_init_config_()
uint8_t refresh_core_config_()
uint8_t read_mifare_classic_tag_(nfc::NfcTag &tag)
bool card_emu_t4t_read_ndef_(uint16_t offset, uint8_t length, CardEmuResponse &ndef_response)
uint8_t format_endpoint_(uint8_t protocol)
void process_rf_deactivate_oid_(nfc::NciMessage &rx)
virtual uint8_t verify_reset(nfc::NciMessage &rx, bool reset_config)=0
Validates what follows a successful CORE_RESET_RSP (in rx); may read more messages from the NFCC.
uint8_t read_endpoint_data_(uint8_t protocol, nfc::NfcTag &tag)
virtual std::span< const uint8_t > listen_mode_routing_config() const =0
Payload of the RF_SET_LISTEN_MODE_ROUTING_CMD.
void set_tag_write_message(std::shared_ptr< nfc::NdefMessage > message)
uint8_t clean_endpoint_(uint8_t protocol)
uint8_t format_mifare_classic_ndef_()
void process_data_message_(nfc::NciMessage &rx)
std::shared_ptr< nfc::NdefMessage > next_task_message_to_write_
LazyCallbackManager< void()> on_emulated_tag_scan_callback_
uint8_t halt_mifare_classic_tag_()
virtual uint8_t process_init_response(nfc::NciMessage &rx)=0
Logs chip information from a successful CORE_INIT_RSP.
virtual std::span< const uint8_t > pmu_config() const =0
Parameters for the CORE_SET_CONFIG_CMD that configures the power management unit.
void process_rf_discover_oid_(nfc::NciMessage &rx)
uint8_t reset_core_(bool reset_config, bool power)
uint8_t write_endpoint_(uint8_t protocol, nfc::NfcTagUid &uid, std::shared_ptr< nfc::NdefMessage > &message)
uint8_t set_listen_mode_routing_()
void set_tag_emulation_on()
void dump_config() override
LazyCallbackManager< void()> on_finished_write_callback_
uint8_t read_mifare_ultralight_tag_(nfc::NfcTag &tag)
void process_rf_intf_activated_oid_(nfc::NciMessage &rx)
FixedVector< uint8_t > card_emulation_ndef_
virtual uint8_t write_nfcc(nfc::NciMessage &tx)=0
bool nci_fsm_set_error_state_(NCIState new_state)
setting controller to this state caused an error; returns true if too many errors/failures
uint8_t selecting_endpoint_
virtual uint8_t read_nfcc(nfc::NciMessage &rx, uint16_t timeout)=0
CardEmulationState ce_state_
void card_emu_t4t_get_response_(std::span< const uint8_t > response, CardEmuResponse &ndef_response)
uint8_t start_discovery_()
void erase_tag_(uint8_t tag_index)
uint8_t format_mifare_classic_mifare_()
bool parse_uid_(uint8_t mode_tech, std::span< const uint8_t > rf_tech_params, nfc::NfcTagUid &uid)
Reads the UID from the RF technology parameters of a discovery or activation notification.
bool config_refresh_pending_
NCIState nci_state_error_
const LogString * message
char * format_bytes_to(char *buffer, std::span< const uint8_t > bytes)
Format bytes to buffer with ' ' separator (e.g., "04 11 22 33"). Returns buffer for inline use.
char * format_uid_to(char *buffer, std::span< const uint8_t > uid)
Format UID to buffer with '-' separator (e.g., "04-11-22-33"). Returns buffer for inline use.
@ NFCC_SET_LISTEN_MODE_ROUTING
ESPHOME_LOG_TAG(TAG, "pn71xx")
@ CARD_EMU_NDEF_APP_SELECTED
void HOT delay(uint32_t ms)
uint32_t IRAM_ATTR HOT millis()
Application App
Global storage of Application pointer - only one Application can exist.