-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrfid_scanner_eos_rpi.js
206 lines (169 loc) · 5.64 KB
/
rfid_scanner_eos_rpi.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
"use strict";
const mfrc522 = require("mfrc522-rpi");
const piezo = require('rpio-rtttl-piezo');
require('log-timestamp');
const { Api, JsonRpc, RpcError } = require ('eosjs');
const { JsSignatureProvider } = require('eosjs/dist/eosjs-jssig');
const fetch = require('node-fetch');
const { TextEncoder, TextDecoder } = require('util');
// Setup the RFID scanner's access to the EOS blockchain.
// A demonstration account is setup to allow RFID scanners to submit
// their scanned tag UID to a blockchain smart contract.
// This account is called "eosiot11node"
// Furthermore, a special permission has been made availble publicly just
// for this project. The permission is called "scan" and it can only submit
// scanned tag data to the "submit" method of the contract on eosiot11rfid.
// The private key to allow this device to use the "scan" permission is
// provided below.
const defaultPrivateKey = "5KfjeKpRzAu3DVsk7iHENozkfaRRthTcpEJsk4jQcBPQopSHtX5";
const signatureProvider = new JsSignatureProvider([defaultPrivateKey]);
//const rpc = new JsonRpc('http://jungle2.cryptolions.io:80', { fetch });
const rpc = new JsonRpc('http://eos.eoscafeblock.com', { fetch });
const api = new Api({ rpc, signatureProvider, textDecoder:new TextDecoder(), textEncoder: new TextEncoder()});
function report_scan(devid, uid, time) {
(async () => {
const result = await api.transact({
actions : [{
account : 'eosiot11rfid',
name : 'submit',
authorization: [{
actor: 'eosiot11node',
permission : 'scan',
}],
data: {
device: 'eosiot11node',
device_id: devid,
node_time: time,
tag_uid : uid,
},
}]
}, {
blocksBehind : 3,
expireSeconds : 30,
});
console.dir(result);
})();
}
// Get a unique 32-bit device identifier
function getUniqueId() {
var uniqueId = 0xCAFEBABE;
var intfs = require('os').networkInterfaces();
var intf = intfs["eth0"];
if (intf == undefined) {
intf = intfs["wlan0"];
}
if (intf != undefined) {
for (var s in intf) {
var mac = intf[s].mac;
//console.log(mac);
if (mac != undefined) {
var smac = mac.split(':');
//console.log(parseInt(smac[0],16), smac[1], smac[2], smac[3], smac[0] << 24);
uniqueId =
(parseInt(smac[0],16) << 24) |
(parseInt(smac[1],16) << 16) |
(parseInt(smac[2],16) << 8) |
(parseInt(smac[3],16));
break;
}
}
} else {
console.log("warning: unique ID could not be generated.");
}
return uniqueId & 0x7FFFFFFF;
}
var UniqueId = getUniqueId();
console.log("Device ID: " + UniqueId + " (0x" + UniqueId.toString(16)+")");
//# Init WiringPi with SPI Channel 0
mfrc522.initWiringPi(0);
// Check connection with the blockchain.
async function print_chain() {
console.log("Blockchain:");
console.log(await rpc.get_info());
}
print_chain();
//# This loop keeps checking for chips. If one is near it will get the UID and authenticate
console.log("scanning...");
console.log("Please put chip or keycard in the antenna inductive zone!");
console.log("Press Ctrl-C to stop.");
function scanSound(type) {
var rtttl = 'scan:d=4,o=6,b=200:';
if (type == 0) {
rtttl += 'g';
} else {
rtttl += 'g,a';
}
piezo.play({
pwmOutputPin: 12,
rtttl: rtttl,
dutyCycle : 8,
});
}
function compare_uid(uid1, uid2) {
if (uid1 == undefined || uid2 == undefined || uid1.length != uid2.length) {
return false;
}
for (var i = 0; i < uid1.length; i++) {
if (uid1[i] != uid2[i]) {
return false;
}
}
return true;
}
var no_card_count = 0;
const no_card_count_limit = 2; // 1 second
var last_scan_uid;
setInterval(function() {
//# reset card
mfrc522.reset();
//# Scan for cards
let response = mfrc522.findCard();
if (!response.status) {
console.log("No Card");
if (++no_card_count == no_card_count_limit) {
// reset the last scanned uid to allow re-scan of the card
last_scan_uid = undefined;
no_card_count = 0;
}
return;
}
// Time of the scan in seconds UTC
var nowTimeSec = Math.floor(new Date().getTime() / 1000);
// Only scan the same tag once. It must be removed for a period of time before
// it can be scanned again. New tags are scanned immediately.
//# Get the UID of the card
response = mfrc522.getUid();
if (!response.status) {
scanSound(1);
console.log("UID Scan Error");
return;
}
const uid = response.data;
if (compare_uid(last_scan_uid, uid)) {
console.log("Multiple scan");
return;
} else {
last_scan_uid = uid;
}
scanSound(0);
console.log("Card detected, CardType: " + response.bitSize);
//# If we have the UID, continue
console.log("Card read UID (%d): %s %s %s %s", uid.length,
uid[0].toString(16), uid[1].toString(16), uid[2].toString(16), uid[3].toString(16));
//# Select the scanned card
const memoryCapacity = mfrc522.selectCard(uid);
console.log("Card Memory Capacity: " + memoryCapacity);
//# This is the default key for authentication
const key = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF];
//# Authenticate on Block 8 with key and uid
if (!mfrc522.authenticate(8, key, uid)) {
console.log("Authentication Error");
return;
}
//# Dump Block 8
console.log("Block: 8 Data: " + mfrc522.getDataForBlock(8));
//# Stop
mfrc522.stopCrypto();
// Transact with blockchain
report_scan(UniqueId, uid, nowTimeSec);
}, 500);