Skip to content

Commit 7d55d28

Browse files
AlbertMNclaude
andcommitted
Cache NDEF data to eliminate repeated reader commands
Previously, NDEF data was read on every 500ms poll cycle even when using cached card detection. This caused excessive reader command traffic that could trigger firmware bugs in readers like ACR1252 (hanging after ~14 consecutive operations). Now the cache includes NDEF data, so detection + NDEF read happens only once per card UID. Subsequent polls return cached data with zero reader commands. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 9889626 commit 7d55d28

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

internal/core/card.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ type Card struct {
3333
}
3434

3535
// cardDetectionCache stores card detection results keyed by UID to avoid
36-
// re-running expensive detection (GET_VERSION, CC reads, memory probes)
37-
// on every poll cycle. The cache is cleared when a card is removed.
36+
// re-running expensive detection (GET_VERSION, CC reads, memory probes, NDEF reads)
37+
// on every poll cycle. This dramatically reduces reader command traffic and prevents
38+
// readers like ACR1252 from becoming unresponsive due to rapid command sequences.
3839
var (
3940
cardDetectionCache = make(map[string]*Card)
4041
cardDetectionCacheMu sync.RWMutex
@@ -119,7 +120,10 @@ func GetCardUID(readerName string) (*Card, error) {
119120

120121
var cardInfo *Card
121122
if found {
122-
// Use cached detection results - only update ATR in case it changed
123+
// Use cached detection results including NDEF data.
124+
// This dramatically reduces reader command traffic - we only detect once
125+
// per card UID, not on every 500ms poll. Critical for readers like ACR1252
126+
// that become unresponsive with rapid command sequences.
123127
logging.Debug(logging.CatCard, "Using cached card detection", map[string]any{"uid": uidHex})
124128
cardInfo = &Card{
125129
UID: cachedCard.UID,
@@ -129,6 +133,9 @@ func GetCardUID(readerName string) (*Card, error) {
129133
ProtocolISO: cachedCard.ProtocolISO,
130134
Size: cachedCard.Size,
131135
Writable: cachedCard.Writable,
136+
Data: cachedCard.Data,
137+
DataType: cachedCard.DataType,
138+
URL: cachedCard.URL,
132139
}
133140
} else {
134141
// No cache - run full detection
@@ -140,7 +147,10 @@ func GetCardUID(readerName string) (*Card, error) {
140147
// Detect card type by reading version info (for NTAG cards)
141148
detectCardType(card, cardInfo)
142149

143-
// Cache the detection result (excluding NDEF data which may change)
150+
// Try to read NDEF data from the card
151+
readNDEFData(card, cardInfo)
152+
153+
// Cache the detection result including NDEF data
144154
cardDetectionCacheMu.Lock()
145155
cardDetectionCache[uidHex] = &Card{
146156
UID: cardInfo.UID,
@@ -150,18 +160,20 @@ func GetCardUID(readerName string) (*Card, error) {
150160
ProtocolISO: cardInfo.ProtocolISO,
151161
Size: cardInfo.Size,
152162
Writable: cardInfo.Writable,
163+
Data: cardInfo.Data,
164+
DataType: cardInfo.DataType,
165+
URL: cardInfo.URL,
153166
}
154167
cardDetectionCacheMu.Unlock()
155168
logging.Debug(logging.CatCard, "Cached card detection result", map[string]any{
156-
"uid": uidHex,
157-
"type": cardInfo.Type,
158-
"size": cardInfo.Size,
169+
"uid": uidHex,
170+
"type": cardInfo.Type,
171+
"size": cardInfo.Size,
172+
"hasNDEF": cardInfo.Data != "",
173+
"dataType": cardInfo.DataType,
159174
})
160175
}
161176

162-
// Try to read NDEF data from the card
163-
readNDEFData(card, cardInfo)
164-
165177
return cardInfo, nil
166178
}
167179

0 commit comments

Comments
 (0)