From 0a3eaafb2bc6b543134d8959928e6fbf47d91a2c Mon Sep 17 00:00:00 2001 From: Santiago Gimeno Date: Wed, 23 Sep 2015 12:41:37 +0200 Subject: [PATCH] src: fix reader disconnection logic - A reader disconnection can't be detected by SCardGetStatusChange in the reader (cardreader.cpp) but by detecting that the reader doesn't appear in the list of readers retrieved in pcsclite.cpp. - The list of readers is now stored in an object where the keys are the names of the readers. When a reader disconnection is detected, the reader is closed triggering the 'end' event. Then the reader is removed from the readers list. --- lib/pcsclite.js | 30 +++++++++++++++++++----------- src/cardreader.cpp | 5 +---- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/lib/pcsclite.js b/lib/pcsclite.js index 2c73df8..dba0be9 100644 --- a/lib/pcsclite.js +++ b/lib/pcsclite.js @@ -20,9 +20,18 @@ var parse_readers_string = function(readers_str) { return readers; }; +/* + * It returns an array with the elements contained in a that aren't contained in b + */ +function diff(a, b) { + return a.filter(function(i) { + return b.indexOf(i) === -1; + }); +}; + module.exports = function() { - var readers = []; + var readers = {}; var p = new PCSCLite(); process.nextTick(function() { p.start(function(err, data) { @@ -32,19 +41,13 @@ module.exports = function() { var names = parse_readers_string(data); - var new_names = readers.length === 0 ? names : names.filter(function(name) { - return readers.every(function(reader) { - return reader.name !== name; - }); - }); - - readers = readers.filter(function(reader) { - return names.indexOf(reader.name) !== -1; - }); + var current_names = Object.keys(readers); + var new_names = diff(names, current_names); + var removed_names = diff(current_names, names); new_names.forEach(function(name) { var r = new CardReader(name); - readers.push(r); + readers[name] = r; r.get_status(function(err, state, atr) { if (err) { return r.emit('error', err); @@ -62,10 +65,15 @@ module.exports = function() { r.on('_end', function() { r.removeAllListeners('status'); r.emit('end'); + delete readers[name]; }); p.emit('reader', r); }); + + removed_names.forEach(function(name) { + readers[name].close(); + }); }); }); diff --git a/src/cardreader.cpp b/src/cardreader.cpp index 028648e..e858808 100644 --- a/src/cardreader.cpp +++ b/src/cardreader.cpp @@ -383,10 +383,7 @@ void CardReader::HandlerFunction(void* arg) { while (keep_watching) { result = SCardGetStatusChange(reader->m_status_card_context, INFINITE, &card_reader_state, 1); - keep_watching = ((result == SCARD_S_SUCCESS) && - (!reader->m_state) && - (!((card_reader_state.dwEventState & SCARD_STATE_UNKNOWN) || - (card_reader_state.dwEventState & SCARD_STATE_UNAVAILABLE)))); + keep_watching = (result == SCARD_S_SUCCESS) && (!reader->m_state); uv_mutex_lock(&reader->m_mutex); if (reader->m_state == 1) {