react-native-nfc-manager 4.0.0-beta.1 → 4.0.0-beta.11
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/README.md +146 -49
- package/android/src/main/java/community/revteltech/nfc/MifareClassicHandler.java +419 -0
- package/android/src/main/java/community/revteltech/nfc/MifareUltralightHandler.java +84 -0
- package/android/src/main/java/community/revteltech/nfc/NdefHandler.java +397 -0
- package/android/src/main/java/community/revteltech/nfc/NfcAdapterStateChangedReceiver.java +48 -0
- package/android/src/main/java/community/revteltech/nfc/NfcErrorCodes.java +16 -0
- package/android/src/main/java/community/revteltech/nfc/NfcManager.java +348 -1087
- package/android/src/main/java/community/revteltech/nfc/NfcManagerIOSStubBase.java +130 -0
- package/android/src/main/java/community/revteltech/nfc/NfcTechIoRouter.java +258 -0
- package/android/src/main/java/community/revteltech/nfc/TagTechnologyRequest.java +19 -7
- package/android/src/main/java/community/revteltech/nfc/Util.java +275 -2
- package/app.plugin.js +8 -9
- package/dist/ndef-lib/constants.js +67 -0
- package/dist/ndef-lib/constants.js.map +1 -0
- package/dist/ndef-lib/index.js +79 -0
- package/dist/ndef-lib/index.js.map +1 -0
- package/dist/ndef-lib/ndef-text.js +29 -0
- package/dist/ndef-lib/ndef-text.js.map +1 -0
- package/dist/ndef-lib/ndef-uri.js +40 -0
- package/dist/ndef-lib/ndef-uri.js.map +1 -0
- package/dist/ndef-lib/ndef-wifi-simple.js +100 -0
- package/dist/ndef-lib/ndef-wifi-simple.js.map +1 -0
- package/dist/ndef-lib/ndef.js +152 -0
- package/dist/ndef-lib/ndef.js.map +1 -0
- package/dist/ndef-lib/stringifier.js +155 -0
- package/dist/ndef-lib/stringifier.js.map +1 -0
- package/dist/ndef-lib/util.js +134 -0
- package/dist/ndef-lib/util.js.map +1 -0
- package/dist/specs/NativeNfcManager.js +5 -0
- package/dist/specs/NativeNfcManager.js.map +1 -0
- package/dist/src/NativeNfcManager.js +55 -0
- package/dist/src/NativeNfcManager.js.map +1 -0
- package/dist/src/NfcError.js +220 -0
- package/dist/src/NfcError.js.map +1 -0
- package/dist/src/NfcManager.js +175 -0
- package/dist/src/NfcManager.js.map +1 -0
- package/dist/src/NfcManagerAndroid.js +112 -0
- package/dist/src/NfcManagerAndroid.js.map +1 -0
- package/dist/src/NfcManagerIOS.js +119 -0
- package/dist/src/NfcManagerIOS.js.map +1 -0
- package/dist/src/NfcTech/Iso15693HandlerIOS.js +99 -0
- package/dist/src/NfcTech/Iso15693HandlerIOS.js.map +1 -0
- package/dist/src/NfcTech/IsoDepHandler.js +29 -0
- package/dist/src/NfcTech/IsoDepHandler.js.map +1 -0
- package/dist/src/NfcTech/MifareClassicHandlerAndroid.js +68 -0
- package/dist/src/NfcTech/MifareClassicHandlerAndroid.js.map +1 -0
- package/dist/src/NfcTech/MifareUltralightHandlerAndroid.js +23 -0
- package/dist/src/NfcTech/MifareUltralightHandlerAndroid.js.map +1 -0
- package/dist/src/NfcTech/NdefFormatableHandlerAndroid.js +16 -0
- package/dist/src/NfcTech/NdefFormatableHandlerAndroid.js.map +1 -0
- package/dist/src/NfcTech/NdefHandler.js +54 -0
- package/dist/src/NfcTech/NdefHandler.js.map +1 -0
- package/dist/src/NfcTech/NfcAHandler.js +16 -0
- package/dist/src/NfcTech/NfcAHandler.js.map +1 -0
- package/dist/src/NfcTech/NfcVHandler.js +33 -0
- package/dist/src/NfcTech/NfcVHandler.js.map +1 -0
- package/dist/src/index.js +53 -0
- package/dist/src/index.js.map +1 -0
- package/index.d.ts +110 -46
- package/ios/NfcManager.h +2 -11
- package/ios/NfcManager.mm +264 -438
- package/ios/RNNfcBridgeUtil.h +28 -0
- package/ios/RNNfcBridgeUtil.mm +52 -0
- package/ios/RNNfcManager+Felica.swift +61 -0
- package/ios/RNNfcManager+Iso15693.swift +895 -0
- package/ios/RNNfcManager+IsoDep.swift +145 -0
- package/ios/RNNfcManager+Mifare.swift +61 -0
- package/ios/RNNfcManager+Ndef.swift +120 -0
- package/ios/RNNfcManager.h +251 -0
- package/ios/RNNfcManager.swift +648 -0
- package/ios/RNNfcSessionDelegateProxy.swift +104 -0
- package/ios/RNNfcSwiftUtil.swift +34 -0
- package/ndef-lib/{constants.js → constants.ts} +2 -0
- package/ndef-lib/{index.js → index.ts} +23 -12
- package/ndef-lib/{ndef-text.js → ndef-text.ts} +7 -2
- package/ndef-lib/{ndef-uri.js → ndef-uri.ts} +8 -3
- package/ndef-lib/{ndef-wifi-simple.js → ndef-wifi-simple.ts} +34 -11
- package/ndef-lib/{ndef.js → ndef.ts} +53 -25
- package/ndef-lib/{stringifier.js → stringifier.ts} +27 -10
- package/ndef-lib/{util.js → util.ts} +23 -9
- package/package.json +39 -21
- package/react-native-nfc-manager.podspec +3 -2
- package/specs/NativeNfcManager.ts +18 -4
- package/src/NativeNfcManager.ts +84 -0
- package/src/{NfcError.js → NfcError.ts} +6 -17
- package/src/{NfcManager.js → NfcManager.ts} +51 -34
- package/src/{NfcManagerAndroid.js → NfcManagerAndroid.ts} +27 -8
- package/src/{NfcManagerIOS.js → NfcManagerIOS.ts} +31 -10
- package/src/NfcTech/{Iso15693HandlerIOS.js → Iso15693HandlerIOS.ts} +64 -36
- package/src/NfcTech/{IsoDepHandler.js → IsoDepHandler.ts} +8 -5
- package/src/NfcTech/{MifareClassicHandlerAndroid.js → MifareClassicHandlerAndroid.ts} +33 -24
- package/src/NfcTech/{MifareUltralightHandlerAndroid.js → MifareUltralightHandlerAndroid.ts} +14 -5
- package/src/NfcTech/{NdefFormatableHandlerAndroid.js → NdefFormatableHandlerAndroid.ts} +9 -2
- package/src/NfcTech/{NdefHandler.js → NdefHandler.ts} +19 -6
- package/src/NfcTech/{NfcAHandler.js → NfcAHandler.ts} +6 -3
- package/src/NfcTech/{NfcVHandler.js → NfcVHandler.ts} +8 -5
- package/src/__mocks__/{NativeNfcManager.js → NativeNfcManager.ts} +4 -1
- package/src/{index.js → index.ts} +1 -1
- package/android/src/main/java/community/revteltech/nfc/JsonConvert.java +0 -141
- package/android/src/main/java/community/revteltech/nfc/MifareUtil.java +0 -84
- package/ios/NfcManager+Felica.mm +0 -43
- package/ios/NfcManager+Iso15693.mm +0 -600
- package/ios/NfcManager+IsoDep.mm +0 -83
- package/ios/NfcManager+Mifare.mm +0 -43
- package/ios/Util.mm +0 -55
- package/specs/NativeNfcManager.d.ts +0 -6
- package/specs/NativeNfcManager.js +0 -3
- package/specs/NativeNfcManager.js.map +0 -1
- package/src/NativeNfcManager.js +0 -37
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import CoreNFC
|
|
2
|
+
import Foundation
|
|
3
|
+
|
|
4
|
+
@objcMembers
|
|
5
|
+
@objc(RNNfcSessionDelegateProxy)
|
|
6
|
+
public class RNNfcSessionDelegateProxy: NSObject, NFCNDEFReaderSessionDelegate, NFCTagReaderSessionDelegate {
|
|
7
|
+
public func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
|
|
8
|
+
NSLog("readerSession:didDetectNDEFs")
|
|
9
|
+
if let firstMessage = messages.first {
|
|
10
|
+
RNNfcBridgeUtil.emitEvent("NfcManagerDiscoverTag", body: ["ndefMessage": RNNfcManager.convertNdefMessage(firstMessage)])
|
|
11
|
+
} else {
|
|
12
|
+
RNNfcBridgeUtil.emitEvent("NfcManagerDiscoverTag", body: ["ndefMessage": []])
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
|
|
17
|
+
NSLog("readerSession:didInvalidateWithError: (%@)", (error as NSError).localizedDescription)
|
|
18
|
+
guard RNNfcManager.isCurrentNdefSession(session) else {
|
|
19
|
+
return
|
|
20
|
+
}
|
|
21
|
+
let invalidationCallback = RNNfcManager.takeSessionInvalidationCallback()
|
|
22
|
+
RNNfcManager.resetSessionsState()
|
|
23
|
+
RNNfcManager.resetRequestState()
|
|
24
|
+
invalidationCallback?([])
|
|
25
|
+
RNNfcBridgeUtil.emitEvent("NfcManagerSessionClosed", body: ["error": RNNfcSwiftUtil.errorMessage(from: error as NSError)])
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@available(iOS 13.0, *)
|
|
29
|
+
public func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
|
|
30
|
+
NSLog("NFCTag didDetectTags")
|
|
31
|
+
guard let requestedTypes = RNNfcManager.pendingTechnologyRequestTypes(for: session) else {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
for tag in tags {
|
|
36
|
+
let tagType = techName(for: tag)
|
|
37
|
+
var matchedRequestType: String?
|
|
38
|
+
for requestType in requestedTypes {
|
|
39
|
+
if tagType == requestType || requestType == "Ndef" {
|
|
40
|
+
matchedRequestType = requestType
|
|
41
|
+
break
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
guard let matchedRequestType else {
|
|
46
|
+
continue
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
session.connect(to: tag) { error in
|
|
50
|
+
if error != nil {
|
|
51
|
+
guard RNNfcManager.isCurrentTagSession(session) else {
|
|
52
|
+
return
|
|
53
|
+
}
|
|
54
|
+
NSLog("NFCTag restarting polling")
|
|
55
|
+
session.restartPolling()
|
|
56
|
+
return
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
guard let callback = RNNfcManager.takeTechnologyRequestCallback(for: session) else {
|
|
60
|
+
return
|
|
61
|
+
}
|
|
62
|
+
callback([NSNull(), matchedRequestType])
|
|
63
|
+
}
|
|
64
|
+
return
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
@available(iOS 13.0, *)
|
|
69
|
+
public func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {
|
|
70
|
+
NSLog("NFCTag didInvalidateWithError")
|
|
71
|
+
|
|
72
|
+
guard RNNfcManager.isCurrentTagSession(session) else {
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
let callback = RNNfcManager.takeTechnologyRequestCallback(for: session)
|
|
77
|
+
let invalidationCallback = RNNfcManager.takeSessionInvalidationCallback()
|
|
78
|
+
RNNfcManager.resetSessionsState()
|
|
79
|
+
RNNfcManager.resetRequestState()
|
|
80
|
+
callback?([RNNfcSwiftUtil.errorMessage(from: error as NSError)])
|
|
81
|
+
invalidationCallback?([])
|
|
82
|
+
RNNfcBridgeUtil.emitEvent("NfcManagerSessionClosed", body: ["error": RNNfcSwiftUtil.errorMessage(from: error as NSError)])
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@available(iOS 13.0, *)
|
|
86
|
+
public func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {
|
|
87
|
+
NSLog("NFCTag didBecomeActive")
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private func techName(for tag: NFCTag) -> String {
|
|
91
|
+
switch tag {
|
|
92
|
+
case .miFare:
|
|
93
|
+
return "mifare"
|
|
94
|
+
case .feliCa:
|
|
95
|
+
return "felica"
|
|
96
|
+
case .iso15693:
|
|
97
|
+
return "iso15693"
|
|
98
|
+
case .iso7816:
|
|
99
|
+
return "IsoDep"
|
|
100
|
+
@unknown default:
|
|
101
|
+
return "unknown"
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
@objc(RNNfcSwiftUtil)
|
|
4
|
+
public class RNNfcSwiftUtil: NSObject {
|
|
5
|
+
@objc(hexStringFromData:)
|
|
6
|
+
public static func hexString(from data: Data) -> String {
|
|
7
|
+
var output = String()
|
|
8
|
+
output.reserveCapacity(data.count * 2)
|
|
9
|
+
for byte in data {
|
|
10
|
+
output += String(format: "%02X", byte)
|
|
11
|
+
}
|
|
12
|
+
return output
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@objc(errorMessageFromError:)
|
|
16
|
+
public static func errorMessage(from error: NSError) -> String {
|
|
17
|
+
if let underlyingError = error.userInfo[NSUnderlyingErrorKey] as? NSError {
|
|
18
|
+
return "\(error.domain):\(error.code),\(underlyingError.domain):\(underlyingError.code)"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return "\(error.domain):\(error.code)"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@objc(dataFromNumberArray:)
|
|
25
|
+
public static func data(from numberArray: [NSNumber]) -> Data {
|
|
26
|
+
let bytes = numberArray.map { $0.uint8Value }
|
|
27
|
+
return Data(bytes)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@objc(numberArrayFromData:)
|
|
31
|
+
public static func numberArray(from data: Data) -> [NSNumber] {
|
|
32
|
+
return data.map { NSNumber(value: Int($0)) }
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -14,20 +14,29 @@ const uriHelper = require('./ndef-uri');
|
|
|
14
14
|
const wifiSimpleHelper = require('./ndef-wifi-simple');
|
|
15
15
|
const stringifier = require('./stringifier');
|
|
16
16
|
|
|
17
|
+
type Byte = number;
|
|
18
|
+
type ByteArray = Byte[];
|
|
19
|
+
type NdefRecord = {
|
|
20
|
+
tnf: number;
|
|
21
|
+
type: string | ByteArray;
|
|
22
|
+
id: ByteArray;
|
|
23
|
+
payload: ByteArray;
|
|
24
|
+
};
|
|
25
|
+
|
|
17
26
|
const PrimitiveRecord = {
|
|
18
|
-
emptyRecord() {
|
|
27
|
+
emptyRecord(): NdefRecord {
|
|
19
28
|
return createNdefRecord(constants.TNF_EMPTY, [], [], []);
|
|
20
29
|
},
|
|
21
30
|
|
|
22
|
-
absoluteUriRecord(uri, payload = [], id = []) {
|
|
31
|
+
absoluteUriRecord(uri: string, payload: string | ByteArray = [], id: string | ByteArray = []): NdefRecord {
|
|
23
32
|
return createNdefRecord(constants.TNF_ABSOLUTE_URI, uri, id, payload);
|
|
24
33
|
},
|
|
25
34
|
|
|
26
|
-
mimeMediaRecord(mimeType, payload, id = []) {
|
|
35
|
+
mimeMediaRecord(mimeType: string, payload: string | ByteArray, id: string | ByteArray = []): NdefRecord {
|
|
27
36
|
return createNdefRecord(constants.TNF_MIME_MEDIA, mimeType, id, payload);
|
|
28
37
|
},
|
|
29
38
|
|
|
30
|
-
externalTypeRecord(externalType, payload, id = []) {
|
|
39
|
+
externalTypeRecord(externalType: string, payload: string | ByteArray, id: string | ByteArray = []): NdefRecord {
|
|
31
40
|
return createNdefRecord(
|
|
32
41
|
constants.TNF_EXTERNAL_TYPE,
|
|
33
42
|
externalType,
|
|
@@ -38,7 +47,7 @@ const PrimitiveRecord = {
|
|
|
38
47
|
};
|
|
39
48
|
|
|
40
49
|
const WellKnownRecord = {
|
|
41
|
-
textRecord(text, languageCode, id = []) {
|
|
50
|
+
textRecord(text: string, languageCode?: string, id: string | ByteArray = []): NdefRecord {
|
|
42
51
|
return createNdefRecord(
|
|
43
52
|
constants.TNF_WELL_KNOWN,
|
|
44
53
|
constants.RTD_TEXT,
|
|
@@ -47,7 +56,7 @@ const WellKnownRecord = {
|
|
|
47
56
|
);
|
|
48
57
|
},
|
|
49
58
|
|
|
50
|
-
uriRecord(uri, id = []) {
|
|
59
|
+
uriRecord(uri: string, id: string | ByteArray = []): NdefRecord {
|
|
51
60
|
return createNdefRecord(
|
|
52
61
|
constants.TNF_WELL_KNOWN,
|
|
53
62
|
constants.RTD_URI,
|
|
@@ -56,8 +65,8 @@ const WellKnownRecord = {
|
|
|
56
65
|
);
|
|
57
66
|
},
|
|
58
67
|
|
|
59
|
-
smartPoster(ndefRecords, id = []) {
|
|
60
|
-
let payload = [];
|
|
68
|
+
smartPoster(ndefRecords: NdefRecord[] | ByteArray, id: string | ByteArray = []): NdefRecord {
|
|
69
|
+
let payload: ByteArray = [];
|
|
61
70
|
|
|
62
71
|
if (ndefRecords) {
|
|
63
72
|
// make sure we have an array of something like NDEF records before encoding
|
|
@@ -65,10 +74,10 @@ const WellKnownRecord = {
|
|
|
65
74
|
ndefRecords[0] instanceof Object &&
|
|
66
75
|
ndefRecords[0].hasOwnProperty('tnf')
|
|
67
76
|
) {
|
|
68
|
-
payload = encodeNdefMessage(ndefRecords);
|
|
77
|
+
payload = encodeNdefMessage(ndefRecords as NdefRecord[]);
|
|
69
78
|
} else {
|
|
70
79
|
// assume the caller has already encoded the NDEF records into a byte array
|
|
71
|
-
payload = ndefRecords;
|
|
80
|
+
payload = ndefRecords as ByteArray;
|
|
72
81
|
}
|
|
73
82
|
} else {
|
|
74
83
|
console.log('WARNING: Expecting an array of NDEF records');
|
|
@@ -84,7 +93,7 @@ const WellKnownRecord = {
|
|
|
84
93
|
};
|
|
85
94
|
|
|
86
95
|
const ExtraTypeRecord = {
|
|
87
|
-
androidApplicationRecord(packageName, id = []) {
|
|
96
|
+
androidApplicationRecord(packageName: string, id: string | ByteArray = []): NdefRecord {
|
|
88
97
|
return PrimitiveRecord.externalTypeRecord(
|
|
89
98
|
'android.com:pkg',
|
|
90
99
|
packageName,
|
|
@@ -92,7 +101,7 @@ const ExtraTypeRecord = {
|
|
|
92
101
|
);
|
|
93
102
|
},
|
|
94
103
|
|
|
95
|
-
wifiSimpleRecord: function (credentials, id = []) {
|
|
104
|
+
wifiSimpleRecord: function (credentials: {ssid: string; networkKey: string; authType?: ByteArray}, id: string | ByteArray = []): NdefRecord {
|
|
96
105
|
let payload = wifiSimpleHelper.encodePayload(credentials);
|
|
97
106
|
return PrimitiveRecord.mimeMediaRecord(constants.MIME_WFA_WSC, payload, id);
|
|
98
107
|
},
|
|
@@ -120,3 +129,5 @@ const NDEF = {
|
|
|
120
129
|
};
|
|
121
130
|
|
|
122
131
|
module.exports = NDEF;
|
|
132
|
+
|
|
133
|
+
export {};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
var util = require('./util');
|
|
2
2
|
|
|
3
|
+
type Byte = number;
|
|
4
|
+
type ByteArray = Byte[];
|
|
5
|
+
|
|
3
6
|
// decode text bytes from ndef record payload
|
|
4
7
|
// @returns a string
|
|
5
|
-
function decode(data) {
|
|
8
|
+
function decode(data: ByteArray): string | null {
|
|
6
9
|
var languageCodeLength = data[0] & 0x3f; // 6 LSBs
|
|
7
10
|
// languageCode = data.slice(1, 1 + languageCodeLength),
|
|
8
11
|
// utf16 = (data[0] & 0x80) !== 0; // assuming UTF-16BE
|
|
@@ -15,7 +18,7 @@ function decode(data) {
|
|
|
15
18
|
|
|
16
19
|
// encode text payload
|
|
17
20
|
// @returns an array of bytes
|
|
18
|
-
function encode(text, lang, encoding) {
|
|
21
|
+
function encode(text: string, lang?: string, encoding?: unknown): ByteArray {
|
|
19
22
|
// ISO/IANA language code, but we're not enforcing
|
|
20
23
|
if (!lang) {
|
|
21
24
|
lang = 'en';
|
|
@@ -31,3 +34,5 @@ module.exports = {
|
|
|
31
34
|
encodePayload: encode,
|
|
32
35
|
decodePayload: decode,
|
|
33
36
|
};
|
|
37
|
+
|
|
38
|
+
export {};
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
const util = require('./util');
|
|
2
2
|
const protocols = require('./constants').RTD_URI_PROTOCOLS;
|
|
3
3
|
|
|
4
|
+
type Byte = number;
|
|
5
|
+
type ByteArray = Byte[];
|
|
6
|
+
|
|
4
7
|
// decode a URI payload bytes
|
|
5
8
|
// @returns a string
|
|
6
|
-
function decode(data) {
|
|
9
|
+
function decode(data: ByteArray): string {
|
|
7
10
|
var prefix = protocols[data[0]];
|
|
8
11
|
if (!prefix) {
|
|
9
12
|
// 36 to 255 should be ""
|
|
@@ -14,8 +17,8 @@ function decode(data) {
|
|
|
14
17
|
|
|
15
18
|
// shorten a URI with standard prefix
|
|
16
19
|
// @returns an array of bytes
|
|
17
|
-
function encode(uri) {
|
|
18
|
-
var prefix, protocolCode, encoded;
|
|
20
|
+
function encode(uri: string): ByteArray {
|
|
21
|
+
var prefix: string | undefined, protocolCode, encoded;
|
|
19
22
|
|
|
20
23
|
// check each protocol, unless we've found a match
|
|
21
24
|
// "urn:" is the one exception where we need to keep checking
|
|
@@ -42,3 +45,5 @@ module.exports = {
|
|
|
42
45
|
encodePayload: encode,
|
|
43
46
|
decodePayload: decode,
|
|
44
47
|
};
|
|
48
|
+
|
|
49
|
+
export {};
|
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
var util = require('./util');
|
|
2
2
|
|
|
3
|
+
type Byte = number;
|
|
4
|
+
type ByteArray = Byte[];
|
|
5
|
+
|
|
6
|
+
type WifiCredentials = {
|
|
7
|
+
ssid: string;
|
|
8
|
+
networkKey: string;
|
|
9
|
+
authType?: ByteArray;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type Tlv = {
|
|
13
|
+
type: ByteArray;
|
|
14
|
+
length: ByteArray;
|
|
15
|
+
value: ByteArray;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type DecodedWifiCredentials = {
|
|
19
|
+
ssid?: string | null;
|
|
20
|
+
networkKey?: string | null;
|
|
21
|
+
authType?: ByteArray;
|
|
22
|
+
};
|
|
23
|
+
|
|
3
24
|
const CREDENTIAL_FIELD_ID = [0x10, 0x0e];
|
|
4
25
|
const SSID_FIELD_ID = [0x10, 0x45];
|
|
5
26
|
const AUTH_TYPE_FIELD_ID = [0x10, 0x03];
|
|
@@ -10,14 +31,14 @@ const AUTH_TYPES = {
|
|
|
10
31
|
WPA2_PSK: [0x00, 0x20],
|
|
11
32
|
};
|
|
12
33
|
|
|
13
|
-
function _getLengthBytes(valueBytes) {
|
|
34
|
+
function _getLengthBytes(valueBytes: ByteArray): ByteArray {
|
|
14
35
|
if (valueBytes.length > 255) {
|
|
15
36
|
return [Math.floor(valueBytes.length / 256), valueBytes.length % 256];
|
|
16
37
|
}
|
|
17
38
|
return [0x0, valueBytes.length];
|
|
18
39
|
}
|
|
19
40
|
|
|
20
|
-
function _arrayEqual(arr1, arr2) {
|
|
41
|
+
function _arrayEqual(arr1: ByteArray, arr2: ByteArray): boolean {
|
|
21
42
|
if (arr1.length !== arr2.length) {
|
|
22
43
|
return false;
|
|
23
44
|
}
|
|
@@ -31,7 +52,7 @@ function _arrayEqual(arr1, arr2) {
|
|
|
31
52
|
return true;
|
|
32
53
|
}
|
|
33
54
|
|
|
34
|
-
function _getNextTLV(bytes) {
|
|
55
|
+
function _getNextTLV(bytes: ByteArray): Tlv {
|
|
35
56
|
const type = bytes.slice(0, 2);
|
|
36
57
|
const length = bytes.slice(2, 4);
|
|
37
58
|
const value = bytes.slice(4, 4 + (length[0] * 256 + length[1]));
|
|
@@ -43,8 +64,8 @@ function _getNextTLV(bytes) {
|
|
|
43
64
|
}
|
|
44
65
|
|
|
45
66
|
// @returns an string of wifi credentials
|
|
46
|
-
function decode(bytes) {
|
|
47
|
-
let result = {};
|
|
67
|
+
function decode(bytes: ByteArray): DecodedWifiCredentials {
|
|
68
|
+
let result: DecodedWifiCredentials = {};
|
|
48
69
|
|
|
49
70
|
while (bytes.length > 0) {
|
|
50
71
|
let {type, value} = _getNextTLV(bytes);
|
|
@@ -73,13 +94,13 @@ function decode(bytes) {
|
|
|
73
94
|
|
|
74
95
|
// encode wifi object payload
|
|
75
96
|
// @returns an array of bytes
|
|
76
|
-
function encode({ssid, networkKey, authType = AUTH_TYPES.WPA2_PSK}) {
|
|
97
|
+
function encode({ssid, networkKey, authType = AUTH_TYPES.WPA2_PSK}: WifiCredentials): ByteArray {
|
|
77
98
|
if (typeof ssid !== 'string' || typeof networkKey !== 'string') {
|
|
78
99
|
throw new Error('');
|
|
79
100
|
}
|
|
80
101
|
|
|
81
|
-
|
|
82
|
-
|
|
102
|
+
const ssidBytes = util.stringToBytes(ssid);
|
|
103
|
+
const networkKeyBytes = util.stringToBytes(networkKey);
|
|
83
104
|
|
|
84
105
|
// build seperated TLV
|
|
85
106
|
const authTypeTLV = [
|
|
@@ -88,12 +109,12 @@ function encode({ssid, networkKey, authType = AUTH_TYPES.WPA2_PSK}) {
|
|
|
88
109
|
authType.length,
|
|
89
110
|
...authType,
|
|
90
111
|
];
|
|
91
|
-
const ssidTLV = [...SSID_FIELD_ID, 0x0,
|
|
112
|
+
const ssidTLV = [...SSID_FIELD_ID, 0x0, ssidBytes.length, ...ssidBytes];
|
|
92
113
|
const networkKeyTLV = [
|
|
93
114
|
...NETWORK_KEY_FIELD_ID,
|
|
94
115
|
0x0,
|
|
95
|
-
|
|
96
|
-
...
|
|
116
|
+
networkKeyBytes.length,
|
|
117
|
+
...networkKeyBytes,
|
|
97
118
|
];
|
|
98
119
|
|
|
99
120
|
// build credential TLV
|
|
@@ -112,3 +133,5 @@ module.exports = {
|
|
|
112
133
|
decodePayload: decode,
|
|
113
134
|
authTypes: AUTH_TYPES,
|
|
114
135
|
};
|
|
136
|
+
|
|
137
|
+
export {};
|
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
const util = require('./util');
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
type Byte = number;
|
|
4
|
+
type ByteArray = Byte[];
|
|
5
|
+
|
|
6
|
+
type TnfHeader = {
|
|
7
|
+
mb: boolean;
|
|
8
|
+
me: boolean;
|
|
9
|
+
cf: boolean;
|
|
10
|
+
sr: boolean;
|
|
11
|
+
il: boolean;
|
|
12
|
+
tnf: number;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type NdefRecord = {
|
|
16
|
+
tnf: number;
|
|
17
|
+
type: string | ByteArray;
|
|
18
|
+
id: ByteArray;
|
|
19
|
+
payload: ByteArray;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function createNdefRecord(
|
|
23
|
+
tnf: number,
|
|
24
|
+
type: string | ByteArray,
|
|
25
|
+
id: string | ByteArray,
|
|
26
|
+
payload: string | ByteArray,
|
|
27
|
+
): NdefRecord {
|
|
4
28
|
if (
|
|
5
29
|
tnf === undefined ||
|
|
6
30
|
type === undefined ||
|
|
@@ -25,16 +49,19 @@ function createNdefRecord(tnf, type, id, payload) {
|
|
|
25
49
|
payload = util.stringToBytes(payload);
|
|
26
50
|
}
|
|
27
51
|
|
|
52
|
+
const idBytes = id as ByteArray;
|
|
53
|
+
const payloadBytes = payload as ByteArray;
|
|
54
|
+
|
|
28
55
|
return {
|
|
29
|
-
tnf
|
|
30
|
-
type
|
|
31
|
-
id:
|
|
32
|
-
payload:
|
|
56
|
+
tnf,
|
|
57
|
+
type,
|
|
58
|
+
id: idBytes,
|
|
59
|
+
payload: payloadBytes,
|
|
33
60
|
};
|
|
34
61
|
}
|
|
35
62
|
|
|
36
|
-
function encodeNdefMessage(ndefRecords) {
|
|
37
|
-
const encodeTnf = ({mb, me, cf, sr, il, tnf}) => {
|
|
63
|
+
function encodeNdefMessage(ndefRecords: NdefRecord[]): ByteArray {
|
|
64
|
+
const encodeTnf = ({mb, me, cf, sr, il, tnf}: TnfHeader): number => {
|
|
38
65
|
let value = tnf;
|
|
39
66
|
|
|
40
67
|
if (mb) {
|
|
@@ -114,8 +141,8 @@ function encodeNdefMessage(ndefRecords) {
|
|
|
114
141
|
return encoded;
|
|
115
142
|
}
|
|
116
143
|
|
|
117
|
-
function decodeNdefMessage(ndefBytes) {
|
|
118
|
-
const decodeTnf = (tnf_byte) => ({
|
|
144
|
+
function decodeNdefMessage(ndefBytes: ByteArray | Uint8Array): NdefRecord[] {
|
|
145
|
+
const decodeTnf = (tnf_byte: number): TnfHeader => ({
|
|
119
146
|
mb: (tnf_byte & 0x80) !== 0,
|
|
120
147
|
me: (tnf_byte & 0x40) !== 0,
|
|
121
148
|
cf: (tnf_byte & 0x20) !== 0,
|
|
@@ -124,18 +151,17 @@ function decodeNdefMessage(ndefBytes) {
|
|
|
124
151
|
tnf: tnf_byte & 0x7,
|
|
125
152
|
});
|
|
126
153
|
|
|
127
|
-
//
|
|
128
|
-
let bytes;
|
|
129
|
-
if (ndefBytes instanceof
|
|
130
|
-
bytes =
|
|
154
|
+
// Buffer extends Uint8Array; copy only the supplied view before parsing.
|
|
155
|
+
let bytes: ByteArray;
|
|
156
|
+
if (Array.isArray(ndefBytes) || ndefBytes instanceof Uint8Array) {
|
|
157
|
+
bytes = Array.from(ndefBytes);
|
|
131
158
|
} else {
|
|
132
159
|
throw new Error(
|
|
133
|
-
'ndef.decodeMessage requires a Buffer or an Array of bytes',
|
|
160
|
+
'ndef.decodeMessage requires a Buffer, Uint8Array, or an Array of bytes',
|
|
134
161
|
);
|
|
135
162
|
}
|
|
136
163
|
|
|
137
|
-
|
|
138
|
-
let ndef_message = [],
|
|
164
|
+
let ndef_message: NdefRecord[] = [],
|
|
139
165
|
tnf_byte,
|
|
140
166
|
header,
|
|
141
167
|
type_length = 0,
|
|
@@ -146,23 +172,23 @@ function decodeNdefMessage(ndefBytes) {
|
|
|
146
172
|
payload = [];
|
|
147
173
|
|
|
148
174
|
while (bytes.length) {
|
|
149
|
-
tnf_byte = bytes.shift();
|
|
175
|
+
tnf_byte = bytes.shift() as number;
|
|
150
176
|
header = decodeTnf(tnf_byte);
|
|
151
177
|
|
|
152
|
-
type_length = bytes.shift();
|
|
178
|
+
type_length = bytes.shift() as number;
|
|
153
179
|
|
|
154
180
|
if (header.sr) {
|
|
155
|
-
payload_length = bytes.shift();
|
|
181
|
+
payload_length = bytes.shift() as number;
|
|
156
182
|
} else {
|
|
157
183
|
// next 4 bytes are length
|
|
158
184
|
payload_length =
|
|
159
|
-
((0xff & bytes.shift()) << 24) |
|
|
160
|
-
((0xff & bytes.shift()) << 16) |
|
|
161
|
-
((0xff & bytes.shift()) << 8) |
|
|
162
|
-
(0xff & bytes.shift());
|
|
185
|
+
((0xff & (bytes.shift() as number)) << 24) |
|
|
186
|
+
((0xff & (bytes.shift() as number)) << 16) |
|
|
187
|
+
((0xff & (bytes.shift() as number)) << 8) |
|
|
188
|
+
(0xff & (bytes.shift() as number));
|
|
163
189
|
}
|
|
164
190
|
|
|
165
|
-
id_length = header.il ? bytes.shift() : 0;
|
|
191
|
+
id_length = header.il ? (bytes.shift() as number) : 0;
|
|
166
192
|
|
|
167
193
|
record_type = bytes.splice(0, type_length);
|
|
168
194
|
id = bytes.splice(0, id_length);
|
|
@@ -178,7 +204,7 @@ function decodeNdefMessage(ndefBytes) {
|
|
|
178
204
|
return ndef_message;
|
|
179
205
|
}
|
|
180
206
|
|
|
181
|
-
function equalToRecordType(record, tnf, type) {
|
|
207
|
+
function equalToRecordType(record: NdefRecord, tnf: number, type: string): boolean {
|
|
182
208
|
if (record.tnf === tnf) {
|
|
183
209
|
if (Array.isArray(record.type)) {
|
|
184
210
|
return util.bytesToString(record.type) === type;
|
|
@@ -195,3 +221,5 @@ module.exports = {
|
|
|
195
221
|
decodeNdefMessage,
|
|
196
222
|
equalToRecordType,
|
|
197
223
|
};
|
|
224
|
+
|
|
225
|
+
export {};
|
|
@@ -1,19 +1,34 @@
|
|
|
1
1
|
const ndef = require('./ndef');
|
|
2
2
|
const constants = require('./constants');
|
|
3
3
|
|
|
4
|
+
type Byte = number;
|
|
5
|
+
type ByteArray = Byte[];
|
|
6
|
+
|
|
7
|
+
type NdefRecord = {
|
|
8
|
+
tnf: number;
|
|
9
|
+
type: string | ByteArray;
|
|
10
|
+
payload: ByteArray;
|
|
11
|
+
id?: ByteArray;
|
|
12
|
+
};
|
|
13
|
+
|
|
4
14
|
// Convert NDEF records and messages to strings
|
|
5
15
|
// This works OK for demos, but real code proably needs
|
|
6
16
|
// a custom implementation. It would be nice to make
|
|
7
17
|
// smarter record objects that can print themselves
|
|
8
18
|
let stringifier = {
|
|
9
|
-
stringify: function (data, separator) {
|
|
19
|
+
stringify: function (data: NdefRecord | NdefRecord[] | ByteArray, separator?: string): string {
|
|
10
20
|
if (Array.isArray(data)) {
|
|
21
|
+
const records: NdefRecord[] =
|
|
22
|
+
typeof data[0] === 'number'
|
|
23
|
+
? ndef.decodeMessage(data as ByteArray)
|
|
24
|
+
: (data as NdefRecord[]);
|
|
25
|
+
|
|
11
26
|
if (typeof data[0] === 'number') {
|
|
12
27
|
// guessing this message bytes
|
|
13
|
-
data =
|
|
28
|
+
data = records;
|
|
14
29
|
}
|
|
15
30
|
|
|
16
|
-
return stringifier.printRecords(
|
|
31
|
+
return stringifier.printRecords(records, separator);
|
|
17
32
|
} else {
|
|
18
33
|
return stringifier.printRecord(data, separator);
|
|
19
34
|
}
|
|
@@ -22,7 +37,7 @@ let stringifier = {
|
|
|
22
37
|
// @message - NDEF Message (array of NDEF Records)
|
|
23
38
|
// @separator - line separator, optional, defaults to \n
|
|
24
39
|
// @returns string with NDEF Message
|
|
25
|
-
printRecords: function (message, separator) {
|
|
40
|
+
printRecords: function (message: NdefRecord[], separator?: string) {
|
|
26
41
|
if (!separator) {
|
|
27
42
|
separator = '\n';
|
|
28
43
|
}
|
|
@@ -40,7 +55,7 @@ let stringifier = {
|
|
|
40
55
|
// @record - NDEF Record
|
|
41
56
|
// @separator - line separator, optional, defaults to \n
|
|
42
57
|
// @returns string with NDEF Record
|
|
43
|
-
printRecord: function (record, separator) {
|
|
58
|
+
printRecord: function (record: NdefRecord, separator?: string): string {
|
|
44
59
|
let result = '';
|
|
45
60
|
|
|
46
61
|
if (!separator) {
|
|
@@ -65,7 +80,7 @@ let stringifier = {
|
|
|
65
80
|
case constants.TNF_ABSOLUTE_URI:
|
|
66
81
|
result += 'Absolute URI';
|
|
67
82
|
result += separator;
|
|
68
|
-
result += s(record.type);
|
|
83
|
+
result += s(record.type);
|
|
69
84
|
result += separator;
|
|
70
85
|
result += s(record.payload); // might be binary
|
|
71
86
|
break;
|
|
@@ -86,7 +101,7 @@ let stringifier = {
|
|
|
86
101
|
return result;
|
|
87
102
|
},
|
|
88
103
|
|
|
89
|
-
printWellKnown: function (record, separator) {
|
|
104
|
+
printWellKnown: function (record: NdefRecord, separator?: string): string {
|
|
90
105
|
let result = '';
|
|
91
106
|
|
|
92
107
|
if (record.tnf !== constants.TNF_WELL_KNOWN) {
|
|
@@ -120,8 +135,8 @@ let stringifier = {
|
|
|
120
135
|
return result;
|
|
121
136
|
},
|
|
122
137
|
|
|
123
|
-
tnfToString: function (tnf) {
|
|
124
|
-
let value = tnf;
|
|
138
|
+
tnfToString: function (tnf: number): string | number {
|
|
139
|
+
let value: string | number = tnf;
|
|
125
140
|
|
|
126
141
|
switch (tnf) {
|
|
127
142
|
case constants.TNF_EMPTY:
|
|
@@ -153,7 +168,7 @@ let stringifier = {
|
|
|
153
168
|
},
|
|
154
169
|
};
|
|
155
170
|
|
|
156
|
-
function s(bytes) {
|
|
171
|
+
function s(bytes: string | ByteArray): string {
|
|
157
172
|
if (typeof bytes === 'string') {
|
|
158
173
|
return bytes;
|
|
159
174
|
}
|
|
@@ -164,3 +179,5 @@ function s(bytes) {
|
|
|
164
179
|
}
|
|
165
180
|
|
|
166
181
|
module.exports = stringifier;
|
|
182
|
+
|
|
183
|
+
export {};
|