This post is part of the Infineon Blockchain Starter Kit road test.

Blockchain - outside of the bitcoin context - is new to me.

Follow along with me on this path to learn the technology....

 

 

Let's dive further into the example Android App "coinfinity". Look how it iteracts with the Infineon Security 2Go cards.

 

 

NFC on Android

 

Android has decent documentation: NFC Basics.

Rough summary: if your application has flagged that it uses the NFC subsystem, and you hold a card to the phone's NFC reader, Android will invoke a callback method in your application.

You can then react on that. The Android lingo is: Intent.

 

Requesting access to NFC is done in the manifest file:

    <uses-permission android:name="android.permission.NFC"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    <uses-feature
            android:name="android.hardware.nfc"
            android:required="true"/>

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

 

 

Here's the method (in MainActivity class) that will get called when NFC (or any other intent) is captured:

    /**
     * Called by Android systems whenever a new Intent is received. NFC tags are also
     * delivered via an Intent.
     *
     * @param intent
     */
    @Override
    protected void onNewIntent(Intent intent) {
        activityPaused = false; // onPause() gets called when a Intent gets dispatched by Android
        setIntent(intent);
        resolveIntent(intent);
    }

 

The stack frame, when a card is detected by the phone:

 

The top method, MainActivity.onNewIntent(), is in the app code. All the rest is standard Android application and event handling.

It shows how this detected event trickles through to a point where you can handle it in the code.

The right half of the image shows the intent's attributes. We got a "tag discovered" message. That makes sense because we just tapped a card on the phone.

 

The app code then calls Android's setIntent() - the usual first action in onNewIntent(). Then over to the app's own resolveIntent().

    /**
     * Will be called after card was hold to back of device.
     *
     * @param intent includes nfc extras
     */
    private void resolveIntent(Intent intent) {
        // Only handle NFC intents
        if (intent.getParcelableExtra(NfcAdapter.EXTRA_TAG) == null) {
            return;
        }

        Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
        UiUtils.logTagInfo(tag);
        IsoDep isoDep = IsoDep.get(tag);
        if (isoDep == null) {
            showToast(getString(R.string.wrong_card), this);
            return;
        }
        // now we have an IsoTag:

        // update UI
        displayOnUI(GuiState.PROGRESS_BAR);

        try {
            SharedPreferences pref = this.getSharedPreferences(PREFERENCE_FILENAME, Context.MODE_PRIVATE);
            pubKeyString = NfcUtils.readPublicKeyOrCreateIfNotExists(IsoTagWrapper.of(isoDep),
                    pref.getInt(KEY_INDEX_OF_CARD, 1)).getPublicKeyInHexWithoutPrefix();
            isoDep.close();
        } catch (IOException | NfcCardException e) {
            showToast(e.getMessage(), this);
            Log.e(TAG, "Exception while reading public key from card: ", e);
            resetGuiState();
            return;
        }
        Log.d(TAG, String.format("pubkey read from card: '%s'", pubKeyString));
        // use web3j to format this public key as ETH address
        ethAddress = Keys.toChecksumAddress(Keys.getAddress(pubKeyString));
        ethAddressView.setText(ethAddress);
        Log.d(TAG, String.format("ETH address: %s", ethAddress));
        qrCodeView.setImageBitmap(QrCodeGenerator.generateQrCode(ethAddress));
        holdCard.setText(R.string.card_found);
    }

 

This is the first time that a specific Infineon NFC class and logic is called.

First there's a test to see if this is an NFC event.

If yes, additional info is recovered from the context that's passed on by Android.

If all matches up, and it's confirmed this is an IsoTag type of card, we try to retrieve the public key (the one that matches the key index selected in the app).

 

 

 

Then an external library, web3j, is used to retrieve the etherium address (it's used for some other transactional functionality later).

The library dependency is documented in the project's (not the app's) Gradle build file:

dependencies {
    // ...
    implementation 'com.github.UnknownEnergy:web3j:android_with_erc20_contract-SNAPSHOT'
    // ...

 

That's then displayed on the app, both as a string and a QR code.

 

What To Look Up Next?

 

This is a good hook to start looking into the NfcUtils class, and see how the public key is actually retrieved from the card.

If you (like me) are new to apps, it's also a good starting point to see how an app works, how events are handled, and see some real code.

 

In the next post, I'm going to investigate how the card info is used when submitting a Blockchain transaction.

 

Related Blog
Blockchain - HyperLedger Fabric: post and search transactions on a distributed trusted ledger
Blockchain - Hyperledger Burrow: set up a distributed ledger
Blockchain - Get Some Crypto Currency on an Infineon Security 2Go Card
Blockchain - Debug the Infineon Demo App with Android Studio and Your Phone
Blockchain - Analyse the Infineon Android Demo App - part a: Detect Card
Blockchain - Analyse the Infineon Android Demo App - part b: Retrieve Ethereum Crypto Currency Balance
Blockchain - Analyse the Infineon Android Demo App - part c: Transaction, Move Crypto Currency to Another Account
Blockchain - Talk Directly to the Infineon 2Go Smart Cards API
Blockchain - Smart Contract Test
Road Test notepad: Infineon Blockchain Starter Kit
Infineon Blockchain Starter Kit - Review