node-pcsclite
node-pcsclite copied to clipboard
Implement reconnect / SCardReconnect
+1 I'm not able to reconnect to the card on the same JS instance. Is there a workaround on that? I have the Sharing violation issue coming back even if I set reader.connect with SCARD_SHARE_SHARED
@iboxgithub do you have a sample code explaining your issue?
Hi, sure
var pcsc = Npm.require('pcsclite'); var pcsc = pcsc(); //todo: change var name ?
pcsc.on('reader', function(reader) {
function exit() {
reader.close();
pcsc.close();
}
console.log('Using card reader: ', reader.name);
reader.connect(/*this.SCARD_SHARE_SHARED,*/function(err, protocol) {
if (err) {
console.log('Connection between middleware and card failed: ' + err);
return exit();
}
//Get length
cmd_1 = new Buffer([0x80, 0x04, 0x00, 0x00, 0x00]);
reader.transmit(cmd_1, 255, protocol, function(err, data) {
if (err) {
console.log(err);
}
else{
console.log('Data received: ', data);
}
return exit();
});
});
reader.on('end', function() {
console.log('***********************************************');
});
});
pcsc.on('error', function(err) {
console.log('PCSC error', err.message);
});
is this example relevant?
I don't know. I'll try to implement the SCardReconnect wrapper as soon as I can if you think it can solve your issues
Thank you very much !!! Otherwise (just in case) you don't know about any workaround for that matter?
@iboxgithub WIP implementation here: https://github.com/santigimeno/node-pcsclite/pull/34. Could you test it and see if it works for you? Thanks!
Hi Santiago, sorry about that but I have no clue how to update your package with your commit on my computer (I used the npm install command at the first time), if you give me quick steps I take care about it right after. Thanks again a lot for your help and concern.
Let me know if this works for you:
# Clone this repo:
$ git clone https://github.com/santigimeno/node-pcsclite.git
$ cd node-pcsclite
# use the scardreconnect branch
$ git checkout -b scardreconnect origin/scardreconnect
# build the module
$ npm install
# run a script
$ node examples/example.js
Hi, excuse me I didn't give feedback I came back home super late. So first, the reconnect works when I put it here
function exit() { reader.close(); reader.reconnect(function(err, protocol) {/my code/} pcsc.close(); }
Now, looking at the pcslite doc there http://pcsclite.alioth.debian.org/pcsc-lite/node13.html
I am trying to find the difference of state of my card when it had ALREADY been connected in order to put the reconnect in a loop but variables like reader.SCARD_SHARE_SHARED or reader.SCARD_RESET_CARD alwys have the same value, do you know which one will say 'the card is locked'? Extra question: is it better to the loop around the reader object or the pcsc object? (just to know if there is no buffer or some stuff like this around, I would like to be able to loop as much as I want)
Thanks for your help, I keep on testing on my side
SCARD_SHARE_SHARED and SCARD_RESET_CARD are orthogonal constant values (they are not variables). One value is for dwShareMode parameter and the other is for dwInitialization parameter.
@iboxgithub I think it's pretty well explained in the documentation. If a command you execute returns SCARD_W_RESET_CARD it's when you should execute reconnect. This can happen, for example, when another application connected to the card disconnects and resets the card using SCARD_RESET_CARD as disposition, and then your application tries to execute a command (transmit for example).
Yes you are right it is straightforward, nevertheless my problem is that in JS I never catch it (0x80100068L), just Sharing violation. (0x8010000b)
I still use the same code (totally pasted from Ludovic Rousseau blog), triggered on a button click from a web interface.
pcsc.on('reader', function(reader) {
function exit() {
reader.close();
pcsc.close();
}
reader.connect(function(err, protocol) {
if (err) {
//A1 todo : SCARD_W_RESET_CARD -> how to catch this var!!!!
if(err == 'Error: SCardConnect error: Sharing violation.(0x8010000b)'){
console.log('Trying to reconnect...');
reader.reconnect(function(err, protocol) {
if (err) {
return exit();
}
else{
cmd_1 = new Buffer([0x80, 0x04, 0x00, 0x00, 0x00]);
//B2 transmit after the reconnect
reader.transmit(cmd_1, 255, protocol, function(err, data) {
if (err) {
return exit();
}else{
console.log('Data received : ', data);
rreturn exit();
}
});
}
});
}
else{ //A1. First connection
return exit();
}
}
else{ //A2. First connection
cmd_1 = new Buffer([0x80, 0x04, 0x00, 0x00, 0x00]);
reader.transmit(cmd_1, 255, protocol, function(err, data) {
if (err) {
return exit();
}
else{
console.log('Data received : ', data);
return exit();
}
});
}
});
reader.on('end', function() {
console.log('Reader', this.name, 'removed');
});
});
pcsc.on('error', function(err) {
console.log('PCSC error', err.message);
});
Despite the fact I am able to make it work within the same pcsc.on bloc, I am not able to create a new bloc and connect again, I will always have a sharing violation. Could this come from dwShareMode that is on Exclusive by default? More general : maybe this is not what Reconnect is supposed to do, so in this case sorry for bothering
@iboxgithub It looks like that. Have you tried using SCARD_SHARE_SHARED mode?
As a side note, I think I should add the actual error code in the Error object
Thanks, I succeeded to do when I wanted with SCARD_SHARE_SHARED set up in the connect function (I tried before but not using the good parameter -_-)
So, in this case there's indeed no need for the Reconnect function, but remains the case where the error SCARD_W_RESET_CARD would be returned. When the error object will be updated with that let me know, I will test it
More generally what are the steps that occured when I restart my server? Because now that I copied this prototype in my real code where several transmit can occur I have an erratic behavior :
- sometimes I am able to get the same value twice in a row (never more, I guess it could be my card reader?)
- sometimes it works if I alternate the different values I try to get (eg: name and surname)
- and EVERYTIME the crash occurs at the second transmit returning "Error: SCardTransmit error: Transaction failed.(0x80100016)"
So the best would be to everytime "simulate" a server restart (from the card reader POV) to have a real reconnection function no? There would be no more need for a share mode, am I missing something by inexperience?
@iboxgithub I'm not sure I follow... can you post code that causes the error?
My apologies, I was not properly handling an error, it is solved now, so no need to take care about my last post.
The Error object returned topic stays on the table (even though not impacting me).
@iboxgithub That's great news! Thanks for following up the issue