react-native-nfc-manager 3.11.5 → 3.13.2
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/android/src/main/java/community/revteltech/nfc/MifareUtil.java +3 -3
- package/android/src/main/java/community/revteltech/nfc/NfcManager.java +84 -38
- package/android/src/main/java/community/revteltech/nfc/TagTechnologyRequest.java +3 -0
- package/android/src/main/java/community/revteltech/nfc/Util.java +9 -9
- package/index.d.ts +28 -0
- package/ios/NfcManager.h +5 -0
- package/ios/NfcManager.m +107 -127
- package/ios/Util.m +55 -0
- package/ndef-lib/index.js +1 -1
- package/package.json +1 -1
- package/src/NfcManager.js +9 -0
- package/src/NfcManagerAndroid.js +16 -2
- package/src/NfcManagerIOS.js +4 -1
- package/src/NfcTech/Iso15693HandlerIOS.js +21 -1
- package/src/NfcTech/NdefFormatableHandlerAndroid.js +16 -0
- package/src/NfcTech/NfcVHandler.js +39 -0
- package/src/index.js +2 -0
|
@@ -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;
|
|
@@ -266,6 +266,36 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
|
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
|
|
269
|
+
@ReactMethod
|
|
270
|
+
public void formatNdef(ReadableArray rnArray, ReadableMap options, Callback callback) {
|
|
271
|
+
boolean readOnly = options.getBoolean("readOnly");
|
|
272
|
+
|
|
273
|
+
synchronized(this) {
|
|
274
|
+
if (techRequest != null) {
|
|
275
|
+
try {
|
|
276
|
+
NdefFormatable ndef = (NdefFormatable)techRequest.getTechHandle();
|
|
277
|
+
if (ndef == null) {
|
|
278
|
+
callback.invoke(ERR_API_NOT_SUPPORT);
|
|
279
|
+
} else {
|
|
280
|
+
byte[] bytes = rnArrayToBytes(rnArray);
|
|
281
|
+
NdefMessage msg = new NdefMessage(bytes);
|
|
282
|
+
if (readOnly) {
|
|
283
|
+
ndef.formatReadOnly(msg);
|
|
284
|
+
} else {
|
|
285
|
+
ndef.format(msg);
|
|
286
|
+
}
|
|
287
|
+
callback.invoke();
|
|
288
|
+
}
|
|
289
|
+
} catch (Exception ex) {
|
|
290
|
+
Log.d(LOG_TAG, ex.toString());
|
|
291
|
+
callback.invoke(ex.toString());
|
|
292
|
+
}
|
|
293
|
+
} else {
|
|
294
|
+
callback.invoke(ERR_NO_TECH_REQ);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
269
299
|
private void mifareClassicAuthenticate(char type, int sector, ReadableArray key, Callback callback) {
|
|
270
300
|
if (techRequest != null) {
|
|
271
301
|
try {
|
|
@@ -616,27 +646,27 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
|
|
|
616
646
|
@ReactMethod
|
|
617
647
|
public void connect(ReadableArray techs, Callback callback){
|
|
618
648
|
synchronized(this) {
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
649
|
+
try {
|
|
650
|
+
techRequest = new TagTechnologyRequest(techs.toArrayList(), callback);
|
|
651
|
+
techRequest.connect(this.tag);
|
|
652
|
+
callback.invoke(null, null);
|
|
653
|
+
return;
|
|
654
|
+
} catch (Exception ex) {
|
|
655
|
+
callback.invoke(ex.toString());
|
|
656
|
+
}
|
|
627
657
|
}
|
|
628
658
|
}
|
|
629
659
|
|
|
630
660
|
@ReactMethod
|
|
631
661
|
public void close(Callback callback){
|
|
632
662
|
synchronized(this) {
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
663
|
+
try {
|
|
664
|
+
techRequest.close();
|
|
665
|
+
callback.invoke(null, null);
|
|
666
|
+
return;
|
|
667
|
+
} catch (Exception ex) {
|
|
668
|
+
callback.invoke(ex.toString());
|
|
669
|
+
}
|
|
640
670
|
}
|
|
641
671
|
}
|
|
642
672
|
|
|
@@ -941,11 +971,11 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
|
|
|
941
971
|
|
|
942
972
|
@ReactMethod
|
|
943
973
|
private void registerTagEvent(ReadableMap options, Callback callback) {
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
974
|
+
isReaderModeEnabled = options.getBoolean("isReaderModeEnabled");
|
|
975
|
+
readerModeFlags = options.getInt("readerModeFlags");
|
|
976
|
+
readerModeDelay = options.getInt("readerModeDelay");
|
|
947
977
|
|
|
948
|
-
Log.d(LOG_TAG, "
|
|
978
|
+
Log.d(LOG_TAG, "registerTagEvent");
|
|
949
979
|
isForegroundEnabled = true;
|
|
950
980
|
|
|
951
981
|
// capture all mime-based dispatch NDEF
|
|
@@ -972,18 +1002,23 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
|
|
|
972
1002
|
|
|
973
1003
|
@ReactMethod
|
|
974
1004
|
private void unregisterTagEvent(Callback callback) {
|
|
975
|
-
Log.d(LOG_TAG, "
|
|
976
|
-
isForegroundEnabled = false;
|
|
977
|
-
intentFilters.clear();
|
|
1005
|
+
Log.d(LOG_TAG, "unregisterTagEvent");
|
|
978
1006
|
if (isResumed) {
|
|
979
1007
|
enableDisableForegroundDispatch(false);
|
|
980
1008
|
}
|
|
1009
|
+
|
|
1010
|
+
intentFilters.clear();
|
|
1011
|
+
isForegroundEnabled = false;
|
|
1012
|
+
isReaderModeEnabled = false;
|
|
1013
|
+
readerModeFlags = 0;
|
|
1014
|
+
readerModeDelay = 0;
|
|
1015
|
+
|
|
981
1016
|
callback.invoke();
|
|
982
1017
|
}
|
|
983
1018
|
|
|
984
1019
|
@ReactMethod
|
|
985
1020
|
private void hasTagEventRegistration(Callback callback) {
|
|
986
|
-
Log.d(LOG_TAG, "isSessionAvailable");
|
|
1021
|
+
Log.d(LOG_TAG, "isSessionAvailable: " + isForegroundEnabled);
|
|
987
1022
|
callback.invoke(null, isForegroundEnabled);
|
|
988
1023
|
}
|
|
989
1024
|
|
|
@@ -1031,25 +1066,36 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
|
|
|
1031
1066
|
}
|
|
1032
1067
|
|
|
1033
1068
|
if (enable) {
|
|
1034
|
-
Log.i(LOG_TAG, "enableReaderMode");
|
|
1069
|
+
Log.i(LOG_TAG, "enableReaderMode: " + readerModeFlags);
|
|
1035
1070
|
Bundle readerModeExtras = new Bundle();
|
|
1036
1071
|
readerModeExtras.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, readerModeDelay * 1000);
|
|
1037
1072
|
nfcAdapter.enableReaderMode(currentActivity, new NfcAdapter.ReaderCallback() {
|
|
1038
1073
|
@Override
|
|
1039
1074
|
public void onTagDiscovered(Tag tag) {
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1075
|
+
synchronized (this) {
|
|
1076
|
+
manager.tag = tag;
|
|
1077
|
+
Log.d(LOG_TAG, "readerMode onTagDiscovered");
|
|
1078
|
+
WritableMap nfcTag = null;
|
|
1079
|
+
// if the tag contains NDEF, we want to report the content
|
|
1080
|
+
if (Arrays.asList(tag.getTechList()).contains(Ndef.class.getName())) {
|
|
1081
|
+
Ndef ndef = Ndef.get(tag);
|
|
1082
|
+
nfcTag = ndef2React(ndef, new NdefMessage[] { ndef.getCachedNdefMessage() });
|
|
1083
|
+
} else {
|
|
1084
|
+
nfcTag = tag2React(tag);
|
|
1085
|
+
}
|
|
1086
|
+
|
|
1087
|
+
if (nfcTag != null) {
|
|
1088
|
+
sendEvent("NfcManagerDiscoverTag", nfcTag);
|
|
1089
|
+
if (techRequest!= null && !techRequest.isConnected()) {
|
|
1090
|
+
boolean result = techRequest.connect(tag);
|
|
1091
|
+
if (result) {
|
|
1092
|
+
techRequest.getPendingCallback().invoke(null, techRequest.getTechType());
|
|
1093
|
+
} else {
|
|
1094
|
+
// this indicates that we get a NFC tag, but none of the user required tech is matched
|
|
1095
|
+
techRequest.getPendingCallback().invoke(null, null);
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1053
1099
|
}
|
|
1054
1100
|
}
|
|
1055
1101
|
}, readerModeFlags, readerModeExtras);
|
|
@@ -1077,7 +1123,7 @@ class NfcManager extends ReactContextBaseJavaModule implements ActivityEventList
|
|
|
1077
1123
|
|
|
1078
1124
|
int flag = 0;
|
|
1079
1125
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
|
1080
|
-
|
|
1126
|
+
flag = PendingIntent.FLAG_MUTABLE;
|
|
1081
1127
|
}
|
|
1082
1128
|
return PendingIntent.getActivity(activity, 0, intent, flag);
|
|
1083
1129
|
}
|
|
@@ -11,6 +11,7 @@ import android.nfc.tech.NfcV;
|
|
|
11
11
|
import android.nfc.tech.NfcF;
|
|
12
12
|
import android.nfc.tech.MifareClassic;
|
|
13
13
|
import android.nfc.tech.MifareUltralight;
|
|
14
|
+
import android.nfc.tech.NdefFormatable;
|
|
14
15
|
import android.nfc.tech.IsoDep;
|
|
15
16
|
import android.util.Log;
|
|
16
17
|
import com.facebook.react.bridge.*;
|
|
@@ -76,6 +77,8 @@ class TagTechnologyRequest {
|
|
|
76
77
|
mTech = MifareClassic.get(tag);
|
|
77
78
|
} else if (techType.equals("MifareUltralight")) {
|
|
78
79
|
mTech = MifareUltralight.get(tag);
|
|
80
|
+
} else if (techType.equals("NdefFormatable")) {
|
|
81
|
+
mTech = NdefFormatable.get(tag);
|
|
79
82
|
}
|
|
80
83
|
|
|
81
84
|
if (mTech == null) {
|
|
@@ -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
|
@@ -22,6 +22,7 @@ declare module 'react-native-nfc-manager' {
|
|
|
22
22
|
MifareIOS = 'mifare',
|
|
23
23
|
Iso15693IOS = 'iso15693',
|
|
24
24
|
FelicaIOS = 'felica',
|
|
25
|
+
NdefFormatable = 'NdefFormatable',
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
export enum NdefStatus {
|
|
@@ -47,6 +48,17 @@ declare module 'react-native-nfc-manager' {
|
|
|
47
48
|
Select = 1 << 4,
|
|
48
49
|
Address = 1 << 5,
|
|
49
50
|
Option = 1 << 6,
|
|
51
|
+
CommandSpecificBit8 = 1 << 7,
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export enum Nfc15693ResponseFlagIOS {
|
|
55
|
+
Error = 1 << 0,
|
|
56
|
+
ResponseBufferValid = 1 << 1,
|
|
57
|
+
FinalResponse = 1 << 2,
|
|
58
|
+
ProtocolExtension = 1 << 3,
|
|
59
|
+
BlockSecurityStatusBit5 = 1 << 4,
|
|
60
|
+
BlockSecurityStatusBit6 = 1 << 5,
|
|
61
|
+
WaitTimeExtension = 1 << 6,
|
|
50
62
|
}
|
|
51
63
|
|
|
52
64
|
type TNF = 0x0 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07;
|
|
@@ -76,6 +88,7 @@ declare module 'react-native-nfc-manager' {
|
|
|
76
88
|
|
|
77
89
|
export interface CancelTechReqOpts {
|
|
78
90
|
throwOnError?: boolean = false;
|
|
91
|
+
delayMsAndroid?: number = 1000;
|
|
79
92
|
}
|
|
80
93
|
|
|
81
94
|
interface NdefHandler {
|
|
@@ -93,6 +106,10 @@ declare module 'react-native-nfc-manager' {
|
|
|
93
106
|
transceive: (bytes: number[]) => Promise<number[]>;
|
|
94
107
|
}
|
|
95
108
|
|
|
109
|
+
interface NfcVHandler {
|
|
110
|
+
transceive: (bytes: number[]) => Promise<number[]>;
|
|
111
|
+
}
|
|
112
|
+
|
|
96
113
|
interface IsoDepHandler {
|
|
97
114
|
transceive: (bytes: number[]) => Promise<number[]>;
|
|
98
115
|
}
|
|
@@ -121,6 +138,10 @@ declare module 'react-native-nfc-manager' {
|
|
|
121
138
|
) => Promise<void>;
|
|
122
139
|
}
|
|
123
140
|
|
|
141
|
+
interface NdefFormatableHandlerAndroid {
|
|
142
|
+
formatNdef: (bytes: number[], options?: { readOnly: boolean }) => Promise<void>;
|
|
143
|
+
}
|
|
144
|
+
|
|
124
145
|
/** [iOS ONLY] */
|
|
125
146
|
interface Iso15693HandlerIOS {
|
|
126
147
|
getSystemInfo: (
|
|
@@ -159,6 +180,11 @@ declare module 'react-native-nfc-manager' {
|
|
|
159
180
|
customCommandCode: number;
|
|
160
181
|
customRequestParameters: number[];
|
|
161
182
|
}) => Promise<number[]>;
|
|
183
|
+
sendRequest: (params: {
|
|
184
|
+
flags: number;
|
|
185
|
+
commandCode: number;
|
|
186
|
+
data: number[];
|
|
187
|
+
}) => Promise<[number, number[]]>;
|
|
162
188
|
extendedReadSingleBlock: (params: {
|
|
163
189
|
flags: number;
|
|
164
190
|
blockNumber: number;
|
|
@@ -201,6 +227,7 @@ declare module 'react-native-nfc-manager' {
|
|
|
201
227
|
*/
|
|
202
228
|
ndefHandler: NdefHandler;
|
|
203
229
|
nfcAHandler: NfcAHandler;
|
|
230
|
+
nfcVHandler: NfcVHandler;
|
|
204
231
|
isoDepHandler: IsoDepHandler;
|
|
205
232
|
|
|
206
233
|
/**
|
|
@@ -236,6 +263,7 @@ declare module 'react-native-nfc-manager' {
|
|
|
236
263
|
setTimeout(timeout: number): Promise<void>;
|
|
237
264
|
mifareClassicHandlerAndroid: MifareClassicHandlerAndroid;
|
|
238
265
|
mifareUltralightHandlerAndroid: MifareUltralightHandlerAndroid;
|
|
266
|
+
ndefFormatableHandlerAndroid: NdefFormatableHandlerAndroid;
|
|
239
267
|
}
|
|
240
268
|
|
|
241
269
|
const nfcManager: NfcManager;
|
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,40 @@ 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)]);
|
|
1118
|
+
}];
|
|
1119
|
+
} else {
|
|
1120
|
+
callback(@[@"Not support in this device", [NSNull null]]);
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
RCT_EXPORT_METHOD(iso15693_sendRequest:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
1125
|
+
{
|
|
1126
|
+
if (@available(iOS 14.0, *)) {
|
|
1127
|
+
if (!tagSession || !tagSession.connectedTag) {
|
|
1128
|
+
callback(@[@"Not connected", [NSNull null]]);
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
id<NFCISO15693Tag> tag = [tagSession.connectedTag asNFCISO15693Tag];
|
|
1133
|
+
if (!tag) {
|
|
1134
|
+
callback(@[@"incorrect tag type", [NSNull null]]);
|
|
1135
|
+
return;
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
NSInteger flags = [[options objectForKey:@"flags"] integerValue];
|
|
1139
|
+
NSInteger commandCode = [[options objectForKey:@"commandCode"] integerValue];
|
|
1140
|
+
NSData *data = arrayToData([options mutableArrayValueForKey:@"data"]);
|
|
1141
|
+
|
|
1142
|
+
[tag sendRequestWithFlag:flags
|
|
1143
|
+
commandCode:commandCode
|
|
1144
|
+
data:data
|
|
1145
|
+
completionHandler:^(NFCISO15693ResponseFlag responseFlag, NSData *resp, NSError *error) {
|
|
1146
|
+
if (error) {
|
|
1147
|
+
callback(@[getErrorMessage(error), [NSNull null]]);
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
callback(@[[NSNull null], [NSNumber numberWithLong:responseFlag], dataToArray(resp)]);
|
|
1171
1151
|
}];
|
|
1172
1152
|
} else {
|
|
1173
1153
|
callback(@[@"Not support in this device", [NSNull null]]);
|
|
@@ -1176,7 +1156,7 @@ RCT_EXPORT_METHOD(iso15693_customCommand:(NSDictionary *)options callback:(nonnu
|
|
|
1176
1156
|
|
|
1177
1157
|
RCT_EXPORT_METHOD(iso15693_extendedReadSingleBlock:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
1178
1158
|
{
|
|
1179
|
-
if (@available(iOS
|
|
1159
|
+
if (@available(iOS 14.0, *)) {
|
|
1180
1160
|
if (!tagSession || !tagSession.connectedTag) {
|
|
1181
1161
|
callback(@[@"Not connected", [NSNull null]]);
|
|
1182
1162
|
return;
|
|
@@ -1199,7 +1179,7 @@ RCT_EXPORT_METHOD(iso15693_extendedReadSingleBlock:(NSDictionary *)options callb
|
|
|
1199
1179
|
return;
|
|
1200
1180
|
}
|
|
1201
1181
|
|
|
1202
|
-
callback(@[[NSNull null],
|
|
1182
|
+
callback(@[[NSNull null], dataToArray(resp)]);
|
|
1203
1183
|
}];
|
|
1204
1184
|
} else {
|
|
1205
1185
|
callback(@[@"Not support in this device", [NSNull null]]);
|
|
@@ -1208,7 +1188,7 @@ RCT_EXPORT_METHOD(iso15693_extendedReadSingleBlock:(NSDictionary *)options callb
|
|
|
1208
1188
|
|
|
1209
1189
|
RCT_EXPORT_METHOD(iso15693_extendedWriteSingleBlock:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
1210
1190
|
{
|
|
1211
|
-
if (@available(iOS
|
|
1191
|
+
if (@available(iOS 14.0, *)) {
|
|
1212
1192
|
if (!tagSession || !tagSession.connectedTag) {
|
|
1213
1193
|
callback(@[@"Not connected", [NSNull null]]);
|
|
1214
1194
|
return;
|
|
@@ -1222,7 +1202,7 @@ RCT_EXPORT_METHOD(iso15693_extendedWriteSingleBlock:(NSDictionary *)options call
|
|
|
1222
1202
|
|
|
1223
1203
|
RequestFlag flags = [[options objectForKey:@"flags"] unsignedIntValue];
|
|
1224
1204
|
uint16_t blockNumber = [[options objectForKey:@"blockNumber"] unsignedIntValue];
|
|
1225
|
-
NSData *dataBlock =
|
|
1205
|
+
NSData *dataBlock = arrayToData([options mutableArrayValueForKey:@"dataBlock"]);
|
|
1226
1206
|
|
|
1227
1207
|
[tag extendedWriteSingleBlockWithRequestFlags:flags
|
|
1228
1208
|
blockNumber:blockNumber
|
|
@@ -1242,7 +1222,7 @@ RCT_EXPORT_METHOD(iso15693_extendedWriteSingleBlock:(NSDictionary *)options call
|
|
|
1242
1222
|
|
|
1243
1223
|
RCT_EXPORT_METHOD(iso15693_extendedLockBlock:(NSDictionary *)options callback:(nonnull RCTResponseSenderBlock)callback)
|
|
1244
1224
|
{
|
|
1245
|
-
if (@available(iOS
|
|
1225
|
+
if (@available(iOS 14.0, *)) {
|
|
1246
1226
|
if (!tagSession || !tagSession.connectedTag) {
|
|
1247
1227
|
callback(@[@"Not connected", [NSNull null]]);
|
|
1248
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/NfcManager.js
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
} from './NativeNfcManager';
|
|
8
8
|
import {NdefHandler, NdefStatus} from './NfcTech/NdefHandler';
|
|
9
9
|
import {NfcAHandler} from './NfcTech/NfcAHandler';
|
|
10
|
+
import {NfcVHandler} from './NfcTech/NfcVHandler';
|
|
10
11
|
import {IsoDepHandler} from './NfcTech/IsoDepHandler';
|
|
11
12
|
import {
|
|
12
13
|
handleNativeException,
|
|
@@ -33,6 +34,7 @@ const NfcTech = {
|
|
|
33
34
|
MifareIOS: 'mifare',
|
|
34
35
|
Iso15693IOS: 'iso15693',
|
|
35
36
|
FelicaIOS: 'felica',
|
|
37
|
+
NdefFormatable: 'NdefFormatable',
|
|
36
38
|
};
|
|
37
39
|
|
|
38
40
|
const DEFAULT_REGISTER_TAG_EVENT_OPTIONS = {
|
|
@@ -124,6 +126,13 @@ class NfcManagerBase {
|
|
|
124
126
|
return this._nfcAHandler;
|
|
125
127
|
}
|
|
126
128
|
|
|
129
|
+
get nfcVHandler() {
|
|
130
|
+
if (!this._nfcVHandler) {
|
|
131
|
+
this._nfcVHandler = new NfcVHandler();
|
|
132
|
+
}
|
|
133
|
+
return this._nfcVHandler;
|
|
134
|
+
}
|
|
135
|
+
|
|
127
136
|
get isoDepHandler() {
|
|
128
137
|
if (!this._isoDepHandler) {
|
|
129
138
|
this._isoDepHandler = new IsoDepHandler();
|
package/src/NfcManagerAndroid.js
CHANGED
|
@@ -2,6 +2,7 @@ import {callNative} from './NativeNfcManager';
|
|
|
2
2
|
import {NfcManagerBase} from './NfcManager';
|
|
3
3
|
import {MifareClassicHandlerAndroid} from './NfcTech/MifareClassicHandlerAndroid';
|
|
4
4
|
import {MifareUltralightHandlerAndroid} from './NfcTech/MifareUltralightHandlerAndroid';
|
|
5
|
+
import {NdefFormatableHandlerAndroid} from './NfcTech/NdefFormatableHandlerAndroid';
|
|
5
6
|
import {handleNativeException, buildNfcExceptionAndroid} from './NfcError';
|
|
6
7
|
|
|
7
8
|
const NfcAdapter = {
|
|
@@ -14,6 +15,8 @@ const NfcAdapter = {
|
|
|
14
15
|
FLAG_READER_NO_PLATFORM_SOUNDS: 0x100,
|
|
15
16
|
};
|
|
16
17
|
|
|
18
|
+
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
|
|
19
|
+
|
|
17
20
|
class NfcManagerAndroid extends NfcManagerBase {
|
|
18
21
|
constructor() {
|
|
19
22
|
super();
|
|
@@ -41,12 +44,13 @@ class NfcManagerAndroid extends NfcManagerBase {
|
|
|
41
44
|
};
|
|
42
45
|
|
|
43
46
|
cancelTechnologyRequest = async (options = {}) => {
|
|
44
|
-
const {throwOnError = false} = options;
|
|
47
|
+
const {throwOnError = false, delayMsAndroid = 1000} = options;
|
|
45
48
|
|
|
46
49
|
try {
|
|
47
50
|
await callNative('cancelTechnologyRequest');
|
|
48
51
|
|
|
49
|
-
if (
|
|
52
|
+
if (this.cleanUpTagRegistration) {
|
|
53
|
+
await delay(delayMsAndroid);
|
|
50
54
|
await this.unregisterTagEvent();
|
|
51
55
|
this.cleanUpTagRegistration = false;
|
|
52
56
|
}
|
|
@@ -111,6 +115,16 @@ class NfcManagerAndroid extends NfcManagerBase {
|
|
|
111
115
|
return this._mifareUltralightHandlerAndroid;
|
|
112
116
|
}
|
|
113
117
|
|
|
118
|
+
// -------------------------------------
|
|
119
|
+
// (android) NfcTech.NdefFormatable API
|
|
120
|
+
// -------------------------------------
|
|
121
|
+
get ndefFormatableHandlerAndroid() {
|
|
122
|
+
if (!this._ndefFormatableHandlerAndroid) {
|
|
123
|
+
this._ndefFormatableHandlerAndroid = new NdefFormatableHandlerAndroid(this);
|
|
124
|
+
}
|
|
125
|
+
return this._ndefFormatableHandlerAndroid;
|
|
126
|
+
}
|
|
127
|
+
|
|
114
128
|
// -------------------------------------
|
|
115
129
|
// Android private
|
|
116
130
|
// -------------------------------------
|
package/src/NfcManagerIOS.js
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
} from './NfcManager';
|
|
9
9
|
import {
|
|
10
10
|
Nfc15693RequestFlagIOS,
|
|
11
|
+
Nfc15693ResponseFlagIOS,
|
|
11
12
|
Iso15693HandlerIOS,
|
|
12
13
|
} from './NfcTech/Iso15693HandlerIOS';
|
|
13
14
|
import {handleNativeException} from './NfcError';
|
|
@@ -30,6 +31,8 @@ class NfcManagerIOS extends NfcManagerBase {
|
|
|
30
31
|
for (const t of tech) {
|
|
31
32
|
if (t === NfcTech.NfcA) {
|
|
32
33
|
techList.push(NfcTech.MifareIOS);
|
|
34
|
+
} else if (t === NfcTech.NfcV) {
|
|
35
|
+
techList.push(NfcTech.Iso15693IOS);
|
|
33
36
|
} else {
|
|
34
37
|
techList.push(t);
|
|
35
38
|
}
|
|
@@ -145,4 +148,4 @@ class NfcManagerIOS extends NfcManagerBase {
|
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
|
|
148
|
-
export {NfcManagerIOS, Nfc15693RequestFlagIOS};
|
|
151
|
+
export {NfcManagerIOS, Nfc15693RequestFlagIOS, Nfc15693ResponseFlagIOS};
|
|
@@ -8,6 +8,17 @@ const Nfc15693RequestFlagIOS = {
|
|
|
8
8
|
Select: 1 << 4,
|
|
9
9
|
Address: 1 << 5,
|
|
10
10
|
Option: 1 << 6,
|
|
11
|
+
CommandSpecificBit8: 1 << 7,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const Nfc15693ResponseFlagIOS = {
|
|
15
|
+
Error: 1 << 0,
|
|
16
|
+
ResponseBufferValid: 1 << 1,
|
|
17
|
+
FinalResponse: 1 << 2,
|
|
18
|
+
ProtocolExtension: 1 << 3,
|
|
19
|
+
BlockSecurityStatusBit5: 1 << 4,
|
|
20
|
+
BlockSecurityStatusBit6: 1 << 5,
|
|
21
|
+
WaitTimeExtension: 1 << 6
|
|
11
22
|
};
|
|
12
23
|
|
|
13
24
|
class Iso15693HandlerIOS {
|
|
@@ -87,6 +98,15 @@ class Iso15693HandlerIOS {
|
|
|
87
98
|
);
|
|
88
99
|
}
|
|
89
100
|
|
|
101
|
+
// https://developer.apple.com/documentation/corenfc/nfciso15693tag/3551933-sendrequestwithflag?language=objc
|
|
102
|
+
sendRequest({flags, commandCode, data}) {
|
|
103
|
+
return handleNativeException(
|
|
104
|
+
callNative('iso15693_sendRequest', [
|
|
105
|
+
{flags, commandCode, data},
|
|
106
|
+
]),
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
90
110
|
extendedReadSingleBlock({flags, blockNumber}) {
|
|
91
111
|
return handleNativeException(
|
|
92
112
|
callNative('iso15693_extendedReadSingleBlock', [{flags, blockNumber}]),
|
|
@@ -108,4 +128,4 @@ class Iso15693HandlerIOS {
|
|
|
108
128
|
}
|
|
109
129
|
}
|
|
110
130
|
|
|
111
|
-
export {Nfc15693RequestFlagIOS, Iso15693HandlerIOS};
|
|
131
|
+
export {Nfc15693RequestFlagIOS, Nfc15693ResponseFlagIOS, Iso15693HandlerIOS};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {callNative} from '../NativeNfcManager';
|
|
2
|
+
import {handleNativeException} from '../NfcError';
|
|
3
|
+
|
|
4
|
+
class NdefFormatableHandlerAndroid {
|
|
5
|
+
async formatNdef(bytes, options={}) {
|
|
6
|
+
const defaultOptions = { readOnly: false };
|
|
7
|
+
return handleNativeException(
|
|
8
|
+
callNative('formatNdef', [
|
|
9
|
+
bytes,
|
|
10
|
+
{...defaultOptions, ...options}
|
|
11
|
+
])
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export {NdefFormatableHandlerAndroid};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {Platform} from 'react-native';
|
|
2
|
+
import {callNative, NativeNfcManager} from '../NativeNfcManager';
|
|
3
|
+
import {handleNativeException} from '../NfcError';
|
|
4
|
+
|
|
5
|
+
class NfcVHandler {
|
|
6
|
+
async transceive(bytes) {
|
|
7
|
+
if (!Array.isArray(bytes)) {
|
|
8
|
+
throw new Error(
|
|
9
|
+
'IsoDepHandler.transceive only takes input as a byte array',
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
if (Platform.OS === 'ios') {
|
|
14
|
+
const [flags, commandCode, ...data] = bytes;
|
|
15
|
+
return handleNativeException(
|
|
16
|
+
new Promise((resolve, reject) => {
|
|
17
|
+
NativeNfcManager.iso15693_sendRequest(
|
|
18
|
+
{
|
|
19
|
+
flags,
|
|
20
|
+
commandCode,
|
|
21
|
+
data,
|
|
22
|
+
},
|
|
23
|
+
(err, responseFlag, response) => {
|
|
24
|
+
if (err) {
|
|
25
|
+
reject(err);
|
|
26
|
+
} else {
|
|
27
|
+
resolve([responseFlag, ...response]);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
);
|
|
31
|
+
}),
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return handleNativeException(callNative('transceive', [bytes]));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export {NfcVHandler};
|
package/src/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import {NfcEvents, NfcTech, NdefStatus} from './NfcManager';
|
|
|
4
4
|
import {NfcAdapter, NfcManagerAndroid} from './NfcManagerAndroid';
|
|
5
5
|
import {
|
|
6
6
|
Nfc15693RequestFlagIOS,
|
|
7
|
+
Nfc15693ResponseFlagIOS,
|
|
7
8
|
NfcManagerIOS,
|
|
8
9
|
} from './NfcManagerIOS';
|
|
9
10
|
import * as NfcError from './NfcError';
|
|
@@ -26,6 +27,7 @@ export {
|
|
|
26
27
|
NfcEvents,
|
|
27
28
|
NfcAdapter,
|
|
28
29
|
Nfc15693RequestFlagIOS,
|
|
30
|
+
Nfc15693ResponseFlagIOS,
|
|
29
31
|
Ndef,
|
|
30
32
|
NdefStatus,
|
|
31
33
|
NfcError,
|