react-native-nfc-manager 3.13.0 → 3.13.3
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/CHANGELOG.md +98 -0
- package/README.md +6 -0
- package/android/src/main/java/community/revteltech/nfc/MifareUtil.java +3 -3
- package/android/src/main/java/community/revteltech/nfc/NfcManager.java +147 -38
- package/android/src/main/java/community/revteltech/nfc/Util.java +9 -9
- package/index.d.ts +16 -0
- package/ios/NfcManager.h +5 -0
- package/ios/NfcManager.m +76 -129
- package/ios/Util.m +55 -0
- package/ndef-lib/index.js +1 -1
- package/package.json +1 -1
- package/react-native-nfc-manager.podspec +1 -1
- package/src/NfcManagerAndroid.js +5 -2
- package/src/NfcTech/MifareClassicHandlerAndroid.js +42 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
## [3.0.2](https://github.com/whitedogg13/react-native-nfc-manager/compare/v3.0.1...v3.0.2) (2021-02-22)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **android:** allow requestTechnology resolves to tags even when tech ([8b7f862](https://github.com/whitedogg13/react-native-nfc-manager/commit/8b7f8629a8e46304f2a68d62f01e745047fe01dc))
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## [3.0.1](https://github.com/whitedogg13/react-native-nfc-manager/compare/v3.0.0...v3.0.1) (2021-02-20)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* [#371](https://github.com/whitedogg13/react-native-nfc-manager/issues/371) missing MIFARE_BLOCK_SIZE for mifareClassicHandlerAndroid ([b136419](https://github.com/whitedogg13/react-native-nfc-manager/commit/b1364197c80ab16542bbb823483a2079a896e169))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# [3.0.0](https://github.com/whitedogg13/react-native-nfc-manager/compare/v3.0.0-0...v3.0.0) (2021-02-18)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
* expose RTD_URI_PROTOCOLS ([26516a7](https://github.com/whitedogg13/react-native-nfc-manager/commit/26516a7ce8309ade21464df13a8e5c799c0e417c))
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# [3.0.0-0](https://github.com/whitedogg13/react-native-nfc-manager/compare/v2.0.0-beta.1...v3.0.0-0) (2021-02-10)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
### Bug Fixes
|
|
32
|
+
|
|
33
|
+
* disable 18092 polling (cause iOS freeze) ([64115f8](https://github.com/whitedogg13/react-native-nfc-manager/commit/64115f80f8cd93ed5ef3b01987d6c628a5a9127b))
|
|
34
|
+
* **ios:** add polling for iso18092 ([b7984a5](https://github.com/whitedogg13/react-native-nfc-manager/commit/b7984a59ea27076d7fd34a2614592f468c80f5e1))
|
|
35
|
+
* add callback type null possible ([1371533](https://github.com/whitedogg13/react-native-nfc-manager/commit/13715334ea908b89654b42eba4ec902bcc6f4229))
|
|
36
|
+
* cancelTechnology might cause exception if there's a connected tag ([af2f1f9](https://github.com/whitedogg13/react-native-nfc-manager/commit/af2f1f92bbd7bfcf8c604db48b790289c3ca4946))
|
|
37
|
+
* cancelTechnology might cause exception if there's a connected tag ([dcb26b8](https://github.com/whitedogg13/react-native-nfc-manager/commit/dcb26b85a955ce17ae633e00f6f189a895e8adcb))
|
|
38
|
+
* getNdefMessage should use the same structure for platforms ([73859fb](https://github.com/whitedogg13/react-native-nfc-manager/commit/73859fbac8939277f1e7fc2ad13ececee8c9d4c7))
|
|
39
|
+
* import NfcManager from new location ([c95cc76](https://github.com/whitedogg13/react-native-nfc-manager/commit/c95cc76a0a3b52c751c1a0f00895cf1b34b66b28))
|
|
40
|
+
* ios isSupported ([adcc966](https://github.com/whitedogg13/react-native-nfc-manager/commit/adcc966c8ed4a565c2800fabc5e5a0cad07ea376))
|
|
41
|
+
* promise won't be rejected when calling cancelTechnologyRequest in ([64c9cbd](https://github.com/whitedogg13/react-native-nfc-manager/commit/64c9cbd05e34e975fa4744727859efd08ea610bf))
|
|
42
|
+
* reject tech request promise when native iOS cancel button is pressed ([7915b98](https://github.com/whitedogg13/react-native-nfc-manager/commit/7915b98132cf5c6f86eb96dfe242b67bef32e8a7))
|
|
43
|
+
* remove getNdefMessage's parameter declaration ([6fc257e](https://github.com/whitedogg13/react-native-nfc-manager/commit/6fc257e61e1da5600a7aac44d9a8a97a7ecc988c))
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
### Features
|
|
47
|
+
|
|
48
|
+
* extract more NfcTech handlers ([0032408](https://github.com/whitedogg13/react-native-nfc-manager/commit/0032408af21cafa3f5f92c16083f914325450524))
|
|
49
|
+
* **android:** getNdefStatus ([4cc68ce](https://github.com/whitedogg13/react-native-nfc-manager/commit/4cc68ce233d81c03760b791fc2f568fe4b8415c4))
|
|
50
|
+
* **ios:** enhance didDetectTags and add queryNDEFStatus / makeReadOnly ([32dd3be](https://github.com/whitedogg13/react-native-nfc-manager/commit/32dd3be2968abbe095ae42fd12793a9a8c0725c6))
|
|
51
|
+
* invalidateSessionWithErrorIOS ([c631110](https://github.com/whitedogg13/react-native-nfc-manager/commit/c631110b6454c08821607014a28b8dffb20fe8b0))
|
|
52
|
+
* ios 13 ndef read and write ([31a3ae6](https://github.com/whitedogg13/react-native-nfc-manager/commit/31a3ae6e141e41f3f36a102d5c2bb5ce04ba78a5))
|
|
53
|
+
* requestTechnology support multi-techs ([65e8f02](https://github.com/whitedogg13/react-native-nfc-manager/commit/65e8f02b83820cb72e65c8443a607b6dca2c8fae))
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
# [2.0.0-beta.1](https://github.com/whitedogg13/react-native-nfc-manager/compare/0.0.9...v2.0.0-beta.1) (2019-07-13)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
### Bug Fixes
|
|
61
|
+
|
|
62
|
+
* call the correct method `mifareUltralightReadPages` (notice the tailing s) ([60feee8](https://github.com/whitedogg13/react-native-nfc-manager/commit/60feee88c2d20bc18af23b3abb6d8cb22fe17e16))
|
|
63
|
+
* ios crash on registerTagEvent ([e654d93](https://github.com/whitedogg13/react-native-nfc-manager/commit/e654d9359751327284d20b3bee1139c78657dcb4))
|
|
64
|
+
* MifareClassic should also support `transceive` ([dd4a902](https://github.com/whitedogg13/react-native-nfc-manager/commit/dd4a902257a402e5d6d3eae8bd43f9d37c03928b))
|
|
65
|
+
* use non-cached ndef for getNdefMessage API ([49f8541](https://github.com/whitedogg13/react-native-nfc-manager/commit/49f85415a5bc6d0218992dc6ba2b9303cee8e3ac))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### Features
|
|
69
|
+
|
|
70
|
+
* mifareultralight support ([4a53a13](https://github.com/whitedogg13/react-native-nfc-manager/commit/4a53a135c594ef340927ae053dfc142ebfd0b9b6))
|
|
71
|
+
* support `getMaxTransceiveLength` and `setTimeout` ([e759c39](https://github.com/whitedogg13/react-native-nfc-manager/commit/e759c399008e9060ae6f5fe23d7b31a61b1f8037))
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
## [0.0.9](https://github.com/whitedogg13/react-native-nfc-manager/compare/0.0.8...0.0.9) (2018-01-02)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
## [0.0.8](https://github.com/whitedogg13/react-native-nfc-manager/compare/0.0.7...0.0.8) (2017-12-09)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
## [0.0.7](https://github.com/whitedogg13/react-native-nfc-manager/compare/0.0.6...0.0.7) (2017-12-04)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
## [0.0.6](https://github.com/whitedogg13/react-native-nfc-manager/compare/0.0.3...0.0.6) (2017-11-17)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
## [0.0.3](https://github.com/whitedogg13/react-native-nfc-manager/compare/0.0.2...0.0.3) (2017-09-27)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
## 0.0.2 (2017-08-01)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
package/README.md
CHANGED
|
@@ -69,6 +69,12 @@ We have a full featured NFC utility app using this library available for downloa
|
|
|
69
69
|
|
|
70
70
|
It also open sourced in this repo: [React Native NFC ReWriter App](https://github.com/revtel/react-native-nfc-rewriter)
|
|
71
71
|
|
|
72
|
+
## Learn
|
|
73
|
+
|
|
74
|
+
We have published a React Native NFC course with [newline.co](https://www.newline.co/), check it out!
|
|
75
|
+
- Free course (1 hour) about basic NFC setup and concept [here](https://www.youtube.com/watch?v=rAS-DvNUFck)
|
|
76
|
+
- Full course (3 hours) for more (NDEF, Deep Linking, NTAG password protection, signature with UID) [here](https://www.newline.co/courses/newline-guide-to-nfcs-with-react-native)
|
|
77
|
+
|
|
72
78
|
## Usage
|
|
73
79
|
|
|
74
80
|
The simplest (and most common) use case for this library is to read `NFC` tags containing `NDEF`, which can be achieved via the following codes:
|
|
@@ -49,7 +49,7 @@ class MifareUtil {
|
|
|
49
49
|
// able of reading/writing MIFARE Classic tags. I don't know why...
|
|
50
50
|
// https://github.com/ikarus23/MifareClassicTool/issues/152
|
|
51
51
|
boolean isLenovoP2 = Build.MANUFACTURER.equals("LENOVO")
|
|
52
|
-
|
|
52
|
+
&& Build.MODEL.equals("Lenovo P2a42");
|
|
53
53
|
File device = new File("/dev/bcm2079x-i2c");
|
|
54
54
|
if (!isLenovoP2 && device.exists()) {
|
|
55
55
|
return false;
|
|
@@ -70,8 +70,8 @@ class MifareUtil {
|
|
|
70
70
|
File[] libs = libsFolder.listFiles();
|
|
71
71
|
for (File lib : libs) {
|
|
72
72
|
if (lib.isFile()
|
|
73
|
-
|
|
74
|
-
|
|
73
|
+
&& lib.getName().startsWith("libnfc")
|
|
74
|
+
&& lib.getName().contains("brcm")
|
|
75
75
|
// Add here other non NXP NFC libraries.
|
|
76
76
|
) {
|
|
77
77
|
return false;
|
|
@@ -536,6 +536,99 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
|
|
|
536
536
|
}
|
|
537
537
|
}
|
|
538
538
|
|
|
539
|
+
@ReactMethod
|
|
540
|
+
public void mifareClassicIncrementBlock(int blockIndex, int value, Callback callback) {
|
|
541
|
+
synchronized(this) {
|
|
542
|
+
if (techRequest != null) {
|
|
543
|
+
try {
|
|
544
|
+
MifareClassic mifareTag = (MifareClassic) techRequest.getTechHandle();
|
|
545
|
+
if (mifareTag == null || mifareTag.getType() == MifareClassic.TYPE_UNKNOWN) {
|
|
546
|
+
// Not a mifare card, fail
|
|
547
|
+
callback.invoke("mifareClassicIncrementBlock fail: TYPE_UNKNOWN");
|
|
548
|
+
return;
|
|
549
|
+
} else if (blockIndex >= mifareTag.getBlockCount()) {
|
|
550
|
+
// Check if in range
|
|
551
|
+
String msg = String.format("mifareClassicIncrementBlock fail: invalid block %d (max %d)", blockIndex, mifareTag.getBlockCount());
|
|
552
|
+
callback.invoke(msg);
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
mifareTag.increment(blockIndex, value);
|
|
557
|
+
|
|
558
|
+
callback.invoke(null, true);
|
|
559
|
+
} catch (TagLostException ex) {
|
|
560
|
+
callback.invoke("mifareClassicIncrementBlock fail: TAG_LOST");
|
|
561
|
+
} catch (Exception ex) {
|
|
562
|
+
callback.invoke("mifareClassicIncrementBlock fail: " + ex.toString());
|
|
563
|
+
}
|
|
564
|
+
} else {
|
|
565
|
+
callback.invoke(ERR_NO_TECH_REQ);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
@ReactMethod
|
|
571
|
+
public void mifareClassicDecrementBlock(int blockIndex, int value, Callback callback) {
|
|
572
|
+
synchronized(this) {
|
|
573
|
+
if (techRequest != null) {
|
|
574
|
+
try {
|
|
575
|
+
MifareClassic mifareTag = (MifareClassic) techRequest.getTechHandle();
|
|
576
|
+
if (mifareTag == null || mifareTag.getType() == MifareClassic.TYPE_UNKNOWN) {
|
|
577
|
+
// Not a mifare card, fail
|
|
578
|
+
callback.invoke("mifareClassicDecrementBlock fail: TYPE_UNKNOWN");
|
|
579
|
+
return;
|
|
580
|
+
} else if (blockIndex >= mifareTag.getBlockCount()) {
|
|
581
|
+
// Check if in range
|
|
582
|
+
String msg = String.format("mifareClassicDecrementBlock fail: invalid block %d (max %d)", blockIndex, mifareTag.getBlockCount());
|
|
583
|
+
callback.invoke(msg);
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
mifareTag.decrement(blockIndex, value);
|
|
588
|
+
|
|
589
|
+
callback.invoke(null, true);
|
|
590
|
+
} catch (TagLostException ex) {
|
|
591
|
+
callback.invoke("mifareClassicDecrementBlock fail: TAG_LOST");
|
|
592
|
+
} catch (Exception ex) {
|
|
593
|
+
callback.invoke("mifareClassicDecrementBlock fail: " + ex.toString());
|
|
594
|
+
}
|
|
595
|
+
} else {
|
|
596
|
+
callback.invoke(ERR_NO_TECH_REQ);
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
@ReactMethod
|
|
602
|
+
public void mifareClassicTransferBlock(int blockIndex, Callback callback) {
|
|
603
|
+
synchronized(this) {
|
|
604
|
+
if (techRequest != null) {
|
|
605
|
+
try {
|
|
606
|
+
MifareClassic mifareTag = (MifareClassic) techRequest.getTechHandle();
|
|
607
|
+
if (mifareTag == null || mifareTag.getType() == MifareClassic.TYPE_UNKNOWN) {
|
|
608
|
+
// Not a mifare card, fail
|
|
609
|
+
callback.invoke("mifareClassicTransferBlock fail: TYPE_UNKNOWN");
|
|
610
|
+
return;
|
|
611
|
+
} else if (blockIndex >= mifareTag.getBlockCount()) {
|
|
612
|
+
// Check if in range
|
|
613
|
+
String msg = String.format("mifareClassicTransferBlock fail: invalid block %d (max %d)", blockIndex, mifareTag.getBlockCount());
|
|
614
|
+
callback.invoke(msg);
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
mifareTag.transfer(blockIndex);
|
|
619
|
+
|
|
620
|
+
callback.invoke(null, true);
|
|
621
|
+
} catch (TagLostException ex) {
|
|
622
|
+
callback.invoke("mifareClassicTransferBlock fail: TAG_LOST");
|
|
623
|
+
} catch (Exception ex) {
|
|
624
|
+
callback.invoke("mifareClassicTransferBlock fail: " + ex.toString());
|
|
625
|
+
}
|
|
626
|
+
} else {
|
|
627
|
+
callback.invoke(ERR_NO_TECH_REQ);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
|
|
539
632
|
@ReactMethod
|
|
540
633
|
public void mifareUltralightReadPages(int pageOffset, Callback callback) {
|
|
541
634
|
synchronized(this) {
|
|
@@ -646,27 +739,27 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
|
|
|
646
739
|
@ReactMethod
|
|
647
740
|
public void connect(ReadableArray techs, Callback callback){
|
|
648
741
|
synchronized(this) {
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
742
|
+
try {
|
|
743
|
+
techRequest = new TagTechnologyRequest(techs.toArrayList(), callback);
|
|
744
|
+
techRequest.connect(this.tag);
|
|
745
|
+
callback.invoke(null, null);
|
|
746
|
+
return;
|
|
747
|
+
} catch (Exception ex) {
|
|
748
|
+
callback.invoke(ex.toString());
|
|
749
|
+
}
|
|
657
750
|
}
|
|
658
751
|
}
|
|
659
752
|
|
|
660
753
|
@ReactMethod
|
|
661
754
|
public void close(Callback callback){
|
|
662
755
|
synchronized(this) {
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
756
|
+
try {
|
|
757
|
+
techRequest.close();
|
|
758
|
+
callback.invoke(null, null);
|
|
759
|
+
return;
|
|
760
|
+
} catch (Exception ex) {
|
|
761
|
+
callback.invoke(ex.toString());
|
|
762
|
+
}
|
|
670
763
|
}
|
|
671
764
|
}
|
|
672
765
|
|
|
@@ -971,11 +1064,11 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
|
|
|
971
1064
|
|
|
972
1065
|
@ReactMethod
|
|
973
1066
|
private void registerTagEvent(ReadableMap options, Callback callback) {
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1067
|
+
isReaderModeEnabled = options.getBoolean("isReaderModeEnabled");
|
|
1068
|
+
readerModeFlags = options.getInt("readerModeFlags");
|
|
1069
|
+
readerModeDelay = options.getInt("readerModeDelay");
|
|
977
1070
|
|
|
978
|
-
Log.d(LOG_TAG, "
|
|
1071
|
+
Log.d(LOG_TAG, "registerTagEvent");
|
|
979
1072
|
isForegroundEnabled = true;
|
|
980
1073
|
|
|
981
1074
|
// capture all mime-based dispatch NDEF
|
|
@@ -1002,18 +1095,23 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
|
|
|
1002
1095
|
|
|
1003
1096
|
@ReactMethod
|
|
1004
1097
|
private void unregisterTagEvent(Callback callback) {
|
|
1005
|
-
Log.d(LOG_TAG, "
|
|
1006
|
-
isForegroundEnabled = false;
|
|
1007
|
-
intentFilters.clear();
|
|
1098
|
+
Log.d(LOG_TAG, "unregisterTagEvent");
|
|
1008
1099
|
if (isResumed) {
|
|
1009
1100
|
enableDisableForegroundDispatch(false);
|
|
1010
1101
|
}
|
|
1102
|
+
|
|
1103
|
+
intentFilters.clear();
|
|
1104
|
+
isForegroundEnabled = false;
|
|
1105
|
+
isReaderModeEnabled = false;
|
|
1106
|
+
readerModeFlags = 0;
|
|
1107
|
+
readerModeDelay = 0;
|
|
1108
|
+
|
|
1011
1109
|
callback.invoke();
|
|
1012
1110
|
}
|
|
1013
1111
|
|
|
1014
1112
|
@ReactMethod
|
|
1015
1113
|
private void hasTagEventRegistration(Callback callback) {
|
|
1016
|
-
Log.d(LOG_TAG, "isSessionAvailable");
|
|
1114
|
+
Log.d(LOG_TAG, "isSessionAvailable: " + isForegroundEnabled);
|
|
1017
1115
|
callback.invoke(null, isForegroundEnabled);
|
|
1018
1116
|
}
|
|
1019
1117
|
|
|
@@ -1061,25 +1159,36 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
|
|
|
1061
1159
|
}
|
|
1062
1160
|
|
|
1063
1161
|
if (enable) {
|
|
1064
|
-
Log.i(LOG_TAG, "enableReaderMode");
|
|
1162
|
+
Log.i(LOG_TAG, "enableReaderMode: " + readerModeFlags);
|
|
1065
1163
|
Bundle readerModeExtras = new Bundle();
|
|
1066
1164
|
readerModeExtras.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, readerModeDelay * 1000);
|
|
1067
1165
|
nfcAdapter.enableReaderMode(currentActivity, new NfcAdapter.ReaderCallback() {
|
|
1068
1166
|
@Override
|
|
1069
1167
|
public void onTagDiscovered(Tag tag) {
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1168
|
+
synchronized (this) {
|
|
1169
|
+
manager.tag = tag;
|
|
1170
|
+
Log.d(LOG_TAG, "readerMode onTagDiscovered");
|
|
1171
|
+
WritableMap nfcTag = null;
|
|
1172
|
+
// if the tag contains NDEF, we want to report the content
|
|
1173
|
+
if (Arrays.asList(tag.getTechList()).contains(Ndef.class.getName())) {
|
|
1174
|
+
Ndef ndef = Ndef.get(tag);
|
|
1175
|
+
nfcTag = ndef2React(ndef, new NdefMessage[] { ndef.getCachedNdefMessage() });
|
|
1176
|
+
} else {
|
|
1177
|
+
nfcTag = tag2React(tag);
|
|
1178
|
+
}
|
|
1179
|
+
|
|
1180
|
+
if (nfcTag != null) {
|
|
1181
|
+
sendEvent("NfcManagerDiscoverTag", nfcTag);
|
|
1182
|
+
if (techRequest!= null && !techRequest.isConnected()) {
|
|
1183
|
+
boolean result = techRequest.connect(tag);
|
|
1184
|
+
if (result) {
|
|
1185
|
+
techRequest.getPendingCallback().invoke(null, techRequest.getTechType());
|
|
1186
|
+
} else {
|
|
1187
|
+
// this indicates that we get a NFC tag, but none of the user required tech is matched
|
|
1188
|
+
techRequest.getPendingCallback().invoke(null, null);
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1083
1192
|
}
|
|
1084
1193
|
}
|
|
1085
1194
|
}, readerModeFlags, readerModeExtras);
|
|
@@ -1107,7 +1216,7 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
|
|
|
1107
1216
|
|
|
1108
1217
|
int flag = 0;
|
|
1109
1218
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
1110
|
-
|
|
1219
|
+
flag = PendingIntent.FLAG_MUTABLE;
|
|
1111
1220
|
}
|
|
1112
1221
|
return PendingIntent.getActivity(activity, 0, intent, flag);
|
|
1113
1222
|
}
|
|
@@ -39,9 +39,9 @@ public class Util {
|
|
|
39
39
|
// mTag.getTagService(); of the Ndef object sometimes returns null
|
|
40
40
|
// see http://issues.mroland.at/index.php?do=details&task_id=47
|
|
41
41
|
try {
|
|
42
|
-
|
|
42
|
+
json.put("canMakeReadOnly", ndef.canMakeReadOnly());
|
|
43
43
|
} catch (NullPointerException e) {
|
|
44
|
-
|
|
44
|
+
json.put("canMakeReadOnly", JSONObject.NULL);
|
|
45
45
|
}
|
|
46
46
|
} catch (JSONException e) {
|
|
47
47
|
Log.e(TAG, "Failed to convert ndef into json: " + ndef.toString(), e);
|
|
@@ -104,16 +104,16 @@ public class Util {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
public static String bytesToHex(byte[] bytes) {
|
|
107
|
-
|
|
107
|
+
char[] hexChars = new char[bytes.length * 2];
|
|
108
108
|
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
for ( int j = 0; j < bytes.length; j++ ) {
|
|
110
|
+
int v = bytes[j] & 0xFF;
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
hexChars[j * 2] = hexArray[v >>> 4];
|
|
113
|
+
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
|
114
|
+
}
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
return new String(hexChars);
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
static byte[] jsonToByteArray(JSONArray json) throws JSONException {
|
package/index.d.ts
CHANGED
|
@@ -88,6 +88,7 @@ declare module 'react-native-nfc-manager' {
|
|
|
88
88
|
|
|
89
89
|
export interface CancelTechReqOpts {
|
|
90
90
|
throwOnError?: boolean = false;
|
|
91
|
+
delayMsAndroid?: number = 1000;
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
interface NdefHandler {
|
|
@@ -122,11 +123,26 @@ declare module 'react-native-nfc-manager' {
|
|
|
122
123
|
block: ArrayLike<number>,
|
|
123
124
|
simpliArr: any[],
|
|
124
125
|
) => Promise<void>;
|
|
126
|
+
mifareClassicIncrementBlock: (
|
|
127
|
+
block: ArrayLike<number>,
|
|
128
|
+
data: number,
|
|
129
|
+
) => Promise<void>;
|
|
130
|
+
mifareClassicDecrementBlock: (
|
|
131
|
+
block: ArrayLike<number>,
|
|
132
|
+
data: number,
|
|
133
|
+
) => Promise<void>;
|
|
134
|
+
mifareClassicTransferBlock: (
|
|
135
|
+
block: ArrayLike<number>,
|
|
136
|
+
) => Promise<void>;
|
|
125
137
|
mifareClassicGetSectorCount: () => Promise<number>;
|
|
126
138
|
mifareClassicAuthenticateA: (
|
|
127
139
|
sector: number,
|
|
128
140
|
keys: number[],
|
|
129
141
|
) => Promise<void>;
|
|
142
|
+
mifareClassicAuthenticateB: (
|
|
143
|
+
sector: number,
|
|
144
|
+
keys: number[],
|
|
145
|
+
) => Promise<void>;
|
|
130
146
|
}
|
|
131
147
|
|
|
132
148
|
interface MifareUltralightHandlerAndroid {
|
package/ios/NfcManager.h
CHANGED
|
@@ -30,3 +30,8 @@
|
|
|
30
30
|
#endif
|
|
31
31
|
|
|
32
32
|
@end
|
|
33
|
+
|
|
34
|
+
extern NSString* _Nonnull getHexString(NSData * _Nonnull);
|
|
35
|
+
extern NSString* _Nonnull getErrorMessage(NSError * _Nonnull);
|
|
36
|
+
extern NSData * _Nonnull arrayToData(NSArray * _Nonnull);
|
|
37
|
+
extern NSArray * _Nonnull dataToArray(NSData * _Nonnull);
|
package/ios/NfcManager.m
CHANGED
|
@@ -4,29 +4,6 @@
|
|
|
4
4
|
#import "React/RCTEventDispatcher.h"
|
|
5
5
|
#import "React/RCTLog.h"
|
|
6
6
|
|
|
7
|
-
NSString* getHexString(NSData *data) {
|
|
8
|
-
NSUInteger capacity = data.length * 2;
|
|
9
|
-
NSMutableString *sbuf = [NSMutableString stringWithCapacity:capacity];
|
|
10
|
-
const unsigned char *buf = data.bytes;
|
|
11
|
-
NSInteger i;
|
|
12
|
-
for (i=0; i<data.length; ++i) {
|
|
13
|
-
[sbuf appendFormat:@"%02lX", (unsigned long)buf[i]];
|
|
14
|
-
}
|
|
15
|
-
return sbuf;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
NSString* getErrorMessage(NSError *error) {
|
|
19
|
-
NSDictionary *userInfo = [error userInfo];
|
|
20
|
-
NSError *underlyingError = [userInfo objectForKey:NSUnderlyingErrorKey];
|
|
21
|
-
if (underlyingError != nil) {
|
|
22
|
-
return [NSString stringWithFormat:@"%@:%ld,%@:%ld",
|
|
23
|
-
[error domain], (long)[error code],
|
|
24
|
-
[underlyingError domain], (long)[underlyingError code]];
|
|
25
|
-
}
|
|
26
|
-
return [NSString stringWithFormat:@"%@:%ld",
|
|
27
|
-
[error domain], (long)[error code]];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
7
|
@implementation NfcManager {
|
|
31
8
|
NSDictionary *nfcTechTypes;
|
|
32
9
|
NSArray *techRequestTypes;
|
|
@@ -37,7 +14,6 @@ RCT_EXPORT_MODULE()
|
|
|
37
14
|
|
|
38
15
|
@synthesize session;
|
|
39
16
|
@synthesize tagSession;
|
|
40
|
-
@synthesize bridge = _bridge;
|
|
41
17
|
|
|
42
18
|
static NSString *const kBgNfcTagNotification = @"RNBgNfcTagNotification";
|
|
43
19
|
NSArray * bgNdefRecords = nil;
|
|
@@ -112,38 +88,12 @@ continueUserActivity:(NSUserActivity *)userActivity
|
|
|
112
88
|
];
|
|
113
89
|
}
|
|
114
90
|
|
|
115
|
-
- (NSData *)arrayToData: (NSArray *) array
|
|
116
|
-
{
|
|
117
|
-
Byte bytes[[array count]];
|
|
118
|
-
for (int i = 0; i < [array count]; i++) {
|
|
119
|
-
bytes[i] = [[array objectAtIndex:i] integerValue];
|
|
120
|
-
}
|
|
121
|
-
NSData *payload = [[NSData alloc] initWithBytes:bytes length:[array count]];
|
|
122
|
-
return payload;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
+ (NSArray *)dataToArray:(NSData *)data
|
|
126
|
-
{
|
|
127
|
-
const unsigned char *dataBuffer = data ? (const unsigned char *)[data bytes] : NULL;
|
|
128
|
-
|
|
129
|
-
if (!dataBuffer)
|
|
130
|
-
return @[];
|
|
131
|
-
|
|
132
|
-
NSUInteger dataLength = [data length];
|
|
133
|
-
NSMutableArray *array = [NSMutableArray arrayWithCapacity:dataLength];
|
|
134
|
-
|
|
135
|
-
for (int i = 0; i < dataLength; ++i)
|
|
136
|
-
[array addObject:[NSNumber numberWithInteger:dataBuffer[i]]];
|
|
137
|
-
|
|
138
|
-
return array;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
91
|
+ (NSDictionary*)convertNdefRecord:(NFCNDEFPayload *) record
|
|
142
92
|
{
|
|
143
93
|
return @{
|
|
144
|
-
@"id":
|
|
145
|
-
@"payload":
|
|
146
|
-
@"type":
|
|
94
|
+
@"id": dataToArray([record identifier]),
|
|
95
|
+
@"payload": dataToArray([record payload]),
|
|
96
|
+
@"type": dataToArray([record type]),
|
|
147
97
|
@"tnf": [NSNumber numberWithInt:[record typeNameFormat]]
|
|
148
98
|
};
|
|
149
99
|
}
|
|
@@ -179,13 +129,13 @@ continueUserActivity:(NSUserActivity *)userActivity
|
|
|
179
129
|
id<NFCISO7816Tag> iso7816Tag = [tag asNFCISO7816Tag];
|
|
180
130
|
[tagInfo setObject:getHexString(iso7816Tag.identifier) forKey:@"id"];
|
|
181
131
|
[tagInfo setObject:iso7816Tag.initialSelectedAID forKey:@"initialSelectedAID"];
|
|
182
|
-
[tagInfo setObject:
|
|
183
|
-
[tagInfo setObject:
|
|
132
|
+
[tagInfo setObject:dataToArray(iso7816Tag.historicalBytes) forKey:@"historicalBytes"];
|
|
133
|
+
[tagInfo setObject:dataToArray(iso7816Tag.applicationData) forKey:@"applicationData"];
|
|
184
134
|
} else if (tag.type == NFCTagTypeISO15693) {
|
|
185
135
|
id<NFCISO15693Tag> iso15693Tag = [tag asNFCISO15693Tag];
|
|
186
136
|
[tagInfo setObject:getHexString(iso15693Tag.identifier) forKey:@"id"];
|
|
187
137
|
[tagInfo setObject:[NSNumber numberWithUnsignedInteger:iso15693Tag.icManufacturerCode] forKey:@"icManufacturerCode"];
|
|
188
|
-
[tagInfo setObject:
|
|
138
|
+
[tagInfo setObject:dataToArray(iso15693Tag.icSerialNumber) forKey:@"icSerialNumber"];
|
|
189
139
|
} else if (tag.type == NFCTagTypeFeliCa) {
|
|
190
140
|
id<NFCFeliCaTag> felicaTag = [tag asNFCFeliCaTag];
|
|
191
141
|
[tagInfo setObject:getHexString(felicaTag.currentIDm) forKey:@"idm"];
|
|
@@ -196,18 +146,17 @@ continueUserActivity:(NSUserActivity *)userActivity
|
|
|
196
146
|
return tagInfo;
|
|
197
147
|
}
|
|
198
148
|
|
|
199
|
-
- (id<NFCNDEFTag>)getNDEFTagHandle:(id<NFCTag>)tag
|
|
149
|
+
- (id<NFCNDEFTag>)getNDEFTagHandle:(id<NFCTag>)tag
|
|
150
|
+
API_AVAILABLE(ios(13.0)) {
|
|
200
151
|
// all following types inherite from NFCNDEFTag
|
|
201
|
-
if (
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
return [tag asNFCFeliCaTag];
|
|
210
|
-
}
|
|
152
|
+
if (tag.type == NFCTagTypeMiFare) {
|
|
153
|
+
return [tag asNFCMiFareTag];
|
|
154
|
+
} else if (tag.type == NFCTagTypeISO7816Compatible) {
|
|
155
|
+
return [tag asNFCISO7816Tag];
|
|
156
|
+
} else if (tag.type == NFCTagTypeISO15693) {
|
|
157
|
+
return [tag asNFCISO15693Tag];
|
|
158
|
+
} else if (tag.type == NFCTagTypeFeliCa) {
|
|
159
|
+
return [tag asNFCFeliCaTag];
|
|
211
160
|
}
|
|
212
161
|
|
|
213
162
|
return nil;
|
|
@@ -235,31 +184,29 @@ continueUserActivity:(NSUserActivity *)userActivity
|
|
|
235
184
|
}
|
|
236
185
|
|
|
237
186
|
- (void)tagReaderSession:(NFCTagReaderSession *)session didDetectTags:(NSArray<__kindof id<NFCTag>> *)tags
|
|
238
|
-
{
|
|
187
|
+
API_AVAILABLE(ios(13.0)) {
|
|
239
188
|
NSLog(@"NFCTag didDetectTags");
|
|
240
|
-
if (
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
189
|
+
if (techRequestCallback != nil) {
|
|
190
|
+
for (id<NFCTag> tag in tags) {
|
|
191
|
+
NSString * tagType = [self getRNTechName:tag];
|
|
192
|
+
|
|
193
|
+
for (NSString* requestType in techRequestTypes) {
|
|
194
|
+
// here we treat Ndef is a special case, because all specific tech types
|
|
195
|
+
// inherites from NFCNDEFTag, so we simply allow it to connect
|
|
196
|
+
if ([tagType isEqualToString:requestType] || [requestType isEqualToString:@"Ndef"]) {
|
|
197
|
+
RCTResponseSenderBlock pendingCallback = techRequestCallback;
|
|
198
|
+
techRequestCallback = nil;
|
|
199
|
+
|
|
200
|
+
[tagSession connectToTag:tag
|
|
201
|
+
completionHandler:^(NSError *error) {
|
|
202
|
+
if (error != nil) {
|
|
203
|
+
pendingCallback(@[getErrorMessage(error)]);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
pendingCallback(@[[NSNull null], requestType]);
|
|
208
|
+
}];
|
|
209
|
+
return;
|
|
263
210
|
}
|
|
264
211
|
}
|
|
265
212
|
}
|
|
@@ -267,7 +214,7 @@ continueUserActivity:(NSUserActivity *)userActivity
|
|
|
267
214
|
}
|
|
268
215
|
|
|
269
216
|
- (void)tagReaderSession:(NFCTagReaderSession *)session didInvalidateWithError:(NSError *)error
|
|
270
|
-
{
|
|
217
|
+
API_AVAILABLE(ios(13.0)) {
|
|
271
218
|
NSLog(@"NFCTag didInvalidateWithError");
|
|
272
219
|
if (techRequestCallback) {
|
|
273
220
|
techRequestCallback(@[getErrorMessage(error)]);
|
|
@@ -280,7 +227,7 @@ continueUserActivity:(NSUserActivity *)userActivity
|
|
|
280
227
|
}
|
|
281
228
|
|
|
282
229
|
- (void)tagReaderSessionDidBecomeActive:(NFCTagReaderSession *)session
|
|
283
|
-
{
|
|
230
|
+
API_AVAILABLE(ios(13.0)) {
|
|
284
231
|
NSLog(@"NFCTag didBecomeActive");
|
|
285
232
|
}
|
|
286
233
|
|
|
@@ -499,7 +446,7 @@ RCT_EXPORT_METHOD(writeNdefMessage:(NSArray*)bytes callback:(nonnull RCTResponse
|
|
|
499
446
|
}
|
|
500
447
|
|
|
501
448
|
if (ndefTag) {
|
|
502
|
-
NSData *data =
|
|
449
|
+
NSData *data = arrayToData(bytes);
|
|
503
450
|
NFCNDEFMessage *ndefMsg = [NFCNDEFMessage ndefMessageWithData:data];
|
|
504
451
|
if (!ndefMsg) {
|
|
505
452
|
callback(@[@"invalid ndef msg"]);
|
|
@@ -568,8 +515,8 @@ RCT_EXPORT_METHOD(queryNDEFStatus:(nonnull RCTResponseSenderBlock)callback)
|
|
|
568
515
|
} else {
|
|
569
516
|
callback(@[[NSNull null],
|
|
570
517
|
@{
|
|
571
|
-
@"status": [[NSNumber alloc] initWithInt:status],
|
|
572
|
-
@"capacity": [[NSNumber alloc] initWithInt:capacity]
|
|
518
|
+
@"status": [[NSNumber alloc] initWithInt:(int)status],
|
|
519
|
+
@"capacity": [[NSNumber alloc] initWithInt:(int)capacity]
|
|
573
520
|
}
|
|
574
521
|
]);
|
|
575
522
|
}
|
|
@@ -591,7 +538,7 @@ RCT_EXPORT_METHOD(sendMifareCommand:(NSArray *)bytes callback: (nonnull RCTRespo
|
|
|
591
538
|
if (tagSession != nil) {
|
|
592
539
|
if (tagSession.connectedTag) {
|
|
593
540
|
id<NFCMiFareTag> mifareTag = [tagSession.connectedTag asNFCMiFareTag];
|
|
594
|
-
NSData *data =
|
|
541
|
+
NSData *data = arrayToData(bytes);
|
|
595
542
|
NSLog(@"input bytes: %@", getHexString(data));
|
|
596
543
|
if (mifareTag) {
|
|
597
544
|
[mifareTag sendMiFareCommand:data
|
|
@@ -599,7 +546,7 @@ RCT_EXPORT_METHOD(sendMifareCommand:(NSArray *)bytes callback: (nonnull RCTRespo
|
|
|
599
546
|
if (error) {
|
|
600
547
|
callback(@[getErrorMessage(error), [NSNull null]]);
|
|
601
548
|
} else {
|
|
602
|
-
callback(@[[NSNull null],
|
|
549
|
+
callback(@[[NSNull null], dataToArray(response)]);
|
|
603
550
|
}
|
|
604
551
|
}];
|
|
605
552
|
return;
|
|
@@ -622,7 +569,7 @@ RCT_EXPORT_METHOD(sendFelicaCommand:(NSArray *)bytes callback: (nonnull RCTRespo
|
|
|
622
569
|
if (tagSession != nil) {
|
|
623
570
|
if (tagSession.connectedTag) {
|
|
624
571
|
id<NFCFeliCaTag> felicaTag = [tagSession.connectedTag asNFCFeliCaTag];
|
|
625
|
-
NSData *data =
|
|
572
|
+
NSData *data = arrayToData(bytes);
|
|
626
573
|
NSLog(@"input bytes: %@", getHexString(data));
|
|
627
574
|
if (felicaTag) {
|
|
628
575
|
[felicaTag sendFeliCaCommandPacket:data
|
|
@@ -630,7 +577,7 @@ RCT_EXPORT_METHOD(sendFelicaCommand:(NSArray *)bytes callback: (nonnull RCTRespo
|
|
|
630
577
|
if (error) {
|
|
631
578
|
callback(@[getErrorMessage(error), [NSNull null]]);
|
|
632
579
|
} else {
|
|
633
|
-
callback(@[[NSNull null],
|
|
580
|
+
callback(@[[NSNull null], dataToArray(response)]);
|
|
634
581
|
}
|
|
635
582
|
}];
|
|
636
583
|
return;
|
|
@@ -653,14 +600,14 @@ RCT_EXPORT_METHOD(sendCommandAPDUBytes:(NSArray *)bytes callback: (nonnull RCTRe
|
|
|
653
600
|
if (tagSession != nil) {
|
|
654
601
|
if (tagSession.connectedTag) {
|
|
655
602
|
id<NFCISO7816Tag> iso7816Tag = [tagSession.connectedTag asNFCISO7816Tag];
|
|
656
|
-
NSData *data =
|
|
603
|
+
NSData *data = arrayToData(bytes);
|
|
657
604
|
NFCISO7816APDU *apdu = [[NFCISO7816APDU alloc] initWithData:data];
|
|
658
605
|
if (iso7816Tag) {
|
|
659
606
|
[iso7816Tag sendCommandAPDU:apdu completionHandler:^(NSData* response, uint8_t sw1, uint8_t sw2, NSError* error) {
|
|
660
607
|
if (error) {
|
|
661
608
|
callback(@[getErrorMessage(error), [NSNull null]]);
|
|
662
609
|
} else {
|
|
663
|
-
callback(@[[NSNull null],
|
|
610
|
+
callback(@[[NSNull null], dataToArray(response), [NSNumber numberWithInt:sw1], [NSNumber numberWithInt:sw2]]);
|
|
664
611
|
}
|
|
665
612
|
}];
|
|
666
613
|
return;
|
|
@@ -688,7 +635,7 @@ RCT_EXPORT_METHOD(sendCommandAPDU:(NSDictionary *)apduData callback: (nonnull RC
|
|
|
688
635
|
NSNumber *p1 = [apduData objectForKey:@"p1"];
|
|
689
636
|
NSNumber *p2 = [apduData objectForKey:@"p2"];
|
|
690
637
|
NSArray *dataArray = [apduData objectForKey:@"data"];
|
|
691
|
-
NSData *data =
|
|
638
|
+
NSData *data = arrayToData(dataArray);
|
|
692
639
|
NSNumber *le = [apduData objectForKey:@"le"];
|
|
693
640
|
|
|
694
641
|
/*
|
|
@@ -701,7 +648,7 @@ RCT_EXPORT_METHOD(sendCommandAPDU:(NSDictionary *)apduData callback: (nonnull RC
|
|
|
701
648
|
if (error) {
|
|
702
649
|
callback(@[getErrorMessage(error), [NSNull null]]);
|
|
703
650
|
} else {
|
|
704
|
-
callback(@[[NSNull null],
|
|
651
|
+
callback(@[[NSNull null], dataToArray(response), [NSNumber numberWithInt:sw1], [NSNumber numberWithInt:sw2]]);
|
|
705
652
|
}
|
|
706
653
|
}];
|
|
707
654
|
return;
|
|
@@ -758,7 +705,7 @@ RCT_EXPORT_METHOD(isTagSessionAvailable:(nonnull RCTResponseSenderBlock)callback
|
|
|
758
705
|
// ---------------------------
|
|
759
706
|
RCT_EXPORT_METHOD(iso15693_getSystemInfo:(nonnull NSNumber *)flags callback:(nonnull RCTResponseSenderBlock)callback)
|
|
760
707
|
{
|
|
761
|
-
if (@available(iOS
|
|
708
|
+
if (@available(iOS 14.0, *)) {
|
|
762
709
|
if (!tagSession || !tagSession.connectedTag) {
|
|
763
710
|
callback(@[@"Not connected", [NSNull null]]);
|
|
764
711
|
return;
|
|
@@ -794,7 +741,7 @@ RCT_EXPORT_METHOD(iso15693_getSystemInfo:(nonnull NSNumber *)flags callback:(non
|
|
|
794
741
|
|
|
795
742
|
RCT_EXPORT_METHOD(iso15693_readSingleBlock:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
796
743
|
{
|
|
797
|
-
if (@available(iOS
|
|
744
|
+
if (@available(iOS 14.0, *)) {
|
|
798
745
|
if (!tagSession || !tagSession.connectedTag) {
|
|
799
746
|
callback(@[@"Not connected", [NSNull null]]);
|
|
800
747
|
return;
|
|
@@ -817,7 +764,7 @@ RCT_EXPORT_METHOD(iso15693_readSingleBlock:(NSDictionary *)options callback:(non
|
|
|
817
764
|
return;
|
|
818
765
|
}
|
|
819
766
|
|
|
820
|
-
callback(@[[NSNull null],
|
|
767
|
+
callback(@[[NSNull null], dataToArray(resp)]);
|
|
821
768
|
}];
|
|
822
769
|
} else {
|
|
823
770
|
callback(@[@"Not support in this device", [NSNull null]]);
|
|
@@ -826,7 +773,7 @@ RCT_EXPORT_METHOD(iso15693_readSingleBlock:(NSDictionary *)options callback:(non
|
|
|
826
773
|
|
|
827
774
|
RCT_EXPORT_METHOD(iso15693_readMultipleBlocks:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
828
775
|
{
|
|
829
|
-
if (@available(iOS
|
|
776
|
+
if (@available(iOS 14.0, *)) {
|
|
830
777
|
if (!tagSession || !tagSession.connectedTag) {
|
|
831
778
|
callback(@[@"Not connected", [NSNull null]]);
|
|
832
779
|
return;
|
|
@@ -853,7 +800,7 @@ RCT_EXPORT_METHOD(iso15693_readMultipleBlocks:(NSDictionary *)options callback:(
|
|
|
853
800
|
}
|
|
854
801
|
NSMutableArray *blocks = [NSMutableArray arrayWithCapacity:[dataBlocks count]];
|
|
855
802
|
[dataBlocks enumerateObjectsUsingBlock:^(NSData *blockData, NSUInteger idx, BOOL *stop) {
|
|
856
|
-
[blocks addObject:
|
|
803
|
+
[blocks addObject:dataToArray(blockData)];
|
|
857
804
|
}];
|
|
858
805
|
callback(@[[NSNull null], blocks]);
|
|
859
806
|
}];
|
|
@@ -864,7 +811,7 @@ RCT_EXPORT_METHOD(iso15693_readMultipleBlocks:(NSDictionary *)options callback:(
|
|
|
864
811
|
|
|
865
812
|
RCT_EXPORT_METHOD(iso15693_writeSingleBlock:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
866
813
|
{
|
|
867
|
-
if (@available(iOS
|
|
814
|
+
if (@available(iOS 14.0, *)) {
|
|
868
815
|
if (!tagSession || !tagSession.connectedTag) {
|
|
869
816
|
callback(@[@"Not connected", [NSNull null]]);
|
|
870
817
|
return;
|
|
@@ -878,7 +825,7 @@ RCT_EXPORT_METHOD(iso15693_writeSingleBlock:(NSDictionary *)options callback:(no
|
|
|
878
825
|
|
|
879
826
|
RequestFlag flags = [[options objectForKey:@"flags"] unsignedIntValue];
|
|
880
827
|
uint8_t blockNumber = [[options objectForKey:@"blockNumber"] unsignedIntValue];
|
|
881
|
-
NSData *dataBlock =
|
|
828
|
+
NSData *dataBlock = arrayToData([options mutableArrayValueForKey:@"dataBlock"]);
|
|
882
829
|
|
|
883
830
|
[tag writeSingleBlockWithRequestFlags:flags
|
|
884
831
|
blockNumber:blockNumber
|
|
@@ -898,7 +845,7 @@ RCT_EXPORT_METHOD(iso15693_writeSingleBlock:(NSDictionary *)options callback:(no
|
|
|
898
845
|
|
|
899
846
|
RCT_EXPORT_METHOD(iso15693_lockBlock:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
900
847
|
{
|
|
901
|
-
if (@available(iOS
|
|
848
|
+
if (@available(iOS 14.0, *)) {
|
|
902
849
|
if (!tagSession || !tagSession.connectedTag) {
|
|
903
850
|
callback(@[@"Not connected", [NSNull null]]);
|
|
904
851
|
return;
|
|
@@ -930,7 +877,7 @@ RCT_EXPORT_METHOD(iso15693_lockBlock:(NSDictionary *)options callback:(nonnull R
|
|
|
930
877
|
|
|
931
878
|
RCT_EXPORT_METHOD(iso15693_writeAFI:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
932
879
|
{
|
|
933
|
-
if (@available(iOS
|
|
880
|
+
if (@available(iOS 14.0, *)) {
|
|
934
881
|
if (!tagSession || !tagSession.connectedTag) {
|
|
935
882
|
callback(@[@"Not connected", [NSNull null]]);
|
|
936
883
|
return;
|
|
@@ -962,7 +909,7 @@ RCT_EXPORT_METHOD(iso15693_writeAFI:(NSDictionary *)options callback:(nonnull RC
|
|
|
962
909
|
|
|
963
910
|
RCT_EXPORT_METHOD(iso15693_lockAFI:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
964
911
|
{
|
|
965
|
-
if (@available(iOS
|
|
912
|
+
if (@available(iOS 14.0, *)) {
|
|
966
913
|
if (!tagSession || !tagSession.connectedTag) {
|
|
967
914
|
callback(@[@"Not connected", [NSNull null]]);
|
|
968
915
|
return;
|
|
@@ -992,7 +939,7 @@ RCT_EXPORT_METHOD(iso15693_lockAFI:(NSDictionary *)options callback:(nonnull RCT
|
|
|
992
939
|
|
|
993
940
|
RCT_EXPORT_METHOD(iso15693_writeDSFID:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
994
941
|
{
|
|
995
|
-
if (@available(iOS
|
|
942
|
+
if (@available(iOS 14.0, *)) {
|
|
996
943
|
if (!tagSession || !tagSession.connectedTag) {
|
|
997
944
|
callback(@[@"Not connected", [NSNull null]]);
|
|
998
945
|
return;
|
|
@@ -1024,7 +971,7 @@ RCT_EXPORT_METHOD(iso15693_writeDSFID:(NSDictionary *)options callback:(nonnull
|
|
|
1024
971
|
|
|
1025
972
|
RCT_EXPORT_METHOD(iso15693_lockDSFID:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
1026
973
|
{
|
|
1027
|
-
if (@available(iOS
|
|
974
|
+
if (@available(iOS 14.0, *)) {
|
|
1028
975
|
if (!tagSession || !tagSession.connectedTag) {
|
|
1029
976
|
callback(@[@"Not connected", [NSNull null]]);
|
|
1030
977
|
return;
|
|
@@ -1055,7 +1002,7 @@ RCT_EXPORT_METHOD(iso15693_lockDSFID:(NSDictionary *)options callback:(nonnull R
|
|
|
1055
1002
|
|
|
1056
1003
|
RCT_EXPORT_METHOD(iso15693_resetToReady:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
1057
1004
|
{
|
|
1058
|
-
if (@available(iOS
|
|
1005
|
+
if (@available(iOS 14.0, *)) {
|
|
1059
1006
|
if (!tagSession || !tagSession.connectedTag) {
|
|
1060
1007
|
callback(@[@"Not connected", [NSNull null]]);
|
|
1061
1008
|
return;
|
|
@@ -1085,7 +1032,7 @@ RCT_EXPORT_METHOD(iso15693_resetToReady:(NSDictionary *)options callback:(nonnul
|
|
|
1085
1032
|
|
|
1086
1033
|
RCT_EXPORT_METHOD(iso15693_select:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
1087
1034
|
{
|
|
1088
|
-
if (@available(iOS
|
|
1035
|
+
if (@available(iOS 14.0, *)) {
|
|
1089
1036
|
if (!tagSession || !tagSession.connectedTag) {
|
|
1090
1037
|
callback(@[@"Not connected", [NSNull null]]);
|
|
1091
1038
|
return;
|
|
@@ -1115,7 +1062,7 @@ RCT_EXPORT_METHOD(iso15693_select:(NSDictionary *)options callback:(nonnull RCTR
|
|
|
1115
1062
|
|
|
1116
1063
|
RCT_EXPORT_METHOD(iso15693_stayQuiet:(nonnull RCTResponseSenderBlock)callback)
|
|
1117
1064
|
{
|
|
1118
|
-
if (@available(iOS
|
|
1065
|
+
if (@available(iOS 14.0, *)) {
|
|
1119
1066
|
if (!tagSession || !tagSession.connectedTag) {
|
|
1120
1067
|
callback(@[@"Not connected", [NSNull null]]);
|
|
1121
1068
|
return;
|
|
@@ -1142,7 +1089,7 @@ RCT_EXPORT_METHOD(iso15693_stayQuiet:(nonnull RCTResponseSenderBlock)callback)
|
|
|
1142
1089
|
|
|
1143
1090
|
RCT_EXPORT_METHOD(iso15693_customCommand:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
1144
1091
|
{
|
|
1145
|
-
if (@available(iOS
|
|
1092
|
+
if (@available(iOS 14.0, *)) {
|
|
1146
1093
|
if (!tagSession || !tagSession.connectedTag) {
|
|
1147
1094
|
callback(@[@"Not connected", [NSNull null]]);
|
|
1148
1095
|
return;
|
|
@@ -1156,7 +1103,7 @@ RCT_EXPORT_METHOD(iso15693_customCommand:(NSDictionary *)options callback:(nonnu
|
|
|
1156
1103
|
|
|
1157
1104
|
RequestFlag flags = [[options objectForKey:@"flags"] unsignedIntValue];
|
|
1158
1105
|
NSInteger customCommandCode = [[options objectForKey:@"customCommandCode"] integerValue];
|
|
1159
|
-
NSData *customRequestParameters =
|
|
1106
|
+
NSData *customRequestParameters = arrayToData([options mutableArrayValueForKey:@"customRequestParameters"]);
|
|
1160
1107
|
|
|
1161
1108
|
[tag customCommandWithRequestFlag:flags
|
|
1162
1109
|
customCommandCode: customCommandCode
|
|
@@ -1167,7 +1114,7 @@ RCT_EXPORT_METHOD(iso15693_customCommand:(NSDictionary *)options callback:(nonnu
|
|
|
1167
1114
|
return;
|
|
1168
1115
|
}
|
|
1169
1116
|
|
|
1170
|
-
callback(@[[NSNull null],
|
|
1117
|
+
callback(@[[NSNull null], dataToArray(resp)]);
|
|
1171
1118
|
}];
|
|
1172
1119
|
} else {
|
|
1173
1120
|
callback(@[@"Not support in this device", [NSNull null]]);
|
|
@@ -1190,7 +1137,7 @@ RCT_EXPORT_METHOD(iso15693_sendRequest:(NSDictionary *)options callback:(nonnull
|
|
|
1190
1137
|
|
|
1191
1138
|
NSInteger flags = [[options objectForKey:@"flags"] integerValue];
|
|
1192
1139
|
NSInteger commandCode = [[options objectForKey:@"commandCode"] integerValue];
|
|
1193
|
-
NSData *data =
|
|
1140
|
+
NSData *data = arrayToData([options mutableArrayValueForKey:@"data"]);
|
|
1194
1141
|
|
|
1195
1142
|
[tag sendRequestWithFlag:flags
|
|
1196
1143
|
commandCode:commandCode
|
|
@@ -1200,7 +1147,7 @@ RCT_EXPORT_METHOD(iso15693_sendRequest:(NSDictionary *)options callback:(nonnull
|
|
|
1200
1147
|
callback(@[getErrorMessage(error), [NSNull null]]);
|
|
1201
1148
|
return;
|
|
1202
1149
|
}
|
|
1203
|
-
callback(@[[NSNull null], [NSNumber numberWithLong:responseFlag],
|
|
1150
|
+
callback(@[[NSNull null], [NSNumber numberWithLong:responseFlag], dataToArray(resp)]);
|
|
1204
1151
|
}];
|
|
1205
1152
|
} else {
|
|
1206
1153
|
callback(@[@"Not support in this device", [NSNull null]]);
|
|
@@ -1209,7 +1156,7 @@ RCT_EXPORT_METHOD(iso15693_sendRequest:(NSDictionary *)options callback:(nonnull
|
|
|
1209
1156
|
|
|
1210
1157
|
RCT_EXPORT_METHOD(iso15693_extendedReadSingleBlock:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
1211
1158
|
{
|
|
1212
|
-
if (@available(iOS
|
|
1159
|
+
if (@available(iOS 14.0, *)) {
|
|
1213
1160
|
if (!tagSession || !tagSession.connectedTag) {
|
|
1214
1161
|
callback(@[@"Not connected", [NSNull null]]);
|
|
1215
1162
|
return;
|
|
@@ -1232,7 +1179,7 @@ RCT_EXPORT_METHOD(iso15693_extendedReadSingleBlock:(NSDictionary *)options callb
|
|
|
1232
1179
|
return;
|
|
1233
1180
|
}
|
|
1234
1181
|
|
|
1235
|
-
callback(@[[NSNull null],
|
|
1182
|
+
callback(@[[NSNull null], dataToArray(resp)]);
|
|
1236
1183
|
}];
|
|
1237
1184
|
} else {
|
|
1238
1185
|
callback(@[@"Not support in this device", [NSNull null]]);
|
|
@@ -1241,7 +1188,7 @@ RCT_EXPORT_METHOD(iso15693_extendedReadSingleBlock:(NSDictionary *)options callb
|
|
|
1241
1188
|
|
|
1242
1189
|
RCT_EXPORT_METHOD(iso15693_extendedWriteSingleBlock:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
1243
1190
|
{
|
|
1244
|
-
if (@available(iOS
|
|
1191
|
+
if (@available(iOS 14.0, *)) {
|
|
1245
1192
|
if (!tagSession || !tagSession.connectedTag) {
|
|
1246
1193
|
callback(@[@"Not connected", [NSNull null]]);
|
|
1247
1194
|
return;
|
|
@@ -1255,7 +1202,7 @@ RCT_EXPORT_METHOD(iso15693_extendedWriteSingleBlock:(NSDictionary *)options call
|
|
|
1255
1202
|
|
|
1256
1203
|
RequestFlag flags = [[options objectForKey:@"flags"] unsignedIntValue];
|
|
1257
1204
|
uint16_t blockNumber = [[options objectForKey:@"blockNumber"] unsignedIntValue];
|
|
1258
|
-
NSData *dataBlock =
|
|
1205
|
+
NSData *dataBlock = arrayToData([options mutableArrayValueForKey:@"dataBlock"]);
|
|
1259
1206
|
|
|
1260
1207
|
[tag extendedWriteSingleBlockWithRequestFlags:flags
|
|
1261
1208
|
blockNumber:blockNumber
|
|
@@ -1275,7 +1222,7 @@ RCT_EXPORT_METHOD(iso15693_extendedWriteSingleBlock:(NSDictionary *)options call
|
|
|
1275
1222
|
|
|
1276
1223
|
RCT_EXPORT_METHOD(iso15693_extendedLockBlock:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
1277
1224
|
{
|
|
1278
|
-
if (@available(iOS
|
|
1225
|
+
if (@available(iOS 14.0, *)) {
|
|
1279
1226
|
if (!tagSession || !tagSession.connectedTag) {
|
|
1280
1227
|
callback(@[@"Not connected", [NSNull null]]);
|
|
1281
1228
|
return;
|
package/ios/Util.m
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Util.m
|
|
3
|
+
// react-native-nfc-manager
|
|
4
|
+
//
|
|
5
|
+
// Created by Richie Hsieh on 2022/1/27.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
#import <Foundation/Foundation.h>
|
|
9
|
+
|
|
10
|
+
NSString* getHexString(NSData *data) {
|
|
11
|
+
NSUInteger capacity = data.length * 2;
|
|
12
|
+
NSMutableString *sbuf = [NSMutableString stringWithCapacity:capacity];
|
|
13
|
+
const unsigned char *buf = data.bytes;
|
|
14
|
+
NSInteger i;
|
|
15
|
+
for (i=0; i<data.length; ++i) {
|
|
16
|
+
[sbuf appendFormat:@"%02lX", (unsigned long)buf[i]];
|
|
17
|
+
}
|
|
18
|
+
return sbuf;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
NSString* getErrorMessage(NSError *error) {
|
|
22
|
+
NSDictionary *userInfo = [error userInfo];
|
|
23
|
+
NSError *underlyingError = [userInfo objectForKey:NSUnderlyingErrorKey];
|
|
24
|
+
if (underlyingError != nil) {
|
|
25
|
+
return [NSString stringWithFormat:@"%@:%ld,%@:%ld",
|
|
26
|
+
[error domain], (long)[error code],
|
|
27
|
+
[underlyingError domain], (long)[underlyingError code]];
|
|
28
|
+
}
|
|
29
|
+
return [NSString stringWithFormat:@"%@:%ld",
|
|
30
|
+
[error domain], (long)[error code]];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
NSData * arrayToData(NSArray *array) {
|
|
34
|
+
Byte bytes[[array count]];
|
|
35
|
+
for (int i = 0; i < [array count]; i++) {
|
|
36
|
+
bytes[i] = [[array objectAtIndex:i] integerValue];
|
|
37
|
+
}
|
|
38
|
+
NSData *payload = [[NSData alloc] initWithBytes:bytes length:[array count]];
|
|
39
|
+
return payload;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
NSArray * dataToArray(NSData *data) {
|
|
43
|
+
const unsigned char *dataBuffer = data ? (const unsigned char *)[data bytes] : NULL;
|
|
44
|
+
|
|
45
|
+
if (!dataBuffer)
|
|
46
|
+
return @[];
|
|
47
|
+
|
|
48
|
+
NSUInteger dataLength = [data length];
|
|
49
|
+
NSMutableArray *array = [NSMutableArray arrayWithCapacity:dataLength];
|
|
50
|
+
|
|
51
|
+
for (int i = 0; i < dataLength; ++i)
|
|
52
|
+
[array addObject:[NSNumber numberWithInteger:dataBuffer[i]]];
|
|
53
|
+
|
|
54
|
+
return array;
|
|
55
|
+
}
|
package/ndef-lib/index.js
CHANGED
package/package.json
CHANGED
package/src/NfcManagerAndroid.js
CHANGED
|
@@ -15,6 +15,8 @@ const NfcAdapter = {
|
|
|
15
15
|
FLAG_READER_NO_PLATFORM_SOUNDS: 0x100,
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
19
|
+
|
|
18
20
|
class NfcManagerAndroid extends NfcManagerBase {
|
|
19
21
|
constructor() {
|
|
20
22
|
super();
|
|
@@ -42,12 +44,13 @@ class NfcManagerAndroid extends NfcManagerBase {
|
|
|
42
44
|
};
|
|
43
45
|
|
|
44
46
|
cancelTechnologyRequest = async (options = {}) => {
|
|
45
|
-
const {throwOnError = false} = options;
|
|
47
|
+
const {throwOnError = false, delayMsAndroid = 1000} = options;
|
|
46
48
|
|
|
47
49
|
try {
|
|
48
50
|
await callNative('cancelTechnologyRequest');
|
|
49
51
|
|
|
50
|
-
if (
|
|
52
|
+
if (this.cleanUpTagRegistration) {
|
|
53
|
+
await delay(delayMsAndroid);
|
|
51
54
|
await this.unregisterTagEvent();
|
|
52
55
|
this.cleanUpTagRegistration = false;
|
|
53
56
|
}
|
|
@@ -67,6 +67,48 @@ class MifareClassicHandlerAndroid {
|
|
|
67
67
|
callNative('mifareClassicWriteBlock', [block, data]),
|
|
68
68
|
);
|
|
69
69
|
}
|
|
70
|
+
|
|
71
|
+
async mifareClassicIncrementBlock(block, value) {
|
|
72
|
+
if (
|
|
73
|
+
!value ||
|
|
74
|
+
Number.isNaN(value)) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`value should be a number`,
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return handleNativeException(
|
|
81
|
+
callNative('mifareClassicIncrementBlock', [block, value]),
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async mifareClassicDecrementBlock(block, value) {
|
|
86
|
+
if (
|
|
87
|
+
!value ||
|
|
88
|
+
Number.isNaN(value)) {
|
|
89
|
+
throw new Error(
|
|
90
|
+
`value should be a number`,
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return handleNativeException(
|
|
95
|
+
callNative('mifareClassicDecrementBlock', [block, value]),
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
async mifareClassicTransferBlock(block) {
|
|
99
|
+
if (
|
|
100
|
+
!block ||
|
|
101
|
+
Number.isNaN(block)) {
|
|
102
|
+
throw new Error(
|
|
103
|
+
`block should be a number`,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return handleNativeException(
|
|
108
|
+
callNative('mifareClassicTransferBlock', [block]),
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
70
112
|
}
|
|
71
113
|
|
|
72
114
|
export {MifareClassicHandlerAndroid};
|