2014-04-14 19 views
6

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 
+0

Emettere un connect() per una qualsiasi delle altre tecnologie (NfcA o IsoDep) prima di connettersi come tecnologia Ndef? –

+0

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? –

+0

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

risposta

3

ora funziona. Ho capito che una routine di avvio che controlla e imposta la parola di configurazione è stata trasmessa con una velocità di trasmissione troppo elevata per AS3953. Questo ha funzionato per la lettura ma qualcosa di deve essere stato mescolato per scrivere sul tag.

Non posso dire con certezza se questo è l'unico motivo per cui non ha funzionato. C'è anche un problema con lettura lenta del FIFO a 32Byte dato che gli interrupt di livello dell'acqua sono gestiti troppo tardi - Mi aspettavo semplicemente il problema di essere sul lato Android poiché non riuscivo a trovare il comando di scrittura nell'analisi logica e l'eccezione non ha descritto la ragione abbastanza.

Grazie mille a Michael Roland per ulteriori debug, io ancora non Unterstand il motivo per cui il tag è letta in un primo momento se voglio scrivere su di esso, ma anche - ci dovrebbe essere una soluzione alternativa la lettura di un messaggio di NDEF vuoto così il processo di scrittura sarà fatto rapidamente.

Per ora devo lavorare sul firmware e non posso prevedere ulteriori problemi, ma il problema effettivo (ndef.writeNdefMessage()) restituisce correttamente.

Problemi correlati