Skip to content

Commit

Permalink
[android] Read NFC tag containing CHIP setup payload (#3601)
Browse files Browse the repository at this point in the history
* [android] Read NFC tag containing CHIP setup payload

Read CHIP setup payload encoded as URI NDEF Record with
scheme "ch:". This allows to use exactly the same setup
payload as for QR Code generation.

After a succesful NFC Tag read automatically switch to
the Device Details screen of the app to present decoded
information.

* Fix formatting
  • Loading branch information
Damian-Nordic authored and pull[bot] committed Dec 11, 2020
1 parent 8414af0 commit 2026322
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 8 deletions.
6 changes: 6 additions & 0 deletions src/android/CHIPTool/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.NFC" />

<application
android:allowBackup="true"
Expand All @@ -23,6 +24,11 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="ch" /><!-- Process CHIP URIs -->
</intent-filter>
</activity>
<activity
android:name="com.google.chip.chiptool.commissioner.CommissionerActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,20 @@
package com.google.chip.chiptool

import android.content.Intent
import android.nfc.NdefMessage
import android.nfc.NfcAdapter
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import chip.setuppayload.SetupPayloadParser
import com.google.chip.chiptool.attestation.AttestationTestFragment
import com.google.chip.chiptool.clusterclient.OnOffClientFragment
import com.google.chip.chiptool.commissioner.CommissionerActivity
import com.google.chip.chiptool.echoclient.EchoClientFragment
import com.google.chip.chiptool.setuppayloadscanner.BarcodeFragment
import com.google.chip.chiptool.setuppayloadscanner.CHIPDeviceDetailsFragment
import com.google.chip.chiptool.setuppayloadscanner.CHIPDeviceInfo
import com.google.chip.chiptool.setuppayloadscanner.QrCodeInfo

class CHIPToolActivity :
AppCompatActivity(),
Expand All @@ -45,6 +49,9 @@ class CHIPToolActivity :
.add(R.id.fragment_container, fragment, fragment.javaClass.simpleName)
.commit()
}

if (intent?.action == NfcAdapter.ACTION_NDEF_DISCOVERED)
onNfcIntent(intent)
}

override fun onCHIPDeviceInfoReceived(deviceInfo: CHIPDeviceInfo) {
Expand Down Expand Up @@ -89,6 +96,31 @@ class CHIPToolActivity :
.commit()
}

private fun onNfcIntent(intent: Intent?) {
// Require 1 NDEF message containing 1 NDEF record
val messages = intent?.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES)
if (messages?.size != 1) return

val records = (messages[0] as NdefMessage).records
if (records.size != 1) return

// Require NDEF URI record starting with "ch:"
val uri = records[0].toUri()
if (!uri?.scheme.equals("ch", true)) return

val setupPayload = SetupPayloadParser().parseQrCode(uri.toString().toUpperCase())
val deviceInfo = CHIPDeviceInfo(
setupPayload.version,
setupPayload.vendorId,
setupPayload.productId,
setupPayload.discriminator,
setupPayload.setupPinCode,
setupPayload.optionalQRCodeInfo.mapValues { (_, info) -> QrCodeInfo(info.tag, info.type, info.data, info.int32) }
)

onCHIPDeviceInfoReceived(deviceInfo)
}

companion object {
var REQUEST_CODE_COMMISSIONING = 0xB003
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,20 +117,13 @@ class BarcodeFragment : Fragment(), CHIPBarcodeProcessor.BarcodeDetectionListene
stopCamera()

val payload = SetupPayloadParser().parseQrCode(barcode.displayValue)

val optionalQrCodeInfo = payload.optionalQRCodeInfo
val qrCodeInfoMap = HashMap<Int, QrCodeInfo>()
optionalQrCodeInfo.forEach { (i, info) ->
qrCodeInfoMap[i] = QrCodeInfo(info.tag, info.type, info.data, info.int32)
}

val deviceInfo = CHIPDeviceInfo(
payload.version,
payload.vendorId,
payload.productId,
payload.discriminator,
payload.setupPinCode,
qrCodeInfoMap
payload.optionalQRCodeInfo.mapValues { (_, info) -> QrCodeInfo(info.tag, info.type, info.data, info.int32) }
)
FragmentUtil.getHost(this, Callback::class.java)?.onCHIPDeviceInfoReceived(deviceInfo)
}
Expand Down

0 comments on commit 2026322

Please sign in to comment.