UNPKG

node-red-contrib-apdu2pcsc

Version:

A simple node for node-red to send apdu to rfid and smartcards

132 lines (113 loc) 3.31 kB
module.exports = function(RED) { function Apdu2Pcsc(config) { // get pcsclite const pcsclite = require('pcsclite'); const pcsc = pcsclite(); RED.nodes.createNode(this,config); var node = this; var pcscReader; var readerProtocol; // on input message arrives this.on('input', function(msg) { console.log('input msg arrived: ', msg.payload); if(msg.payload == 'card removed') { console.log('card removal detected'); return; } var buffer = new Buffer(new Uint8Array(msg.payload.length / 2)); for(var i = 0; i < msg.payload.length; i+=2) { if(isNaN(parseInt(msg.payload.substr(i, 2), 16))) { console.log('ignoring none apdu'); return; } buffer[i / 2] = (parseInt(msg.payload.substr(i, 2), 16)); } var debugString = ""; for(var i = 0; i < buffer.length; i++) { debugString = debugString.concat(buffer[i].toString(16)); } console.log('sending apdu to chipcard: ', debugString); // input message is APDU as string. Reformat to binary byte array and send to reader. pcscReader.transmit(buffer, 255, readerProtocol, function(err, data) { if (err) { console.log(err); node.send(msg); } else { console.log('Data received', data); var response = ""; for(var i = 0; i < data.length; i++) { response = response.concat(('00' + data[i].toString(16)).substr(-2)); } msg.payload = msg.payload.concat(response); node.send(msg); } }); }); pcsc.on('reader', function(reader) { console.log('New reader detected', reader.name); pcscReader = reader; reader.on('error', function(err) { console.log('Error(', this.name, '):', err.message); }); reader.on('status', function(status) { console.log('Status(', this.name, '):', status); /* check what has changed */ var changes = this.state ^ status.state; if (changes) { if ((changes & this.SCARD_STATE_EMPTY) && (status.state & this.SCARD_STATE_EMPTY)) { console.log("card removed");/* card removed */ reader.disconnect(reader.SCARD_LEAVE_CARD, function(err) { if (err) { console.log(err); var msg = { payload: 'err' }; node.send(msg); } else { console.log('Disconnected'); var msg = { payload: 'card removed' }; node.send(msg); } }); } else if ((changes & this.SCARD_STATE_PRESENT) && (status.state & this.SCARD_STATE_PRESENT)) { console.log("card inserted");/* card inserted */ reader.connect({ share_mode : this.SCARD_SHARE_SHARED }, function(err, protocol) { if (err) { console.log(err); var msg = { payload: 'err' }; node.send(msg); } else { console.log('Protocol(', reader.name, '):', protocol); readerProtocol = protocol; var msg = { payload: 'card inserted' }; node.send(msg); } }); } } }); reader.on('end', function() { console.log('Reader', this.name, 'removed'); }); }); pcsc.on('error', function(err) { console.log('PCSC error', err.message); }); } RED.nodes.registerType("Apdu2Pcsc",Apdu2Pcsc); }