community-cordova-plugin-nfc 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/FUNDING.yml +2 -0
- package/CHANGES.txt +118 -0
- package/LICENSE.txt +21 -0
- package/README.md +1371 -0
- package/doc/GettingStartedBlackBerry10.md +64 -0
- package/doc/GettingStartedCLI.md +71 -0
- package/doc/GettingStartedPhoneGapBuild.md +77 -0
- package/doc/phonegap_build.png +0 -0
- package/doc/read_tag_1_basic_app.png +0 -0
- package/doc/read_tag_2_dump_tag.png +0 -0
- package/doc/read_tag_3_payload_as_string.png +0 -0
- package/package.json +33 -0
- package/plugin.xml +147 -0
- package/src/android/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java +1020 -0
- package/src/android/src/com/chariotsolutions/nfc/plugin/Util.java +140 -0
- package/src/blackberry10/index.js +148 -0
- package/src/ios/NfcPlugin.h +40 -0
- package/src/ios/NfcPlugin.m +627 -0
- package/src/webworks/build.xml +24 -0
- package/src/webworks/src/com/chariotsolutions/nfc/plugin/NfcPlugin.java +341 -0
- package/src/webworks/src/com/chariotsolutions/nfc/plugin/Util.java +137 -0
- package/src/windows/nfc-plugin.js +285 -0
- package/src/windows-phone-8/Ndef.cs +191 -0
- package/src/windows-phone-8/NfcPlugin.cs +200 -0
- package/tests/package.json +14 -0
- package/tests/plugin.xml +11 -0
- package/tests/tests.js +135 -0
- package/www/phonegap-nfc-blackberry.js +76 -0
- package/www/phonegap-nfc.js +912 -0
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
/* globals: export, module, console, document, ndef, Windows, Uint8Array */
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
var STATUS_NFC_OK = "NFC_OK";
|
|
6
|
+
var STATUS_NO_NFC = "NO_NFC";
|
|
7
|
+
var STATUS_NFC_DISABLED = "NFC_DISABLED";
|
|
8
|
+
// I don't think there is a Windows API to determine if NFC exists
|
|
9
|
+
var STATUS_NO_NFC_OR_NFC_DISABLED = "NO_NFC_OR_NFC_DISABLED";
|
|
10
|
+
var STATUS_NDEF_PUSH_DISABLED = "NDEF_PUSH_DISABLED";
|
|
11
|
+
|
|
12
|
+
var ndefUtils = {
|
|
13
|
+
// convert Uint8Array to []
|
|
14
|
+
toArray: function (bytes) {
|
|
15
|
+
var output = [], i = 0;
|
|
16
|
+
for (; i < bytes.length; i += 1) {
|
|
17
|
+
output.push(bytes[i]);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return output;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
var self = {
|
|
25
|
+
subscribedMessageId: -1,
|
|
26
|
+
publishedMessageId: -1,
|
|
27
|
+
proximityDeviceStatus: STATUS_NO_NFC_OR_NFC_DISABLED,
|
|
28
|
+
listeningForNonNdefTags: false,
|
|
29
|
+
tagEventTimeoutId: -1,
|
|
30
|
+
initializeProximityDevice: function() {
|
|
31
|
+
if (self.proximityDevice) {
|
|
32
|
+
// TODO Is there an API to tell if the user disabled NFC?
|
|
33
|
+
try {
|
|
34
|
+
// KLUDGE this call fails when the user has disabled the device
|
|
35
|
+
var kludge = self.proximityDevice.maxMessageBytes;
|
|
36
|
+
self.proximityDeviceStatus = STATUS_NFC_OK;
|
|
37
|
+
} catch (e) {
|
|
38
|
+
console.log(e);
|
|
39
|
+
self.proximityDeviceStatus = STATUS_NFC_DISABLED;
|
|
40
|
+
}
|
|
41
|
+
return self.proximityDeviceStatus === STATUS_NFC_OK;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// try to get device again because user might have re-enabled the device
|
|
45
|
+
self.proximityDevice = Windows.Networking.Proximity.ProximityDevice.getDefault();
|
|
46
|
+
|
|
47
|
+
// TODO use these events to implement nfc.addTagDiscoveredListener
|
|
48
|
+
if (self.proximityDevice) {
|
|
49
|
+
self.proximityDevice.ondevicearrived = function (eventArgs) {
|
|
50
|
+
console.log("NFC tag detected");
|
|
51
|
+
if (self.listeningForNonNdefTags) {
|
|
52
|
+
// set a timeout so NDEF tags can cancel this event
|
|
53
|
+
// we want one event to mimic the Android behavior
|
|
54
|
+
self.tagEventTimeoutId = setTimeout(self.fireTagEvent, 100);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
self.proximityDevice.ondevicedeparted = function (eventArgs) {
|
|
59
|
+
console.log("NFC tag is gone");
|
|
60
|
+
};
|
|
61
|
+
} else {
|
|
62
|
+
self.proximityDeviceStatus = STATUS_NO_NFC_OR_NFC_DISABLED;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return self.proximityDeviceStatus === STATUS_NFC_OK;
|
|
66
|
+
},
|
|
67
|
+
init: function (success, failure, args) {
|
|
68
|
+
|
|
69
|
+
self.initializeProximityDevice();
|
|
70
|
+
|
|
71
|
+
if (!self.proximityDevice) {
|
|
72
|
+
console.log("WARNING: proximity device is null");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
success();
|
|
76
|
+
},
|
|
77
|
+
registerNdef: function (success, failure, args) {
|
|
78
|
+
console.log("Listening for NFC tags with NDEF messages.");
|
|
79
|
+
|
|
80
|
+
if (!self.initializeProximityDevice()) {
|
|
81
|
+
failure(self.proximityDeviceStatus);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
self.subscribedMessageId = self.proximityDevice.subscribeForMessage("NDEF", self.messageReceivedHandler);
|
|
87
|
+
success();
|
|
88
|
+
} catch (e) {
|
|
89
|
+
console.log(e);
|
|
90
|
+
failure(e);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
removeNdef: function (success, failure, args) {
|
|
94
|
+
|
|
95
|
+
console.log("Removing NDEF Listener");
|
|
96
|
+
|
|
97
|
+
if (!self.initializeProximityDevice()) {
|
|
98
|
+
failure(self.proximityDeviceStatus);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
if (self.subscribedMessageId !== -1) {
|
|
104
|
+
self.proximityDevice.stopSubscribingForMessage(self.subscribedMessageId);
|
|
105
|
+
self.subscribedMessageId = -1;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
success();
|
|
109
|
+
} catch (e) {
|
|
110
|
+
console.log(e);
|
|
111
|
+
failure(e.message);
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
addTagDiscoveredListener: function(success, failure, args) {
|
|
115
|
+
self.listeningForNonNdefTags = true;
|
|
116
|
+
success();
|
|
117
|
+
},
|
|
118
|
+
remoteTagDiscoveredListener: function(success, failure, args) {
|
|
119
|
+
self.listeningForNonNdefTags = false;
|
|
120
|
+
success();
|
|
121
|
+
},
|
|
122
|
+
writeTag: function (success, failure, args) {
|
|
123
|
+
|
|
124
|
+
console.log("Write Tag");
|
|
125
|
+
|
|
126
|
+
if (!self.initializeProximityDevice()) {
|
|
127
|
+
failure(self.proximityDeviceStatus);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
var records = args[0];
|
|
133
|
+
var bytes = ndef.encodeMessage(records);
|
|
134
|
+
|
|
135
|
+
self.stopPublishing();
|
|
136
|
+
|
|
137
|
+
var dataWriter = new Windows.Storage.Streams.DataWriter();
|
|
138
|
+
dataWriter.unicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.utf16LE;
|
|
139
|
+
dataWriter.writeBytes(bytes);
|
|
140
|
+
|
|
141
|
+
self.publishedMessageId = self.proximityDevice.publishBinaryMessage("NDEF:WriteTag",
|
|
142
|
+
dataWriter.detachBuffer(),
|
|
143
|
+
function (sender, messageId) {
|
|
144
|
+
console.log("Successfully wrote message to the NFC tag.");
|
|
145
|
+
self.stopPublishing();
|
|
146
|
+
|
|
147
|
+
success();
|
|
148
|
+
}
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
} catch (e) {
|
|
152
|
+
console.log(e);
|
|
153
|
+
failure(e.message);
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
shareTag: function(success, failure, args) {
|
|
157
|
+
|
|
158
|
+
console.log("Share Tag");
|
|
159
|
+
|
|
160
|
+
if (!self.initializeProximityDevice()) {
|
|
161
|
+
failure(self.proximityDeviceStatus);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
try {
|
|
166
|
+
var records = args[0];
|
|
167
|
+
var bytes = ndef.encodeMessage(records);
|
|
168
|
+
|
|
169
|
+
self.stopPublishing();
|
|
170
|
+
|
|
171
|
+
var dataWriter = new Windows.Storage.Streams.DataWriter();
|
|
172
|
+
dataWriter.unicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.utf16LE;
|
|
173
|
+
dataWriter.writeBytes(bytes);
|
|
174
|
+
|
|
175
|
+
self.publishedMessageId = self.proximityDevice.publishBinaryMessage("NDEF",
|
|
176
|
+
dataWriter.detachBuffer(),
|
|
177
|
+
function (sender, messageId) {
|
|
178
|
+
console.log("Successfully shared message over peer-to-peer.");
|
|
179
|
+
self.stopPublishing();
|
|
180
|
+
|
|
181
|
+
success();
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
} catch (e) {
|
|
185
|
+
console.log(e);
|
|
186
|
+
failure(e.message);
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
unshareTag: function(success, failure, args) {
|
|
190
|
+
console.log("Unshare Tag");
|
|
191
|
+
|
|
192
|
+
if (!self.initializeProximityDevice()) {
|
|
193
|
+
failure(self.proximityDeviceStatus);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
try {
|
|
198
|
+
self.stopPublishing();
|
|
199
|
+
success();
|
|
200
|
+
} catch (e) {
|
|
201
|
+
console.log(e);
|
|
202
|
+
failure(e.message);
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
enabled: function(success, failure, args) {
|
|
206
|
+
self.initializeProximityDevice();
|
|
207
|
+
|
|
208
|
+
if (self.initializeProximityDevice()) {
|
|
209
|
+
success();
|
|
210
|
+
} else {
|
|
211
|
+
failure(self.proximityDeviceStatus);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
},
|
|
215
|
+
showSettings: function(success, failure, args) {
|
|
216
|
+
|
|
217
|
+
// WARNING: this isn't documented, so it might break
|
|
218
|
+
var nfcSettingsUri = "ms-settings-proximity:";
|
|
219
|
+
var uri = new Windows.Foundation.Uri(nfcSettingsUri);
|
|
220
|
+
|
|
221
|
+
Windows.System.Launcher.launchUriAsync(uri).then(
|
|
222
|
+
function (settingsAppeared) {
|
|
223
|
+
if (settingsAppeared) {
|
|
224
|
+
success();
|
|
225
|
+
} else {
|
|
226
|
+
failure();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
);
|
|
230
|
+
},
|
|
231
|
+
stopPublishing: function() {
|
|
232
|
+
if (self.publishedMessageId !== -1) {
|
|
233
|
+
self.proximityDevice.stopPublishingMessage(self.publishedMessageId);
|
|
234
|
+
self.publishedMessageId = -1;
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
messageReceivedHandler: function (sender, message) {
|
|
238
|
+
|
|
239
|
+
// this is an NDEF message so cancel the tag event before it fires
|
|
240
|
+
clearTimeout(self.tagEventTimeoutId);
|
|
241
|
+
|
|
242
|
+
var bytes = new Uint8Array(message.data.length);
|
|
243
|
+
var dataReader = Windows.Storage.Streams.DataReader.fromBuffer(message.data);
|
|
244
|
+
dataReader.readBytes(bytes);
|
|
245
|
+
dataReader.close();
|
|
246
|
+
|
|
247
|
+
var byteArray = ndefUtils.toArray(bytes);
|
|
248
|
+
var ndefMessage = ndef.decodeMessage(byteArray);
|
|
249
|
+
console.log(JSON.stringify(ndefMessage));
|
|
250
|
+
|
|
251
|
+
// on windows, tag only contains the ndef message
|
|
252
|
+
// other platforms have tag data
|
|
253
|
+
var tag = {
|
|
254
|
+
ndefMessage: ndefMessage
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
// fire JavaScript event with NDEF data
|
|
258
|
+
var e = document.createEvent('Events');
|
|
259
|
+
e.initEvent("ndef", true, false);
|
|
260
|
+
e.tag = tag;
|
|
261
|
+
document.dispatchEvent(e);
|
|
262
|
+
},
|
|
263
|
+
fireTagEvent: function() {
|
|
264
|
+
var e = document.createEvent('Events');
|
|
265
|
+
e.initEvent("tag", true, false);
|
|
266
|
+
// unfortunately we don't have any tag metadata
|
|
267
|
+
e.tag = {};
|
|
268
|
+
document.dispatchEvent(e);
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
module.exports = {
|
|
273
|
+
init: self.init,
|
|
274
|
+
registerNdef: self.registerNdef,
|
|
275
|
+
removeNdef: self.removeNdef,
|
|
276
|
+
registerTag: self.addTagDiscoveredListener,
|
|
277
|
+
remoteTag: self.removeTagDiscoveredListener,
|
|
278
|
+
writeTag: self.writeTag,
|
|
279
|
+
shareTag: self.shareTag,
|
|
280
|
+
unshareTag: self.unshareTag,
|
|
281
|
+
enabled: self.enabled,
|
|
282
|
+
showSettings: self.showSettings
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
require("cordova/exec/proxy").add("NfcPlugin", module.exports);
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
using System.Runtime.Serialization;
|
|
2
|
+
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using System.Linq;
|
|
6
|
+
using System.Text;
|
|
7
|
+
using System.Threading.Tasks;
|
|
8
|
+
using System.IO;
|
|
9
|
+
|
|
10
|
+
using System.Runtime.InteropServices.WindowsRuntime;
|
|
11
|
+
using Windows.Storage.Streams;
|
|
12
|
+
|
|
13
|
+
namespace ChariotSolutions.NFC.NDEF
|
|
14
|
+
{
|
|
15
|
+
public class Ndef
|
|
16
|
+
{
|
|
17
|
+
public static List<NdefRecord> parse(byte[] bytes)
|
|
18
|
+
{
|
|
19
|
+
List<NdefRecord> records = new List<NdefRecord>();
|
|
20
|
+
int index = 0;
|
|
21
|
+
|
|
22
|
+
while (index <= bytes.Length)
|
|
23
|
+
{
|
|
24
|
+
byte tnf_byte = bytes[index];
|
|
25
|
+
bool mb = (tnf_byte & 0x80) != 0;
|
|
26
|
+
bool me = (tnf_byte & 0x40) != 0;
|
|
27
|
+
bool cf = (tnf_byte & 0x20) != 0;
|
|
28
|
+
bool sr = (tnf_byte & 0x10) != 0;
|
|
29
|
+
bool il = (tnf_byte & 0x8) != 0;
|
|
30
|
+
int tnf = tnf_byte & 0x7;
|
|
31
|
+
|
|
32
|
+
if (cf)
|
|
33
|
+
{
|
|
34
|
+
// TODO implement me
|
|
35
|
+
throw new IOException("Chunked records are not supported.");
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
index++;
|
|
39
|
+
int typeLength = bytes[index];
|
|
40
|
+
int idLength = 0;
|
|
41
|
+
int payloadLength = 0;
|
|
42
|
+
|
|
43
|
+
if (sr)
|
|
44
|
+
{
|
|
45
|
+
index++;
|
|
46
|
+
payloadLength = bytes[index];
|
|
47
|
+
}
|
|
48
|
+
else
|
|
49
|
+
{
|
|
50
|
+
payloadLength = ((0xFF & bytes[++index]) << 24) |
|
|
51
|
+
((0xFF & bytes[++index]) << 26) |
|
|
52
|
+
((0xFF & bytes[++index]) << 8) |
|
|
53
|
+
(0xFF & bytes[++index]);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (il)
|
|
57
|
+
{
|
|
58
|
+
index++;
|
|
59
|
+
idLength = bytes[index];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
index++;
|
|
63
|
+
IBuffer type = bytes.AsBuffer(index, typeLength);
|
|
64
|
+
index += typeLength;
|
|
65
|
+
|
|
66
|
+
IBuffer id = bytes.AsBuffer(index, idLength);
|
|
67
|
+
index += idLength;
|
|
68
|
+
|
|
69
|
+
IBuffer payload = bytes.AsBuffer(index, payloadLength);
|
|
70
|
+
index += payloadLength;
|
|
71
|
+
|
|
72
|
+
NdefRecord record = new NdefRecord();
|
|
73
|
+
record.tnf = (byte)tnf;
|
|
74
|
+
record.type = typeLength > 0 ? type.ToArray() : new byte[0];
|
|
75
|
+
record.id = idLength > 0 ? id.ToArray() : new byte[0];
|
|
76
|
+
record.payload = payloadLength > 0 ? payload.ToArray() : new byte[0];
|
|
77
|
+
|
|
78
|
+
records.Add(record);
|
|
79
|
+
|
|
80
|
+
if (me) break; // last message
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return records;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
public static byte[] toBytes(NdefRecord[] records)
|
|
87
|
+
{
|
|
88
|
+
MemoryStream encoded = new MemoryStream();
|
|
89
|
+
|
|
90
|
+
for (int i = 0; i < records.Length; i++)
|
|
91
|
+
{
|
|
92
|
+
|
|
93
|
+
bool mb = (i == 0);
|
|
94
|
+
bool me = (i == (records.Length - 1));
|
|
95
|
+
bool cf = false; // TODO
|
|
96
|
+
bool sr = (records[i].payload.Length < 0xFF);
|
|
97
|
+
bool il = (records[i].id.Length > 0);
|
|
98
|
+
|
|
99
|
+
byte tnf_byte = encodeTnf(mb, me, cf, sr, il, records[i].tnf);
|
|
100
|
+
encoded.WriteByte(tnf_byte);
|
|
101
|
+
|
|
102
|
+
int type_length = records[i].type.Length;
|
|
103
|
+
encoded.WriteByte((byte)type_length);
|
|
104
|
+
|
|
105
|
+
int payload_length = records[i].payload.Length;
|
|
106
|
+
if (sr)
|
|
107
|
+
{
|
|
108
|
+
encoded.WriteByte((byte)payload_length);
|
|
109
|
+
}
|
|
110
|
+
else
|
|
111
|
+
{
|
|
112
|
+
// 4 bytes
|
|
113
|
+
encoded.WriteByte((byte)(payload_length >> 24));
|
|
114
|
+
encoded.WriteByte((byte)(payload_length >> 16));
|
|
115
|
+
encoded.WriteByte((byte)(payload_length >> 8));
|
|
116
|
+
encoded.WriteByte((byte)(payload_length & 0xFF));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
int id_length = 0;
|
|
120
|
+
if (il)
|
|
121
|
+
{
|
|
122
|
+
id_length = records[i].id.Length;
|
|
123
|
+
encoded.WriteByte((byte)id_length);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
encoded.Write(records[i].type, 0, type_length);
|
|
127
|
+
if (il)
|
|
128
|
+
{
|
|
129
|
+
encoded.Write(records[i].id, 0, id_length);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
encoded.Write(records[i].payload, 0, payload_length);
|
|
133
|
+
}
|
|
134
|
+
return encoded.ToArray();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static byte encodeTnf(bool mb, bool me, bool cf, bool sr, bool il, byte tnf)
|
|
138
|
+
{
|
|
139
|
+
byte value = tnf;
|
|
140
|
+
|
|
141
|
+
if (mb)
|
|
142
|
+
{
|
|
143
|
+
value = (byte)(value | 0x80);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (me)
|
|
147
|
+
{
|
|
148
|
+
value = (byte)(value | 0x40);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (cf)
|
|
152
|
+
{
|
|
153
|
+
value = (byte)(value | 0x20);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if (sr)
|
|
157
|
+
{
|
|
158
|
+
value = (byte)(value | 0x10);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (il)
|
|
162
|
+
{
|
|
163
|
+
value = (byte)(value | 0x8);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (cf) // check
|
|
167
|
+
{
|
|
168
|
+
if (!(tnf == 0x06 && !mb && !me && !il))
|
|
169
|
+
{
|
|
170
|
+
throw new IOException("When cf is true, mb, me and il must be false and tnf must be 0x6");
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return value;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
[DataContract]
|
|
179
|
+
public class NdefRecord
|
|
180
|
+
{
|
|
181
|
+
[DataMember]
|
|
182
|
+
public byte tnf { get; set; }
|
|
183
|
+
[DataMember]
|
|
184
|
+
public byte[] type { get; set; }
|
|
185
|
+
[DataMember]
|
|
186
|
+
public byte[] id { get; set; }
|
|
187
|
+
[DataMember]
|
|
188
|
+
public byte[] payload { get; set; }
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
using System.Runtime.Serialization;
|
|
2
|
+
using Windows.Networking.Proximity;
|
|
3
|
+
using WPCordovaClassLib.Cordova;
|
|
4
|
+
using WPCordovaClassLib.Cordova.Commands;
|
|
5
|
+
using WPCordovaClassLib.Cordova.JSON;
|
|
6
|
+
|
|
7
|
+
using System.Runtime.InteropServices.WindowsRuntime;
|
|
8
|
+
using Windows.Storage.Streams;
|
|
9
|
+
using System.Diagnostics;
|
|
10
|
+
using System.IO;
|
|
11
|
+
|
|
12
|
+
using System.Collections.Generic;
|
|
13
|
+
using System.Text;
|
|
14
|
+
using System.Collections;
|
|
15
|
+
|
|
16
|
+
using ChariotSolutions.NFC.NDEF;
|
|
17
|
+
|
|
18
|
+
//
|
|
19
|
+
// http://www.nfc-forum.org/specs/spec_list/
|
|
20
|
+
// http://msdn.microsoft.com/en-us/library/windows/apps/br241250.aspx
|
|
21
|
+
//
|
|
22
|
+
|
|
23
|
+
namespace Cordova.Extension.Commands
|
|
24
|
+
{
|
|
25
|
+
class NfcPlugin : BaseCommand
|
|
26
|
+
{
|
|
27
|
+
private ProximityDevice proximityDevice;
|
|
28
|
+
private long subscribedMessageId = -1;
|
|
29
|
+
private long publishedMessageId = -1;
|
|
30
|
+
|
|
31
|
+
public NfcPlugin()
|
|
32
|
+
{
|
|
33
|
+
Debug.WriteLine("Nfc Plugin");
|
|
34
|
+
proximityDevice = ProximityDevice.GetDefault();
|
|
35
|
+
if (proximityDevice == null) // shouldn't happen
|
|
36
|
+
{
|
|
37
|
+
Debug.WriteLine("WARNING: proximity device is null");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public void init(string args)
|
|
42
|
+
{
|
|
43
|
+
// not used for WP8
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// no args
|
|
47
|
+
public void registerNdef(string args)
|
|
48
|
+
{
|
|
49
|
+
Debug.WriteLine("Registering for NDEF");
|
|
50
|
+
|
|
51
|
+
try
|
|
52
|
+
{
|
|
53
|
+
subscribedMessageId = proximityDevice.SubscribeForMessage("NDEF", MessageReceivedHandler);
|
|
54
|
+
DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
|
|
55
|
+
}
|
|
56
|
+
catch (System.Exception e)
|
|
57
|
+
{
|
|
58
|
+
Debug.WriteLine(e);
|
|
59
|
+
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// no args
|
|
64
|
+
public void removeNdef(string args)
|
|
65
|
+
{
|
|
66
|
+
Debug.WriteLine("Removing NDEF");
|
|
67
|
+
|
|
68
|
+
try
|
|
69
|
+
{
|
|
70
|
+
if (subscribedMessageId != -1)
|
|
71
|
+
{
|
|
72
|
+
proximityDevice.StopSubscribingForMessage(subscribedMessageId);
|
|
73
|
+
subscribedMessageId = -1;
|
|
74
|
+
}
|
|
75
|
+
DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
|
|
76
|
+
}
|
|
77
|
+
catch (System.Exception e)
|
|
78
|
+
{
|
|
79
|
+
Debug.WriteLine(e);
|
|
80
|
+
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// args[0] is a NdefMessage, which is a JSON array of NdefRecords
|
|
86
|
+
public void writeTag(string args)
|
|
87
|
+
{
|
|
88
|
+
Debug.WriteLine("Write Tag");
|
|
89
|
+
|
|
90
|
+
try
|
|
91
|
+
{
|
|
92
|
+
string ndefMessage = JsonHelper.Deserialize<string[]>(args)[0];
|
|
93
|
+
NdefRecord[] records = JsonHelper.Deserialize<NdefRecord[]>(ndefMessage);
|
|
94
|
+
byte[] data = Ndef.toBytes(records);
|
|
95
|
+
|
|
96
|
+
stopPublishing();
|
|
97
|
+
publishedMessageId = proximityDevice.PublishBinaryMessage("NDEF:WriteTag", data.AsBuffer(), nfcWriteTagCallback);
|
|
98
|
+
|
|
99
|
+
// send no result now, C# callback will send success after write
|
|
100
|
+
PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
|
|
101
|
+
result.KeepCallback = true;
|
|
102
|
+
DispatchCommandResult(result);
|
|
103
|
+
}
|
|
104
|
+
catch (System.Exception e)
|
|
105
|
+
{
|
|
106
|
+
Debug.WriteLine(e);
|
|
107
|
+
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// args[0] is a NdefMessage, which is a JSON array of NdefRecords
|
|
112
|
+
public void shareTag(string args)
|
|
113
|
+
{
|
|
114
|
+
Debug.WriteLine("Share Tag");
|
|
115
|
+
|
|
116
|
+
try
|
|
117
|
+
{
|
|
118
|
+
string ndefMessage = JsonHelper.Deserialize<string[]>(args)[0];
|
|
119
|
+
NdefRecord[] records = JsonHelper.Deserialize<NdefRecord[]>(ndefMessage);
|
|
120
|
+
byte[] data = Ndef.toBytes(records);
|
|
121
|
+
|
|
122
|
+
stopPublishing();
|
|
123
|
+
publishedMessageId = proximityDevice.PublishBinaryMessage("NDEF", data.AsBuffer());
|
|
124
|
+
DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
|
|
125
|
+
}
|
|
126
|
+
catch (System.Exception e)
|
|
127
|
+
{
|
|
128
|
+
Debug.WriteLine(e);
|
|
129
|
+
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// no args
|
|
134
|
+
public void unshareTag(string args)
|
|
135
|
+
{
|
|
136
|
+
Debug.WriteLine("Unshare Tag");
|
|
137
|
+
|
|
138
|
+
try
|
|
139
|
+
{
|
|
140
|
+
stopPublishing();
|
|
141
|
+
DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
|
|
142
|
+
}
|
|
143
|
+
catch (System.Exception e)
|
|
144
|
+
{
|
|
145
|
+
Debug.WriteLine(e);
|
|
146
|
+
DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, e.Message));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private void stopPublishing()
|
|
151
|
+
{
|
|
152
|
+
if (publishedMessageId != -1)
|
|
153
|
+
{
|
|
154
|
+
proximityDevice.StopPublishingMessage(publishedMessageId);
|
|
155
|
+
publishedMessageId = -1;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// MessageTransmittedHandler called after the message is written to a tag
|
|
160
|
+
private void nfcWriteTagCallback(ProximityDevice sender, long messageId)
|
|
161
|
+
{
|
|
162
|
+
Debug.WriteLine("Successfully wrote message to the NFC tag.");
|
|
163
|
+
|
|
164
|
+
// only write the tag one time
|
|
165
|
+
stopPublishing();
|
|
166
|
+
|
|
167
|
+
DispatchCommandResult(new PluginResult(PluginResult.Status.OK));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private void MessageReceivedHandler(ProximityDevice sender, ProximityMessage message)
|
|
171
|
+
{
|
|
172
|
+
|
|
173
|
+
var bytes = message.Data.ToArray();
|
|
174
|
+
List<NdefRecord> records = Ndef.parse(bytes);
|
|
175
|
+
|
|
176
|
+
NfcTag tag = new NfcTag(records);
|
|
177
|
+
|
|
178
|
+
// calling a global js method to fire an nfc event
|
|
179
|
+
ScriptCallback script = new ScriptCallback("fireNfcTagEvent", new string[] { "ndef", JsonHelper.Serialize(tag) });
|
|
180
|
+
this.InvokeCustomScript(script, false);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
[DataContract]
|
|
184
|
+
public class NfcTag
|
|
185
|
+
{
|
|
186
|
+
public NfcTag()
|
|
187
|
+
{
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
public NfcTag(List<NdefRecord> records)
|
|
191
|
+
{
|
|
192
|
+
ndefMessage = records;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
[DataMember]
|
|
196
|
+
public List<NdefRecord> ndefMessage { get; set; }
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
}
|
|
200
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "com.chariotsolutions.nfc.plugin.tests",
|
|
3
|
+
"version": "0.0.1-dev",
|
|
4
|
+
"description": "Tests for phonegap-nfc",
|
|
5
|
+
"cordova": {
|
|
6
|
+
"id": "phonegap-nfc-tests",
|
|
7
|
+
"platforms": []
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"ecosystem:cordova"
|
|
11
|
+
],
|
|
12
|
+
"author": "Don Coleman <don.coleman@gmail.com>",
|
|
13
|
+
"license": "MIT"
|
|
14
|
+
}
|
package/tests/plugin.xml
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
|
|
2
|
+
xmlns:rim="http://www.blackberry.com/ns/widgets"
|
|
3
|
+
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
4
|
+
id="phonegap-nfc-tests"
|
|
5
|
+
version="0.0.1-dev">
|
|
6
|
+
<name>PhoneGap NFC Plugin Tests</name>
|
|
7
|
+
<license>Apache 2.0</license>
|
|
8
|
+
|
|
9
|
+
<js-module src="tests.js" name="tests">
|
|
10
|
+
</js-module>
|
|
11
|
+
</plugin>
|