@wimetrix/nfc-serial-reader 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc.js ADDED
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ root: true,
3
+ extends: ["universe/native", "universe/web"],
4
+ ignorePatterns: ["build"],
5
+ };
package/.gitattributes ADDED
@@ -0,0 +1 @@
1
+ * text=auto eol=lf
package/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ lts/*
@@ -0,0 +1,13 @@
1
+ # Ignore artifacts:
2
+ build
3
+ coverage
4
+ node_modules
5
+ dist
6
+ build
7
+ pnpm-lock.yaml
8
+ package-lock.json
9
+ yarn.lock
10
+ trace
11
+ tsconfig.vitest-temp.json
12
+ android
13
+ ios
package/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # NFC Serial Reader
2
+
3
+ This module allows reading NFC tags using a serial connection to an RFID reader.
4
+
5
+ ## Installation
6
+
7
+ To install run:
8
+
9
+ ```bash
10
+ pnpm add nfc-box-reader
11
+ ```
12
+
13
+ or
14
+
15
+ ```bash
16
+ npm install nfc-box-reader
17
+ ```
18
+
19
+ or
20
+
21
+ ```bash
22
+ yarn add nfc-box-reader
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ NFC serial reader module provides the following API:
28
+
29
+ ### `connectNFCSerialReader`
30
+
31
+ This connects to the NFC reader on the given serial port and specified baud rate, starts reading in
32
+ the background and returns a boolean indicating if the connection was successful.
33
+
34
+ ```typescript
35
+ import { connectNFCSerialReader } from "nfc-box-reader";
36
+
37
+ const connected = await connectNFCSerialReader("/dev/ttyS0", 9600);
38
+ ```
39
+
40
+ ### `addNFCReadListener`
41
+
42
+ > Note: This function should be called after `connectNFCSerialReader` has been called.
43
+
44
+ This adds a listener to the NFC reader, the listener will be called every time a new tag is read.
45
+
46
+ ```typescript
47
+ import { addNFCReadListener } from "nfc-box-reader";
48
+
49
+ addNFCReadListener((card) => {
50
+ console.log(`Card Type: ${card.cardType}`);
51
+ console.log(`Card ID: ${card.cardId}`);
52
+ });
53
+ ```
54
+
55
+ The payload of the listener is an object with the following properties:
56
+
57
+ - `cardType`: The type of the card, this is either "TAG" and "WORKER". These are the only two
58
+ supported card types, if the card type is not one of these two values, then the card type
59
+ is returned as "UNKNOWN".
60
+ - `cardId`: The ID of the card which is an integer value.
61
+
62
+ This returns a function that can be called to remove the listener.
63
+
64
+ ### `disconnectNFCSerialReader`
65
+
66
+ This disconnects the NFC reader, stops reading and returns a boolean indicating if the
67
+ disconnection was successful.
68
+
69
+ ```typescript
70
+ import { disconnectNFCSerialReader } from "nfc-box-reader";
71
+
72
+ const disconnected = await disconnectNFCSerialReader();
73
+ ```
74
+
75
+ ### `listSerialPorts`
76
+
77
+ This returns a list of available serial ports on the device (the options that can be passed to
78
+ `connectNFCSerialReader`).
79
+
80
+ ```typescript
81
+ import { listSerialPorts } from "nfc-box-reader";
82
+
83
+ const ports = await listSerialPorts();
84
+ ```
85
+
86
+ ### `listBaudRates`
87
+
88
+ This returns a list of available baud rates that can be passed to `connectNFCSerialReader`.
89
+ The baud rates are hardcoded to the following values: `[9600, 19200, 38400, 57600, 115200]`.
90
+
91
+ ```typescript
92
+ import { listBaudRates } from "nfc-box-reader";
93
+
94
+ const baudRates = listBaudRates();
95
+ ```
@@ -0,0 +1,58 @@
1
+ apply plugin: 'com.android.library'
2
+
3
+ group = 'expo.modules.nfcserialreader'
4
+ version = '0.0.1'
5
+
6
+ def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
7
+ apply from: expoModulesCorePlugin
8
+ applyKotlinExpoModulesCorePlugin()
9
+ useCoreDependencies()
10
+ useExpoPublishing()
11
+
12
+ // If you want to use the managed Android SDK versions from expo-modules-core, set this to true.
13
+ // The Android SDK versions will be bumped from time to time in SDK releases and may introduce breaking changes in your module code.
14
+ // Most of the time, you may like to manage the Android SDK versions yourself.
15
+ def useManagedAndroidSdkVersions = false
16
+ if (useManagedAndroidSdkVersions) {
17
+ useDefaultAndroidSdkVersions()
18
+ } else {
19
+ buildscript {
20
+ // Simple helper that allows the root project to override versions declared by this library.
21
+ ext.safeExtGet = { prop, fallback ->
22
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
23
+ }
24
+ }
25
+ project.android {
26
+ compileSdkVersion safeExtGet("compileSdkVersion", 34)
27
+ defaultConfig {
28
+ minSdkVersion safeExtGet("minSdkVersion", 21)
29
+ targetSdkVersion safeExtGet("targetSdkVersion", 34)
30
+ }
31
+ }
32
+ }
33
+
34
+ android {
35
+ namespace "expo.modules.nfcserialreader"
36
+ defaultConfig {
37
+ versionCode 1
38
+ versionName "0.0.1"
39
+ }
40
+ sourceSets {
41
+ main {
42
+ jniLibs.srcDirs = ['src/main/jniLibs']
43
+ }
44
+ }
45
+ lintOptions {
46
+ abortOnError false
47
+ }
48
+ }
49
+
50
+ repositories {
51
+ flatDir {
52
+ dirs 'libs'
53
+ }
54
+ }
55
+
56
+ dependencies {
57
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
58
+ }
Binary file
@@ -0,0 +1,2 @@
1
+ <manifest>
2
+ </manifest>
@@ -0,0 +1,166 @@
1
+ package expo.modules.nfcserialreader
2
+
3
+ import android.util.Log
4
+ import com.liang.rfid.Reader;
5
+ import java.io.File
6
+
7
+ class NFCReaderService(
8
+ module: NFCSerialReaderModule,
9
+ ) {
10
+ val nfcSerialReaderModule = module
11
+ var reader: Reader? = null
12
+ val key: ByteArray =
13
+ byteArrayOf(
14
+ 0xFF.toByte(),
15
+ 0xFF.toByte(),
16
+ 0xFF.toByte(),
17
+ 0xFF.toByte(),
18
+ 0xFF.toByte(),
19
+ 0xFF.toByte(),
20
+ )
21
+ val readerArgOne = 0x05.toByte()
22
+ val readerArgTwo = 0x03.toByte()
23
+ val readerArgThree = 0x00.toByte()
24
+ val hexChars = "0123456789ABCDEF".toCharArray()
25
+ val cardTypes =
26
+ mapOf(
27
+ 0 to "TAG",
28
+ 5 to "WORKER",
29
+ )
30
+ companion object {
31
+ private const val TAG = "NFCSerialReader"
32
+ }
33
+
34
+ // Extend the ByteArray class to add new function to convert byte array to hex string
35
+ fun ByteArray.toHex(): String {
36
+ val result = StringBuffer()
37
+
38
+ forEach {
39
+ val octet = it.toInt()
40
+ val firstIndex = (octet and 0xF0).ushr(4)
41
+ val secondIndex = octet and 0x0F
42
+ result.append(hexChars[firstIndex])
43
+ result.append(hexChars[secondIndex])
44
+ }
45
+
46
+ return result.toString()
47
+ }
48
+
49
+ fun connect(
50
+ serialPort: String,
51
+ baudRate: Int,
52
+ ): Boolean {
53
+ if (reader != null) {
54
+ Log.i(TAG, "Reader is already connected to $serialPort at $baudRate baud rate")
55
+ return true
56
+ }
57
+
58
+ try {
59
+ Log.i(TAG, "Connecting to the reader at $serialPort with $baudRate baud rate")
60
+ reader = Reader.getInstance(serialPort, baudRate)
61
+ Log.i(
62
+ TAG,
63
+ "Successfully connected to the reader at $serialPort with $baudRate baud rate",
64
+ )
65
+
66
+ // Start reading from the reader
67
+ Thread {
68
+ while (true) {
69
+ // If the reader is null, then we break the loop and stop reading
70
+ // This ensures that we stop reading when the reader is disconnected
71
+ if (reader == null) break
72
+ read()
73
+ Thread.sleep(1000)
74
+ }
75
+ }.start()
76
+
77
+ return true
78
+ } catch (e: Exception) {
79
+ Log.e(
80
+ TAG,
81
+ "Failed to connect to the reader at $serialPort with $baudRate baud rate: $e",
82
+ )
83
+ e.printStackTrace()
84
+ return false
85
+ }
86
+ }
87
+
88
+ fun disconnect(): Boolean {
89
+ if (reader == null) {
90
+ Log.i(TAG, "Reader is already disconnected")
91
+ return true
92
+ }
93
+
94
+ try {
95
+ Log.i(TAG, "Disconnecting from the reader")
96
+ reader?.close()
97
+ reader = null
98
+ Log.i(TAG, "Successfully disconnected from the reader")
99
+ return true
100
+ } catch (e: Exception) {
101
+ Log.e(TAG, "Failed to disconnect from the reader: $e")
102
+ e.printStackTrace()
103
+ return false
104
+ }
105
+ }
106
+
107
+ fun read() {
108
+ try {
109
+ val readData = ByteArray(48)
110
+ val errorCode = ByteArray(1)
111
+ val result =
112
+ reader?.Iso14443a_Read(
113
+ readerArgOne,
114
+ readerArgTwo,
115
+ readerArgThree,
116
+ key,
117
+ readData,
118
+ errorCode,
119
+ )
120
+
121
+ // If the result is not 0, then there was no card to read, so we early return
122
+ if (result != 0) return
123
+
124
+ // Extract the card ID from the read data using bitwise operations
125
+ val cardId =
126
+ ((readData[3].toInt() and 0xFF) shl 24) or
127
+ ((readData[2].toInt() and 0xFF) shl 16) or
128
+ ((readData[1].toInt() and 0xFF) shl 8) or
129
+ (readData[0].toInt() and 0xFF)
130
+
131
+ // Convert the read data to a hex string
132
+ val hexData = readData.toHex()
133
+
134
+ // Extract the card type from the read data
135
+ val cardType = hexData.substring(9, 10).toInt(16)
136
+
137
+ // Translate the card type to a human-readable string
138
+ val cardTypeString = cardTypes[cardType] ?: "UNKNOWN"
139
+
140
+ // If card type is 0, which
141
+ val finalCardId =
142
+ if (cardType == 0) {
143
+ hexData.substring(0, 8) // string
144
+ } else {
145
+ cardId.toString() // convert int to string
146
+ }
147
+
148
+ Log.i(
149
+ TAG,
150
+ "Read card of type $cardType translated to $cardTypeString with raw ID $cardId, final ID $finalCardId"
151
+ )
152
+
153
+ // Send the event to the JS side with the card ID and card type
154
+ nfcSerialReaderModule.sendEvent(
155
+ "onRead",
156
+ mapOf(
157
+ "cardId" to finalCardId,
158
+ "cardType" to cardTypeString,
159
+ ),
160
+ )
161
+ } catch (e: Exception) {
162
+ Log.e(TAG, "Failed to read from the reader, got error: $e")
163
+ e.printStackTrace()
164
+ }
165
+ }
166
+ }
@@ -0,0 +1,64 @@
1
+ package expo.modules.nfcserialreader
2
+
3
+ import android.util.Log
4
+ import expo.modules.kotlin.modules.Module
5
+ import expo.modules.kotlin.modules.ModuleDefinition
6
+ import java.io.File
7
+
8
+ class NFCSerialReaderModule : Module() {
9
+ companion object {
10
+ private const val TAG = "NFCSerialReaderModule"
11
+ }
12
+
13
+ val nfcReader = NFCReaderService(this@NFCSerialReaderModule)
14
+ val serialPorts = mutableListOf<String>()
15
+
16
+ // Get list of available serial ports on the device
17
+ fun listSerialPorts(): List<String> {
18
+ if (serialPorts.isEmpty()) {
19
+ val devDirectory = File("/dev")
20
+
21
+ if (devDirectory.exists() && devDirectory.isDirectory) {
22
+ val files = devDirectory.listFiles()
23
+
24
+ if (files != null) {
25
+ for (file in files) {
26
+ if (file.name.startsWith("tty")) {
27
+ serialPorts.add(file.absolutePath)
28
+ }
29
+ }
30
+ }
31
+ } else {
32
+ Log.e(TAG, "Error Listing Serial Ports! /dev Directory does not exist!")
33
+ }
34
+ }
35
+
36
+ return serialPorts
37
+ }
38
+
39
+ // Pre-defined baud rates
40
+ fun listBaudRates() = listOf(9600, 19200, 38400, 57600, 115200)
41
+
42
+ override fun definition() =
43
+ ModuleDefinition {
44
+ Name("NFCSerialReader")
45
+
46
+ Events("onRead")
47
+
48
+ Function("connect") { serialPort: String, baudRate: Int ->
49
+ nfcReader.connect(serialPort, baudRate)
50
+ }
51
+
52
+ Function("listSerialPorts") {
53
+ listSerialPorts()
54
+ }
55
+
56
+ Function("listBaudRates") {
57
+ listBaudRates()
58
+ }
59
+
60
+ Function("disconnect") {
61
+ nfcReader.disconnect()
62
+ }
63
+ }
64
+ }
package/cspell.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "ignorePaths": [
3
+ ".git",
4
+ ".vscode",
5
+ ".vscode-insiders",
6
+ "**/*.apk",
7
+ "android",
8
+ "build",
9
+ "dist",
10
+ "ios",
11
+ "node_modules",
12
+ "package-lock.json",
13
+ "pnpm-lock.yaml",
14
+ "public",
15
+ "trace",
16
+ "tsconfig.vitest-temp.json",
17
+ "vscode-extension",
18
+ "yarn.lock"
19
+ ],
20
+ "words": ["nfcserialreader", "RFID", "rssi", "UHF"]
21
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "platforms": ["android"],
3
+ "android": {
4
+ "modules": ["expo.modules.nfcserialreader.NFCSerialReaderModule"]
5
+ }
6
+ }
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@wimetrix/nfc-serial-reader",
3
+ "version": "1.0.0",
4
+ "description": "This module allows reading NFC tags using a serial connection to an RFID reader.",
5
+ "main": "build/index.js",
6
+ "types": "build/index.d.ts",
7
+ "scripts": {
8
+ "build": "expo-module build",
9
+ "clean": "expo-module clean",
10
+ "lint": "expo-module lint",
11
+ "test": "expo-module test",
12
+ "expo-module": "expo-module",
13
+ "open:ios": "xed example/ios",
14
+ "open:android": "open -a \"Android Studio\" example/android"
15
+ },
16
+ "keywords": [
17
+ "react-native",
18
+ "expo",
19
+ "nfc-serial-reader",
20
+ "nfc-box-reader",
21
+ "NFCSerialReader"
22
+ ],
23
+ "license": "MIT",
24
+ "devDependencies": {
25
+ "@types/react": "^18.0.25",
26
+ "expo-module-scripts": "^3.5.2",
27
+ "expo-modules-core": "^1.12.24"
28
+ },
29
+ "peerDependencies": {
30
+ "expo": "*",
31
+ "react": "*",
32
+ "react-native": "*"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "https://github.com/WiMetrixDev/nfc-serial-reader"
37
+ },
38
+ "packageManager": "yarn@4.5.0"
39
+ }
@@ -0,0 +1,7 @@
1
+ /** @type {import('prettier').Config} */
2
+ const config = {
3
+ useTabs: true,
4
+ singleAttributePerLine: true,
5
+ };
6
+
7
+ module.exports = config;
@@ -0,0 +1,5 @@
1
+ import { requireNativeModule } from "expo-modules-core";
2
+
3
+ // It loads the native module object from the JSI or falls back to
4
+ // the bridge module (from NativeModulesProxy) if the remote debugger is on.
5
+ export default requireNativeModule("NFCSerialReader");
package/src/index.ts ADDED
@@ -0,0 +1,39 @@
1
+ import { EventEmitter, NativeModulesProxy } from "expo-modules-core";
2
+
3
+ import NFCSerialReaderModule from "./NFCSerialReaderModule";
4
+
5
+ import type { Subscription } from "expo-modules-core";
6
+
7
+ export function connectNFCSerialReader(
8
+ serialPort: string,
9
+ baudRate: number
10
+ ): boolean {
11
+ return NFCSerialReaderModule.connect(serialPort, baudRate);
12
+ }
13
+
14
+ export function listSerialPorts(): string[] {
15
+ return NFCSerialReaderModule.listSerialPorts();
16
+ }
17
+
18
+ export function listBaudRates(): number[] {
19
+ return NFCSerialReaderModule.listBaudRates();
20
+ }
21
+
22
+ export function disconnectNFCSerialReader(): boolean {
23
+ return NFCSerialReaderModule.disconnect();
24
+ }
25
+
26
+ const emitter = new EventEmitter(
27
+ NFCSerialReaderModule ?? NativeModulesProxy.NFCSerialReader
28
+ );
29
+
30
+ export type NFCReadEventPayload = {
31
+ cardType: "TAG" | "WORKER" | "UNKNOWN";
32
+ cardId: string;
33
+ };
34
+
35
+ export function addNFCReadListener(
36
+ listener: (event: NFCReadEventPayload) => void
37
+ ): Subscription {
38
+ return emitter.addListener<NFCReadEventPayload>("onRead", listener);
39
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ // @generated by expo-module-scripts
2
+ {
3
+ "extends": "expo-module-scripts/tsconfig.base",
4
+ "compilerOptions": {
5
+ "outDir": "./build"
6
+ },
7
+ "include": ["./src"],
8
+ "exclude": ["**/__mocks__/*", "**/__tests__/*"]
9
+ }