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.
This commit is contained in:
Santiago Gimeno
2015-09-23 12:41:37 +02:00
parent 8f3309520d
commit 0a3eaafb2b
2 changed files with 20 additions and 15 deletions

View File

@@ -20,9 +20,18 @@ var parse_readers_string = function(readers_str) {
return readers; 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() { module.exports = function() {
var readers = []; var readers = {};
var p = new PCSCLite(); var p = new PCSCLite();
process.nextTick(function() { process.nextTick(function() {
p.start(function(err, data) { p.start(function(err, data) {
@@ -32,19 +41,13 @@ module.exports = function() {
var names = parse_readers_string(data); var names = parse_readers_string(data);
var new_names = readers.length === 0 ? names : names.filter(function(name) { var current_names = Object.keys(readers);
return readers.every(function(reader) { var new_names = diff(names, current_names);
return reader.name !== name; var removed_names = diff(current_names, names);
});
});
readers = readers.filter(function(reader) {
return names.indexOf(reader.name) !== -1;
});
new_names.forEach(function(name) { new_names.forEach(function(name) {
var r = new CardReader(name); var r = new CardReader(name);
readers.push(r); readers[name] = r;
r.get_status(function(err, state, atr) { r.get_status(function(err, state, atr) {
if (err) { if (err) {
return r.emit('error', err); return r.emit('error', err);
@@ -62,10 +65,15 @@ module.exports = function() {
r.on('_end', function() { r.on('_end', function() {
r.removeAllListeners('status'); r.removeAllListeners('status');
r.emit('end'); r.emit('end');
delete readers[name];
}); });
p.emit('reader', r); p.emit('reader', r);
}); });
removed_names.forEach(function(name) {
readers[name].close();
});
}); });
}); });

View File

@@ -383,10 +383,7 @@ void CardReader::HandlerFunction(void* arg) {
while (keep_watching) { while (keep_watching) {
result = SCardGetStatusChange(reader->m_status_card_context, INFINITE, &card_reader_state, 1); result = SCardGetStatusChange(reader->m_status_card_context, INFINITE, &card_reader_state, 1);
keep_watching = ((result == SCARD_S_SUCCESS) && keep_watching = (result == SCARD_S_SUCCESS) && (!reader->m_state);
(!reader->m_state) &&
(!((card_reader_state.dwEventState & SCARD_STATE_UNKNOWN) ||
(card_reader_state.dwEventState & SCARD_STATE_UNAVAILABLE))));
uv_mutex_lock(&reader->m_mutex); uv_mutex_lock(&reader->m_mutex);
if (reader->m_state == 1) { if (reader->m_state == 1) {