Skip to content

Commit 88ca712

Browse files
committed
Say why an operation on a tag did not go through
1 parent f93c0ae commit 88ca712

15 files changed

Lines changed: 793 additions & 364 deletions

File tree

examples/UnitUnified/UHF/Kill/main/Kill.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,9 @@ void dry_run(m5::uhf::Tag& detected)
195195
}
196196
M5_LOGI("Killing with the zero password it holds: %s",
197197
uhf.kill(detected, stored) ? "sent, which it should not be" : "refused before sending");
198+
const auto probed = uhf.kill(detected, PROBE_PASSWORD);
198199
M5_LOGI("Killing with a password it does not hold: %s",
199-
uhf.kill(detected, PROBE_PASSWORD) ? "the tag accepted it" : "the tag refused it");
200+
probed ? "the tag accepted it" : m5::uhf::reasonAsString(probed.error()));
200201
uhf.deselect();
201202
lcd.println("refused, as it should");
202203
}
@@ -222,9 +223,14 @@ void kill_for_good(m5::uhf::Tag& detected)
222223
const std::vector<uint8_t> password{static_cast<uint8_t>(KILL_PASSWORD >> 24),
223224
static_cast<uint8_t>(KILL_PASSWORD >> 16),
224225
static_cast<uint8_t>(KILL_PASSWORD >> 8), static_cast<uint8_t>(KILL_PASSWORD)};
225-
if (!uhf.writeBank(m5::uhf::Bank::Reserved, KILL_PASSWORD_WORD, password.data(),
226-
static_cast<uint16_t>(password.size()))) {
227-
M5_LOGE("Could not write the kill password; the tag is untouched");
226+
const auto stored_password = uhf.writeBank(m5::uhf::Bank::Reserved, KILL_PASSWORD_WORD, password.data(),
227+
static_cast<uint16_t>(password.size()));
228+
if (!stored_password) {
229+
// A tag that answered has not been written to; one that said nothing may hold a
230+
// password nobody knows, which is a tag nobody can kill
231+
M5_LOGE("Could not write the kill password: %s. The tag is %s",
232+
m5::uhf::reasonAsString(stored_password.error()),
233+
m5::uhf::tagUnchanged(stored_password.error()) ? "untouched" : "in a state that cannot be told");
228234
lcd.println("password: not written");
229235
uhf.deselect();
230236
return;
@@ -240,9 +246,9 @@ void kill_for_good(m5::uhf::Tag& detected)
240246
}
241247
M5_LOGW("Kill password written and read back. The tag can now be killed");
242248

243-
const bool killed = uhf.kill(detected, KILL_PASSWORD);
249+
const auto killed = uhf.kill(detected, KILL_PASSWORD);
244250
uhf.deselect();
245-
M5_LOGW("Kill: %s", killed ? "the tag carried it out" : "failed");
251+
M5_LOGW("Kill: %s", killed ? "the tag carried it out" : m5::uhf::reasonAsString(killed.error()));
246252

247253
// The answer to a kill can go missing on the way back, and a tag that did die cannot say so.
248254
// Asking the field is the only way to tell those two apart

examples/UnitUnified/UHF/Lock/main/Lock.cpp

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -145,20 +145,24 @@ void write_probe(const char* when)
145145
constexpr uint32_t RESTORE_INTERVAL_MS{20};
146146

147147
const std::vector<uint8_t> pattern{0x5A, 0xA5};
148-
const bool wrote = uhf.writeBank(m5::uhf::Bank::User, 0, pattern.data(), static_cast<uint16_t>(pattern.size()));
149-
M5_LOGI("Writing one word %s: %s", when, wrote ? "allowed" : "refused");
150-
lcd.printf("write %s: %s\n", when, wrote ? "ok" : "no");
148+
const auto wrote = uhf.writeBank(m5::uhf::Bank::User, 0, pattern.data(), static_cast<uint16_t>(pattern.size()));
149+
// A tag that says no has not been written to; one that says nothing may have been, which is
150+
// a different thing to be told and the reason is what tells them apart
151+
M5_LOGI("Writing one word %s: %s", when, wrote ? "allowed" : m5::uhf::reasonAsString(wrote.error()));
152+
lcd.printf("write %s: %s\n", when, wrote ? "ok" : m5::uhf::tagUnchanged(wrote.error()) ? "no" : "?");
151153
if (!wrote) {
152154
return;
153155
}
154156
const std::vector<uint8_t> zero{0x00, 0x00};
157+
m5::uhf::Result restored{m5::stl::unexpected<m5::uhf::Reason>{m5::uhf::Reason::NoAnswer}};
155158
for (uint8_t i = 0; i < RESTORE_ATTEMPTS; ++i) {
156-
if (uhf.writeBank(m5::uhf::Bank::User, 0, zero.data(), static_cast<uint16_t>(zero.size()))) {
159+
restored = uhf.writeBank(m5::uhf::Bank::User, 0, zero.data(), static_cast<uint16_t>(zero.size()));
160+
if (restored) {
157161
return;
158162
}
159163
m5::utility::delay(RESTORE_INTERVAL_MS);
160164
}
161-
M5_LOGE("FAILED TO RESTORE the word; the tag still holds 5AA5");
165+
M5_LOGE("FAILED TO RESTORE the word (%s); the tag still holds 5AA5", m5::uhf::reasonAsString(restored.error()));
162166
}
163167

164168
//! @brief Address the tag again with a password, since that is what decides the state it is in
@@ -183,9 +187,10 @@ bool set_access_password(const m5::uhf::Tag& tag, const uint32_t password)
183187
{
184188
const std::vector<uint8_t> data{static_cast<uint8_t>(password >> 24), static_cast<uint8_t>(password >> 16),
185189
static_cast<uint8_t>(password >> 8), static_cast<uint8_t>(password)};
186-
if (!uhf.writeBank(m5::uhf::Bank::Reserved, ACCESS_PASSWORD_WORD, data.data(),
187-
static_cast<uint16_t>(data.size()))) {
188-
M5_LOGE("Failed to store the access password %08X", password);
190+
const auto stored =
191+
uhf.writeBank(m5::uhf::Bank::Reserved, ACCESS_PASSWORD_WORD, data.data(), static_cast<uint16_t>(data.size()));
192+
if (!stored) {
193+
M5_LOGE("Failed to store the access password %08X: %s", password, m5::uhf::reasonAsString(stored.error()));
189194
lcd.println("password: failed");
190195
return false;
191196
}
@@ -215,10 +220,11 @@ bool set_access_password(const m5::uhf::Tag& tag, const uint32_t password)
215220
bool set_lock(const m5::uhf::LockTarget target, const m5::uhf::LockAction action, const char* what)
216221
{
217222
const std::vector<m5::uhf::LockSetting> settings{m5::uhf::LockSetting(target, action)};
218-
const bool ok = uhf.lock(settings);
219-
M5_LOGI("%s: %s", what, ok ? "the tag carried it out" : "failed");
220-
lcd.printf("%s: %s\n", what, ok ? "ok" : "NG");
221-
return ok;
223+
const auto result = uhf.lock(settings);
224+
// EPC Gen2 gives no way to read a tag's lock bits, so what the reader says is all there is
225+
M5_LOGI("%s: %s", what, result ? "the tag carried it out" : m5::uhf::reasonAsString(result.error()));
226+
lcd.printf("%s: %s\n", what, result ? "ok" : "NG");
227+
return static_cast<bool>(result);
222228
}
223229

224230
void lock_and_open(m5::uhf::Tag& tag)

examples/UnitUnified/UHF/MonzaQT/main/MonzaQT.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,9 @@ bool look(m5::uhf::Tag& tag, m5::uhf::QTParameters& qt)
123123
(base[1] & 0x80) ? 1 : 0);
124124
}
125125
}
126-
if (!uhf.readQTParameters(qt)) {
127-
M5_LOGE("The tag did not answer the QT command; is it a Monza 4QT?");
126+
const auto read = uhf.readQTParameters(qt);
127+
if (!read) {
128+
M5_LOGE("The QT command did not go through (%s); is it a Monza 4QT?", m5::uhf::reasonAsString(read.error()));
128129
lcd.println("QT: no answer");
129130
uhf.deselect();
130131
return false;
@@ -153,8 +154,9 @@ void switch_map(const bool keep)
153154
M5_LOGI("Switching to the %s map", wanted.public_memory ? "public" : "private");
154155
lcd.printf("-> %s\n", wanted.public_memory ? "public" : "private");
155156
// Written to stay: a volatile switch would be gone before the tag is looked for again
156-
if (!uhf.writeQTParameters(wanted, true)) {
157-
M5_LOGE("Failed to switch the map");
157+
const auto switched = uhf.writeQTParameters(wanted, true);
158+
if (!switched) {
159+
M5_LOGE("Failed to switch the map: %s", m5::uhf::reasonAsString(switched.error()));
158160
lcd.println("switch: failed");
159161
uhf.deselect();
160162
return;
@@ -180,8 +182,10 @@ void switch_map(const bool keep)
180182
}
181183
// Whichever way it went, the tag is put back the way it was found
182184
M5_LOGI("Switching back to the %s map", qt.public_memory ? "public" : "private");
183-
if (!uhf.writeQTParameters(qt, true)) {
184-
M5_LOGE("Failed to switch it back; it is showing its %s map", qt_after.public_memory ? "public" : "private");
185+
const auto back = uhf.writeQTParameters(qt, true);
186+
if (!back) {
187+
M5_LOGE("Failed to switch it back (%s); it is showing its %s map", m5::uhf::reasonAsString(back.error()),
188+
qt_after.public_memory ? "public" : "private");
185189
lcd.println("NOT switched back");
186190
uhf.deselect();
187191
return;

examples/UnitUnified/UHF/NxpG2X/main/NxpG2X.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,10 @@ bool look(m5::uhf::Tag& tag, uint16_t& word)
148148
if (uhf.identify(tag)) {
149149
M5_LOGI("Chip: %s", tag.chipAsString().c_str());
150150
}
151-
if (!uhf.readNxpConfigWord(word)) {
152-
M5_LOGE("The Config-Word could not be read");
151+
const auto read = uhf.readNxpConfigWord(word);
152+
if (!read) {
153+
// A chip that never had the command is a different answer from one that did not reply
154+
M5_LOGE("The Config-Word could not be read: %s", m5::uhf::reasonAsString(read.error()));
153155
lcd.println("no Config-Word");
154156
uhf.deselect();
155157
return false;
@@ -182,8 +184,9 @@ bool set_access_password(const m5::uhf::Tag& tag, const uint32_t password)
182184
{
183185
const uint8_t data[]{static_cast<uint8_t>(password >> 24), static_cast<uint8_t>(password >> 16),
184186
static_cast<uint8_t>(password >> 8), static_cast<uint8_t>(password)};
185-
if (!uhf.writeBank(m5::uhf::Bank::Reserved, ACCESS_PASSWORD_WORD, data, sizeof(data))) {
186-
M5_LOGE("Failed to store the access password %08X", password);
187+
const auto stored = uhf.writeBank(m5::uhf::Bank::Reserved, ACCESS_PASSWORD_WORD, data, sizeof(data));
188+
if (!stored) {
189+
M5_LOGE("Failed to store the access password %08X: %s", password, m5::uhf::reasonAsString(stored.error()));
187190
return false;
188191
}
189192
// The write changed the very password the selection carries, so the tag is addressed again
@@ -216,8 +219,10 @@ void restore_tag(const m5::uhf::Tag& tag, const bool was_raised)
216219
}
217220
uint16_t word{};
218221
if (uhf.readNxpConfigWord(word) && m5::uhf::decodeNxpConfigWord(word).psf_alarm != was_raised) {
219-
if (!uhf.writeNxpEAS(was_raised)) {
220-
M5_LOGE("THE FLAG IS STILL %s; hold the button again", was_raised ? "DOWN" : "UP");
222+
const auto put_back = uhf.writeNxpEAS(was_raised);
223+
if (!put_back) {
224+
M5_LOGE("THE FLAG IS STILL %s (%s); hold the button again", was_raised ? "DOWN" : "UP",
225+
m5::uhf::reasonAsString(put_back.error()));
221226
lcd.println("flag left");
222227
}
223228
}
@@ -249,8 +254,9 @@ void flag_and_unflag()
249254
restore_tag(tag, was_raised);
250255
return;
251256
}
252-
if (!uhf.writeNxpEAS(!was_raised)) {
253-
M5_LOGE("Failed to change the flag");
257+
const auto changed = uhf.writeNxpEAS(!was_raised);
258+
if (!changed) {
259+
M5_LOGE("Failed to change the flag: %s", m5::uhf::reasonAsString(changed.error()));
254260
lcd.println("EAS: failed");
255261
restore_tag(tag, was_raised);
256262
return;

examples/UnitUnified/UHF/NxpReadProtect/main/NxpReadProtect.cpp

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,16 @@ bool look(m5::uhf::Tag& tag, uint16_t& word)
158158
lcd.println("select: failed");
159159
return false;
160160
}
161-
if (!uhf.readNxpConfigWord(word)) {
162-
M5_LOGE("The Config-Word could not be read");
161+
// Which chip this is comes from the TID, and what a chip is decides whether it can have
162+
// the command at all. Asking a chip that cannot costs a round trip and comes back saying
163+
// nothing answered, which is not the same as being told it was never there to answer
164+
if (uhf.identify(tag)) {
165+
M5_LOGI("Chip: %s", tag.chipAsString().c_str());
166+
}
167+
const auto read = uhf.readNxpConfigWord(word);
168+
if (!read) {
169+
// A chip that never had the command is a different answer from one that did not reply
170+
M5_LOGE("The Config-Word could not be read: %s", m5::uhf::reasonAsString(read.error()));
163171
lcd.println("no Config-Word");
164172
uhf.deselect();
165173
return false;
@@ -189,8 +197,9 @@ bool set_access_password(const m5::uhf::Tag& tag, const uint32_t password)
189197
{
190198
const uint8_t data[]{static_cast<uint8_t>(password >> 24), static_cast<uint8_t>(password >> 16),
191199
static_cast<uint8_t>(password >> 8), static_cast<uint8_t>(password)};
192-
if (!uhf.writeBank(m5::uhf::Bank::Reserved, ACCESS_PASSWORD_WORD, data, sizeof(data))) {
193-
M5_LOGE("Failed to store the access password %08X", password);
200+
const auto stored = uhf.writeBank(m5::uhf::Bank::Reserved, ACCESS_PASSWORD_WORD, data, sizeof(data));
201+
if (!stored) {
202+
M5_LOGE("Failed to store the access password %08X: %s", password, m5::uhf::reasonAsString(stored.error()));
194203
return false;
195204
}
196205
// The write changed the very password the selection carries, so the tag is addressed again
@@ -247,8 +256,10 @@ void restore_tag()
247256
undo |= m5::uhf::NXP_CONFIG_PROTECT_TID;
248257
}
249258
if (undo != 0) {
250-
if (!uhf.toggleNxpConfigWord(word, undo)) {
251-
M5_LOGE("THE TAG IS STILL PROTECTED; hold the button again");
259+
const auto undone = uhf.toggleNxpConfigWord(word, undo);
260+
if (!undone) {
261+
M5_LOGE("THE TAG IS STILL PROTECTED (%s); hold the button again",
262+
m5::uhf::reasonAsString(undone.error()));
252263
lcd.println("still protected");
253264
return;
254265
}
@@ -297,8 +308,9 @@ void protect_and_release()
297308
// Inverting both at once, which is what ReadProtect would have done to them
298309
constexpr uint16_t BOTH{m5::uhf::NXP_CONFIG_PROTECT_EPC | m5::uhf::NXP_CONFIG_PROTECT_TID};
299310
uint16_t now{};
300-
if (!uhf.toggleNxpConfigWord(now, BOTH)) {
301-
M5_LOGE("Failed to protect the tag");
311+
const auto protect = uhf.toggleNxpConfigWord(now, BOTH);
312+
if (!protect) {
313+
M5_LOGE("Failed to protect the tag: %s", m5::uhf::reasonAsString(protect.error()));
302314
lcd.println("protect: failed");
303315
restore_tag();
304316
return;

0 commit comments

Comments
 (0)