diff --git a/src/screens/ResultScreen.tsx b/src/screens/ResultScreen.tsx
index 44d4c3f..aaa83a5 100644
--- a/src/screens/ResultScreen.tsx
+++ b/src/screens/ResultScreen.tsx
@@ -219,102 +219,102 @@ export function ResultScreen({ route, navigation }: ResultScreenProps) {
{transponder && (chipInfo || chipFamilyInfo) && (
- setShowChipInfo(!showChipInfo)}
- style={styles.chipInfoHeader}
- activeOpacity={0.7}>
-
- ABOUT THIS CHIP
-
-
- {showChipInfo ? '▼' : '▶'}
-
-
+ setShowChipInfo(!showChipInfo)}
+ style={styles.chipInfoHeader}
+ activeOpacity={0.7}>
+
+ ABOUT THIS CHIP
+
+
+ {showChipInfo ? '▼' : '▶'}
+
+
- {showChipInfo && (
- <>
-
+ {showChipInfo && (
+ <>
+
- {/* Family description */}
- {chipFamilyInfo && (
-
- {chipFamilyInfo}
-
- )}
-
- {/* Detailed chip info */}
- {chipInfo && (
- <>
-
- {chipInfo.description}
+ {/* Family description */}
+ {chipFamilyInfo && (
+
+ {chipFamilyInfo}
+ )}
+
+ {/* Detailed chip info */}
+ {chipInfo && (
+ <>
+
+ {chipInfo.description}
+
+
+ {chipInfo.memoryNote && (
+
+
+ Memory:
+
+
+ {chipInfo.memoryNote}
+
+
+ )}
- {chipInfo.memoryNote && (
- Memory:
+ Security:
-
- {chipInfo.memoryNote}
+
+ {chipInfo.securityLevel.toUpperCase()}
- )}
-
-
- Security:
+
+ {getSecurityLevelDescription(chipInfo.securityLevel)}
-
- {chipInfo.securityLevel.toUpperCase()}
-
-
-
- {getSecurityLevelDescription(chipInfo.securityLevel)}
-
-
- {chipInfo.commonUses.length > 0 && (
- <>
-
- COMMON USES
-
- {chipInfo.commonUses.map((use, idx) => (
-
- • {use}
+ {chipInfo.commonUses.length > 0 && (
+ <>
+
+ COMMON USES
- ))}
- >
- )}
+ {chipInfo.commonUses.map((use, idx) => (
+
+ • {use}
+
+ ))}
+ >
+ )}
- {chipInfo.capabilities.length > 0 && (
- <>
-
- CAPABILITIES
-
- {chipInfo.capabilities.map((cap, idx) => (
-
- • {cap}
+ {chipInfo.capabilities.length > 0 && (
+ <>
+
+ CAPABILITIES
- ))}
- >
- )}
- >
- )}
- >
- )}
-
+ {chipInfo.capabilities.map((cap, idx) => (
+
+ • {cap}
+
+ ))}
+ >
+ )}
+ >
+ )}
+ >
+ )}
+
)}
@@ -341,6 +341,9 @@ export function ResultScreen({ route, navigation }: ResultScreenProps) {
textStyle={styles.formFactorChipText}>
{product.formFactor.replace('_', ' ')}
+ {product.formFactor.startsWith("X") && Injectable}
+ {product.formFactor.startsWith("B") && Large, rigid}
+ {product.formFactor.startsWith("F") && Large, semi-rigid}
@@ -390,28 +393,28 @@ export function ResultScreen({ route, navigation }: ResultScreenProps) {
{transponder && matchResult && matchResult.exactMatches.length === 0 && matchResult.cloneTargets.length === 0 && (
-
- NO DIRECT MATCH
-
-
+
+ NO DIRECT MATCH
+
+
-
- {getMatchSummary(matchResult, transponder.chipName)}
-
+
+ {getMatchSummary(matchResult, transponder.chipName)}
+
- {matchResult.familyMatches.length > 0 && (
- <>
-
- Related products in the same chip family:
-
- {matchResult.familyMatches.slice(0, 2).map(product => (
-
- • {product.name}
+ {matchResult.familyMatches.length > 0 && (
+ <>
+
+ Related products in the same chip family:
- ))}
- >
- )}
-
+ {matchResult.familyMatches.slice(0, 2).map(product => (
+
+ • {product.name}
+
+ ))}
+ >
+ )}
+
)}
@@ -419,29 +422,29 @@ export function ResultScreen({ route, navigation }: ResultScreenProps) {
{transponder?.sakSwapInfo?.hasSakSwap && (
-
- SAK SWAP DETECTED
-
-
+
+ SAK SWAP DETECTED
+
+
-
- {transponder.sakSwapInfo.swapType?.replace(/_/g, ' ').toUpperCase()}
-
+
+ {transponder.sakSwapInfo.swapType?.replace(/_/g, ' ').toUpperCase()}
+
-
- {transponder.sakSwapInfo.description}
-
+
+ {transponder.sakSwapInfo.description}
+
- {transponder.sakSwapInfo.notes && transponder.sakSwapInfo.notes.length > 0 && (
-
- {transponder.sakSwapInfo.notes.map((note, index) => (
-
- • {note}
-
- ))}
-
- )}
-
+ {transponder.sakSwapInfo.notes && transponder.sakSwapInfo.notes.length > 0 && (
+
+ {transponder.sakSwapInfo.notes.map((note, index) => (
+
+ • {note}
+
+ ))}
+
+ )}
+
)}
@@ -449,90 +452,90 @@ export function ResultScreen({ route, navigation }: ResultScreenProps) {
- {tagData ? (
- <>
-
-
- UID
-
-
- {tagData.uid || 'N/A'}
-
-
-
-
-
- TECHNOLOGIES
-
- {
- tagData.techTypes.map((t, i) =>
-
- {t}
- )
- }
-
-
- {tagData.sak !== undefined && (
+ {tagData ? (
+ <>
-
- SAK
+
+ UID
-
- 0x{tagData.sak.toString(16).toUpperCase().padStart(2, '0')}
+
+ {tagData.uid || 'N/A'}
- )}
- {tagData.atqa && (
-
- ATQA
-
-
- {tagData.atqa}
+
+ TECHNOLOGIES
+ {
+ tagData.techTypes.map((t, i) =>
+
+ {t}
+ )
+ }
- )}
- {tagData.historicalBytes && (
-
-
- HISTORICAL BYTES
-
-
- {tagData.historicalBytes}
-
-
- )}
- >
- ) : (
-
- No tag data available
-
- )}
-
+ {tagData.sak !== undefined && (
+
+
+ SAK
+
+
+ 0x{tagData.sak.toString(16).toUpperCase().padStart(2, '0')}
+
+
+ )}
+
+ {tagData.atqa && (
+
+
+ ATQA
+
+
+ {tagData.atqa}
+
+
+ )}
+
+ {tagData.historicalBytes && (
+
+
+ HISTORICAL BYTES
+
+
+ {tagData.historicalBytes}
+
+
+ )}
+ >
+ ) : (
+
+ No tag data available
+
+ )}
+
{/* No Detection Card (fallback) */}
{!transponder && (
-
- CHIP NOT IDENTIFIED
-
-
-
- Unable to identify this chip type. It may be unsupported or require advanced detection.
-
-
- Need help? Ask on our forum for assistance.
-
- Linking.openURL(buildTrackedUrl('https://dngr.us/forum', 'unknown_chip'))}
- >
- VISIT FORUM
-
-
+
+ CHIP NOT IDENTIFIED
+
+
+
+ Unable to identify this chip type. It may be unsupported or require advanced detection.
+
+
+ Need help? Ask on our forum for assistance.
+
+ Linking.openURL(buildTrackedUrl('https://dngr.us/forum', 'unknown_chip'))}
+ >
+ VISIT FORUM
+
+
)}
diff --git a/src/services/detection/desfire.ts b/src/services/detection/desfire.ts
index 1105200..eb20b38 100644
--- a/src/services/detection/desfire.ts
+++ b/src/services/detection/desfire.ts
@@ -78,13 +78,27 @@ export function detectSpark2FromNdef(
/**
* Product type values from GET_VERSION byte 1
+ * Per NXP datasheets:
+ * - NTAG 413 DNA (NT4H1321): Type 0x04, Subtype 0x02
+ * - NTAG 424 DNA (NT4H2421): Type 0x04, Subtype 0x05
+ * - NTAG 424 DNA TT: Type 0x04, Subtype 0x04
+ * - DESFire EV1/EV2/EV3: Type 0x01
*/
const PRODUCT_TYPES = {
DESFIRE: 0x01, // Standard DESFire
- NTAG: 0x04, // NTAG family (including NTAG 413 DNA which uses 0x04)
+ NTAG_DNA: 0x04, // NTAG DNA family (413/424) - distinguished by subtype
NTAG_I2C: 0x05, // NTAG I2C family (can have ISO-DEP on Plus variants)
DESFIRE_LIGHT: 0x08, // DESFire Light
- NTAG_424_DNA: 0x21, // NTAG 424 DNA family
+} as const;
+
+/**
+ * NTAG DNA subtype values from GET_VERSION byte 2
+ * Per NXP NT4H1321 and NT4H2421 datasheets
+ */
+const NTAG_DNA_SUBTYPES = {
+ NTAG413_DNA: 0x02, // NTAG 413 DNA
+ NTAG424_DNA_TT: 0x04, // NTAG 424 DNA TagTamper
+ NTAG424_DNA: 0x05, // NTAG 424 DNA
} as const;
/**
@@ -246,29 +260,31 @@ export async function detectDesfire(): Promise {
// Determine chip type based on product type and version
let chipType: ChipType;
- if (hwProductType === PRODUCT_TYPES.NTAG_424_DNA) {
- // NTAG 424 DNA family uses product type 0x21
- // Subtype 0x02 = TagTamper variant (424 DNA TT only)
- // Storage size helps differentiate:
- // - NTAG 413 DNA: ~160 bytes user memory (storage code <= 0x0E)
- // - NTAG 424 DNA: ~416 bytes user memory (storage code >= 0x0F)
- if (hwSubtype === 0x02) {
- chipType = ChipType.NTAG424_DNA_TT;
- } else if (hwStorageSize <= 0x0e) {
- // Smaller storage indicates NTAG 413 DNA (~160 bytes)
- chipType = ChipType.NTAG413_DNA;
- } else {
- // Larger storage indicates NTAG 424 DNA (~416 bytes)
- chipType = ChipType.NTAG424_DNA;
+ if (hwProductType === PRODUCT_TYPES.NTAG_DNA) {
+ // NTAG DNA family (413/424) - distinguish by subtype per NXP datasheets
+ // NT4H1321 (NTAG 413 DNA): Subtype 0x02, Major 0x04
+ // NT4H2421 (NTAG 424 DNA): Subtype 0x05, Major 0x04
+ // NT4H2421 TT (NTAG 424 DNA TagTamper): Subtype 0x04, Major 0x04
+ switch (hwSubtype) {
+ case NTAG_DNA_SUBTYPES.NTAG413_DNA:
+ console.log('[DESFire] Detected NTAG 413 DNA (product 0x04, subtype 0x02)');
+ chipType = ChipType.NTAG413_DNA;
+ break;
+ case NTAG_DNA_SUBTYPES.NTAG424_DNA_TT:
+ console.log('[DESFire] Detected NTAG 424 DNA TT (product 0x04, subtype 0x04)');
+ chipType = ChipType.NTAG424_DNA_TT;
+ break;
+ case NTAG_DNA_SUBTYPES.NTAG424_DNA:
+ console.log('[DESFire] Detected NTAG 424 DNA (product 0x04, subtype 0x05)');
+ chipType = ChipType.NTAG424_DNA;
+ break;
+ default:
+ // Unknown NTAG DNA subtype - log and fall back to 424 DNA as most common
+ console.warn(
+ `[DESFire] Unknown NTAG DNA subtype: 0x${hwSubtype.toString(16)}, major: 0x${hwMajor.toString(16)}`,
+ );
+ chipType = ChipType.NTAG424_DNA;
}
- } else if (hwProductType === PRODUCT_TYPES.NTAG && hwMajor >= 0x30) {
- // NTAG 413 DNA returns product type 0x04 (like regular NTAG) but with:
- // - hwMajor >= 0x30 (typically 0x30)
- // - hwStorageSize 0x11 (different meaning than regular NTAG)
- // - Responds to IsoDep (unlike regular NTAG 21x)
- // Per NXP NT4H1321 datasheet, NTAG 413 DNA uses this response format
- console.log('[DESFire] Detected NTAG 413 DNA (product type 0x04, hwMajor 0x30+)');
- chipType = ChipType.NTAG413_DNA;
} else if (hwProductType === PRODUCT_TYPES.NTAG_I2C) {
// NTAG I2C family (can have ISO-DEP on Plus variants)
// Per NXP NT3H2111/NT3H2211 datasheet: