Sto sviluppando un ambiente NFC costituito da un tag (chip AS3953 + microcontroller) e uno smartphone (Android Galaxy Fame runnung Android 4.1.2).Android NFC writeNdefMessage genera IOException Tag non è ndef
Durante la lettura di un messaggio NDEF, sono bloccato a scrivere il messaggio sul tag. Ho copiato la maggior parte del codice da http://tapintonfc.blogspot.de/2012/07/the-above-footage-from-our-nfc-workshop.html e l'ho modificato per accettare il tag di tipo 4 ISO14443A cercando la tag lista tecnica per IsoDep, NfcA e Ndef in supportedTechs(). Dal momento che tutti loro sono elencati l'applicazione continua a writeTag():
public WriteResponse writeTag(NdefMessage message, Tag tag) {
try {
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
Log.d(TAG, "writeTag: tag type: "+ndef.getType());
ndef.connect();
Log.d(TAG, "writeTag: connected!");
if (!ndef.isWritable()) {
return new WriteResponse(0, "Tag is read-only");
}
if (ndef.getMaxSize() < message.toByteArray().length) {
return new WriteResponse(0, "size error");
}
Log.d(TAG, "writeTag: write ndef...");
ndef.writeNdefMessage(message);
Log.d(TAG, "writeTag: wrote ndef!");
if (writeProtect)
ndef.makeReadOnly();
return new WriteResponse(1, "Wrote message to pre-formatted tag.");
} else {
Log.d(TAG, "writeTag: ndef==null!");
return new WriteResponse(0, "writeTag: ndef==null!");
}
} catch (Exception e) {
Log.d(TAG, "writeTag: exception: " + e.toString());
return new WriteResponse(0, "Failed to write tag");
}
}
LogCat mostra:
11:08:46.400: onNewIntent 11:08:46.400: supportedTechs: techlist: android.nfc.tech.IsoDep,android.nfc.tech.NfcA,android.nfc.tech.Ndef, 11:08:46.400: supportedTechs: tech is supported! 11:08:46.400: writeTag: tag type: org.nfcforum.ndef.type4 11:08:46.410: writeTag: connected! 11:08:46.410: writeTag: write ndef... 11:08:46.490: writeTag: exception: java.io.IOException: Tag is not ndef
Come si può vedere un'IOException è gettato dicendo che il tag non è NDEF che contraddice la techlist. Esaminando ulteriormente il codice Android writeNdefMessage() tenta di ottenere un TagService e un ServiceHandle dal tag per abbinarli. Questo non riesce così viene lanciata l'eccezione (nessun messaggio scritto fino ad oggi):
public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
...
INfcTag tagService = mTag.getTagService();
...
int serviceHandle = mTag.getServiceHandle();
if (tagService.isNdef(serviceHandle)) {
...
}
else {
throw new IOException("Tag is not ndef");
}
...
}
Esiste una soluzione per che o non è possibile a tutti con il mio tipo di tag? Mentre sto programmando il tag, l'errore potrebbe essere sull'altro lato, ma è che sembra essere un problema Java.
Edit 1:
Non connettersi a qualsiasi tecnologia di prima quindi non ci dovrebbe essere alcun collegamento aperto. Se apro una connessione prima di ndef.connect() c'è IllegalStateException: chiudi prima altra tecnologia!
Ho configurato da AS3953 a ISO14443A livello 4 in modo che solo i blocchi di tipo di etichetta 4 vengono inoltrati al microcontroller . Vengono gestiti solo I-Blocks ma, anche se ci sono altri comandi, μC deve leggerlo sulla porta SPI, che non è il caso dell'analisi logica. Come ho detto leggendo il file ndef funziona e l'ho testato per un file 4KB. Guardando l'analisi logica sono fatte le seguenti fasi (tutto restituzione di un 9000-code positivo):
(c=command, r=response) (corrected due to renaming mistake) select by name: c: 02 00 a4 04 00 07 d2 76 00 00 85 01 01 00 r: 02 90 00 select by id - select cc file c: 03 00 a4 00 0c 02 e1 03 r: 03 90 00 read 0x0f bytes of cc file c: 02 00 b0 00 00 0f r: 02 00 0f 20 00 3b 00 34 04 06 e1 04 0f ff 00 00 90 00 select by id - select ndef file c: 03 00 a4 00 0c 02 e1 04 r: 03 90 00 read 0x02 bytes (first 2 bytes are apdu-size) c: 02 00 b0 00 00 02 r: 02 0f d3 90 00 read 0x3b bytes (frame size) of first part of ndef file (external type, jpeg image as payload) c: 03 00 b0 00 02 3b r: 03 c4 0c 00 00 0f c1 64 65 2e 74 65 73 74 61 70 70 3a 61 01 ff d8 ff e0 00 10 4a 46 49 46 00 01 01 01 00 60 00 60 00 00 ff db 00 43 00 49 32 36 40 36 2d 49 40 3b 40 52 4d 49 56 6d 90 00 [ndef file] read 0x26 bytes of last part of ndef file c: 03 00 b0 0f ae 27 r: 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 FF D9 00 00 90 00
Utilizzando la stessa applicazione per la scrittura mi metto l'attività che filtra intenti NfcAdapter.ACTION_TAG_DISCOVERED. Proprio come nell'esempio collegato, il telefono tocca il tag chiamando suResume() facendo mNfcAdapter.enableForegroundDispatch (...);
Quando registro la comunicazione SPI, viene eseguita la stessa procedura di lettura di cui sopra. Dal momento che LogCat mostra un dispatcher di intenti di lavoro, suppongo che l'app si fermi all'IOException, chiudendo la connessione e andando subito a leggere mentre Android ha trovato di nuovo il tag.
Edit 2:
Ci potrebbe essere un suggerimento come uno dei primi interrupt emettere un comando deselezionare che è gestita da AS3953 sé:
(count * interrupt) 3 * power up 1 * Wake-up IRQ at entry in ACTIVE(*) state 1 * Deselect command 1 * Wake-up IRQ at entry in ACTIVE(*) state 1 * IRQ due to start of receive
Emettere un connect() per una qualsiasi delle altre tecnologie (NfcA o IsoDep) prima di connettersi come tecnologia Ndef? –
Presumo che si stia utilizzando l'AS3953 in modalità diretta e che si gestiscano i comandi ISO 14443-4/ISO 7816-4 sul microcontrollore. Potrebbe essere che non gestisci correttamente tutti i comandi necessari per un tag di tipo 4 Forum NFC? –
Ho aggiunto alcune informazioni nel post originale. Cosa intendi per modalità diretta? La maggior parte dello stack del protocollo (ovvero fino a ISO14443A-4) viene eseguito dall'AS3953 stesso. Se non viene gestito alcun comando, deve essere presente un comando SPI che legge il buffer rx almeno – Eric