简体   繁体   中英

Communication Nexus 4 PN532 NFC

I am currently planning a project which requires a communication from a Nexus 4 Smartphone to a PN532 NFC chip via NFC. I previously managed to read the content of a Mifare Classic 1k card by using the InListPassiveTarget. The next step I took was reading a programmed RFID Tag and the only content I could read was the UID, ATQA and SAK. I wasn't able to read the data I programmed on the tag which must be stored somewhere deeper.

How can I read the data I programmed, which command do I have to use? I used the InListPassiveTarged command to receive the UID, ATQA and SAK.

My second question is now: Is it possible for me to write an Android App that transmits my data to the PN532? If so, how can I manage to achieve this?


First of all it is crucial, that the data is sent from the Nexus 4 to the PN532. The Android app I used was a slightly modified version of the AndroidBeamDemo (the code is abobe). I also managed to read the NDEF message provided by this app with a NFC Reader app installed on another phone downloaded from the Google Play Store. I recreated the scenario from this tutorial . Here it is described (4a), that after the initialization, the InJumpForDEP command is being used. This is the point where I am stuck at. I initialized the PN532 with normal mode (SAM Configuarion, 0xD4 0x14 0x01). Previous tests showed, that it is no problem to read the UID of a Mifare Card for example (with an InListPassiveTarget command). It was also possible, to read out the UID from a RFID Tag. While executing the commands from the turial (4a), the app displayed the "Tap-to-Beam" screen and the createNdefMessage function was called, but the onNdefPushComplete function was never called, instead the LogCat displayed the outlined above output. I hope with this information my situation is now clearer, thank you for your help.


Regarding my second question, I now almost managed to establish a communication between my PN532 Breakout Board and my Nexus 4. Following the initialization of the PN532, I use the InJumpForDEP command. After that, I get no response from the PN532 and there are some logs tracked with Logcat. I hope you can help me out with the tracked logs and tell me how to deal with the errors.

The data I send within the InJumpForDEP command:

0xD4, 0x56, 0x01, 0x02, 0x04, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x10, 0x03, 0x02, 0x00, 0x01, 0x04, 0x01, 0x96

LogCat:

02-22 17:19:08.418: D/NfceeAccess(834):                  Granted NFCEE access to com.google.android.apps.walletnfcrel (wildcard)
02-22 17:19:08.648: D/NfcService(834):                   LLCP Activation message
02-22 17:19:08.648: I/NfcP2pLinkManager(834):            LLCP activated
02-22 17:19:08.648: D/NfcP2pLinkManager(834):            onP2pInRange()
02-22 17:19:08.648: D/audio_hw_primary(176):             select_devices: out_snd_device(2: speaker) in_snd_device(0: )
02-22 17:19:08.648: D/ACDB-LOADER(176):                  ACDB -> send_afe_cal
02-22 17:19:08.668: I/NFC(5006):                         Create android.nfc.NfcEvent@42025c60
02-22 17:19:08.668: D/NfcP2pLinkManager(834):            onP2pSendConfirmationRequested()
02-22 17:19:08.728: D/dalvikvm(834):                     GC_FOR_ALLOC freed 4322K, 27% free 12775K/17320K, paused 22ms, total 22ms
02-22 17:19:08.748: I/dalvikvm-heap(834):                Grow heap (frag case) to 15.822MB for 3483664-byte allocation
02-22 17:19:08.758: D/dalvikvm(834):                     GC_CONCURRENT freed 11K, 22% free 16166K/20724K, paused 3ms+2ms, total 17ms
02-22 17:19:08.758: D/dalvikvm(834):                     WAIT_FOR_CONCURRENT_GC blocked 7ms
02-22 17:19:08.768: D/PhoneStatusBar(683):               disable: < EXPAND* icons alerts ticker system_info back home recent clock search >
02-22 17:19:08.798: W/InputMethodManagerService(599):    Starting input on non-focused client com.android.internal.view.IInputMethodClient$Stub$Proxy@4254ddf8 (uid=10128 pid=5006)
02-22 17:19:09.449: D/NfcP2pLinkManager(834):            onP2pSendConfirmed()
02-22 17:19:09.639: E/BrcmNfcNfa(834):                   nfa_p2p_proc_llcp_disconnect_ind (): Link deactivated
02-22 17:19:09.639: E/BrcmNfcJni(834):                   PeerToPeer::disconnectConnOriented: can't find connection handle: 22
02-22 17:19:09.639: D/NdefPushClient(834):               about to create socket
02-22 17:19:09.639: D/NdefPushClient(834):               about to connect to service com.android.npp
02-22 17:19:09.649: D/NfcService(834):                   LLCP Link Deactivated message. Restart polling loop.
02-22 17:19:09.649: I/NfcP2pLinkManager(834):            LLCP deactivated.
02-22 17:19:09.649: E/NfcP2pLinkManager(834):            onP2pSendDebounce()
02-22 17:19:09.649: E/BrcmNfcNfa(834):                   NFA_P2pConnectByName ():   MIU(128) must be between 128 and 2175 or LLCP link is not activated
02-22 17:19:09.649: E/BrcmNfcJni(834):                   PeerToPeer::createDataLinkConn: fail; error=0x3
02-22 17:19:09.649: E/BrcmNfcJni(834):                   PeerToPeer::disconnectConnOriented: can't find connection handle: 23
02-22 17:19:14.655: D/NfcP2pLinkManager(834):            Debounce timeout
02-22 17:19:14.655: D/NfcP2pLinkManager(834):            onP2pOutOfRange()

The source code of the Android application:

package com.example.nfc_demo_ndef;

import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcAdapter.OnNdefPushCompleteCallback;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;

public class MainActivity extends Activity implements CreateNdefMessageCallback, OnNdefPushCompleteCallback
{
    private NfcAdapter mNfcAdapter;

    private static final int MESSAGE_SENT = 1;

    /** This handler receives a message from onNdefPushComplete */
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {

            switch (msg.what) {
            case MESSAGE_SENT:
                Toast.makeText(getApplicationContext(), "Message sent!", Toast.LENGTH_LONG).show();
                break;
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        if (mNfcAdapter == null) 
        {
            Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
            finish();
            return;
        }

        // Register callback
        mNfcAdapter.setNdefPushMessageCallback(this, this);
        mNfcAdapter.setOnNdefPushCompleteCallback(this, this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public NdefMessage createNdefMessage(NfcEvent event) 
    {
        String text = ("aaaaaaaa");
        NdefMessage msg = new NdefMessage(
                new NdefRecord[] { NdefRecord.createMime(
                        "text/plain", text.getBytes())
         /**
          * The Android Application Record (AAR) is commented out. When a device
          * receives a push with an AAR in it, the application specified in the AAR
          * is guaranteed to run. The AAR overrides the tag dispatch system.
          * You can add it back in to guarantee that this
          * activity starts when receiving a beamed message. For now, this code
          * uses the tag dispatch system.
          */
          //,NdefRecord.createApplicationRecord("com.example.android.beam")
        });

        Log.i("NFC", "Create " + event.toString());

        return msg;
    }

    @Override
    public void onNdefPushComplete(NfcEvent event)
    {
        mHandler.obtainMessage(MESSAGE_SENT).sendToTarget();     
        Log.i("NFC", "Complete " + event.toString());
    }
}

First answer : You need to use the InListPassiveTarget to get the UID of the MIFARE tag. Following that you have to access the secured data in the tag with the InDataExchange command (using the authentication process).

Second answer : Yes, that is definitely possible. I recommend to use an board with the NFC shield attached. Then you can use either P2P communication using NFC or you can try to configure the PN532 in passive card emulation mode so that the Nexus sees a normal RFID tag. The code provided by the NFC shield is good to go with a first shot.

Before evaluating the problem, there are some things to know in advance:

  • Is the InJumpForDEP command the only command you use for data exchange (after configuration of course)?
  • How do you config the PN532 (as target or initiator)?
  • Did you implement the SNEP protocol and the NFC LinkLayer protocol LLCP ?
  • Did you test your Android code with an NDEF formatted tag? Because that is all about: The exchange of NDEF messages. Unfortunately, there is no direct P2P NFC data transfer possible with the current Android framework provided, or maybe I just do not know about it
  • Did you implement a push or pull or push/pull behavior?
  • Did you cross check with other NFC apps?

In general it is easier to implement a push (eg, an URL) from the PN532 to the Nexus. If the PN532 is configured correctly, Android beam should jump into foreground. So you could check first if your PN532 works right, before you can go on with your own app.

Okay, this is the response I receive for the InJumpForDEP :

0xD5 0x57 0x00 0x01 0x01 0xFE 0x95 0xCA 0x46 0x61 0xC5 0x38 0x00 0x00 0x00 0x00 0x00 0x07 0x32 0x46 0x66 0x6D 0x01 0x01 0x55 0x00 0x00 0x00 0x00 0xFF 0x03 0xFD 0xD4 0x14 0x01 0x17 0x00 0x00 0xFF 0xEE 0xD4 0x56 0x01 0x02 0x04 0x46 0x66 0x6D 0x01 0x01 0x10 0x03 0x02 0x00 0x01 0x04 0x01 0x96 0x03

As you can see, the last bytes 0x46 0x66 0x6D 0x01 0x01 0x10 0x03 0x02 0x00 0x01 0x04 0x01 0x96 are correct, as they are the general bytes that were used as parameters. But for the rest, there is a huge discrepancy.

The part 0x95 0xCA 0x46 0x61 0xC5 0x38 variates from time to time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM