react-native-nfc-manager 4.0.0-beta.6 → 4.0.0-beta.8
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 +38 -4
- 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 +373 -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 +339 -1125
- 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 +201 -0
- 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 +153 -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 +126 -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 +76 -43
- package/ios/NfcManager.h +2 -10
- package/ios/NfcManager.mm +176 -434
- 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} +49 -20
- package/ndef-lib/{stringifier.js → stringifier.ts} +27 -10
- package/ndef-lib/{util.js → util.ts} +13 -8
- package/package.json +21 -7
- package/react-native-nfc-manager.podspec +3 -2
- package/specs/NativeNfcManager.ts +17 -4
- package/src/NativeNfcManager.ts +84 -0
- package/src/{NfcError.js → NfcError.ts} +6 -17
- package/src/{NfcManager.js → NfcManager.ts} +49 -34
- package/src/{NfcManagerAndroid.js → NfcManagerAndroid.ts} +25 -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.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): 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,
|
|
@@ -125,7 +152,7 @@ function decodeNdefMessage(ndefBytes) {
|
|
|
125
152
|
});
|
|
126
153
|
|
|
127
154
|
// ndefBytes can be an array of bytes e.g. [0x03, 0x31, 0xd1] or a Buffer
|
|
128
|
-
let bytes;
|
|
155
|
+
let bytes: ByteArray;
|
|
129
156
|
if (ndefBytes instanceof Array) {
|
|
130
157
|
bytes = ndefBytes.slice(0);
|
|
131
158
|
} else {
|
|
@@ -135,7 +162,7 @@ function decodeNdefMessage(ndefBytes) {
|
|
|
135
162
|
}
|
|
136
163
|
|
|
137
164
|
bytes = bytes.slice(0); // clone since parsing is destructive
|
|
138
|
-
let ndef_message = [],
|
|
165
|
+
let ndef_message: NdefRecord[] = [],
|
|
139
166
|
tnf_byte,
|
|
140
167
|
header,
|
|
141
168
|
type_length = 0,
|
|
@@ -146,23 +173,23 @@ function decodeNdefMessage(ndefBytes) {
|
|
|
146
173
|
payload = [];
|
|
147
174
|
|
|
148
175
|
while (bytes.length) {
|
|
149
|
-
tnf_byte = bytes.shift();
|
|
176
|
+
tnf_byte = bytes.shift() as number;
|
|
150
177
|
header = decodeTnf(tnf_byte);
|
|
151
178
|
|
|
152
|
-
type_length = bytes.shift();
|
|
179
|
+
type_length = bytes.shift() as number;
|
|
153
180
|
|
|
154
181
|
if (header.sr) {
|
|
155
|
-
payload_length = bytes.shift();
|
|
182
|
+
payload_length = bytes.shift() as number;
|
|
156
183
|
} else {
|
|
157
184
|
// next 4 bytes are length
|
|
158
185
|
payload_length =
|
|
159
|
-
((0xff & bytes.shift()) << 24) |
|
|
160
|
-
((0xff & bytes.shift()) << 16) |
|
|
161
|
-
((0xff & bytes.shift()) << 8) |
|
|
162
|
-
(0xff & bytes.shift());
|
|
186
|
+
((0xff & (bytes.shift() as number)) << 24) |
|
|
187
|
+
((0xff & (bytes.shift() as number)) << 16) |
|
|
188
|
+
((0xff & (bytes.shift() as number)) << 8) |
|
|
189
|
+
(0xff & (bytes.shift() as number));
|
|
163
190
|
}
|
|
164
191
|
|
|
165
|
-
id_length = header.il ? bytes.shift() : 0;
|
|
192
|
+
id_length = header.il ? (bytes.shift() as number) : 0;
|
|
166
193
|
|
|
167
194
|
record_type = bytes.splice(0, type_length);
|
|
168
195
|
id = bytes.splice(0, id_length);
|
|
@@ -178,7 +205,7 @@ function decodeNdefMessage(ndefBytes) {
|
|
|
178
205
|
return ndef_message;
|
|
179
206
|
}
|
|
180
207
|
|
|
181
|
-
function equalToRecordType(record, tnf, type) {
|
|
208
|
+
function equalToRecordType(record: NdefRecord, tnf: number, type: string): boolean {
|
|
182
209
|
if (record.tnf === tnf) {
|
|
183
210
|
if (Array.isArray(record.type)) {
|
|
184
211
|
return util.bytesToString(record.type) === type;
|
|
@@ -195,3 +222,5 @@ module.exports = {
|
|
|
195
222
|
decodeNdefMessage,
|
|
196
223
|
equalToRecordType,
|
|
197
224
|
};
|
|
225
|
+
|
|
226
|
+
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 {};
|