Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement reconnect / SCardReconnect #10

Open
santigimeno opened this issue Aug 6, 2014 · 20 comments
Open

Implement reconnect / SCardReconnect #10

santigimeno opened this issue Aug 6, 2014 · 20 comments

Comments

@santigimeno
Copy link
Owner

No description provided.

@iboxgithub
Copy link

+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

@santigimeno
Copy link
Owner Author

@iboxgithub do you have a sample code explaining your issue?

@iboxgithub
Copy link

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);
    });

@iboxgithub
Copy link

is this example relevant?

@santigimeno
Copy link
Owner Author

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

@iboxgithub
Copy link

Thank you very much !!!
Otherwise (just in case) you don't know about any workaround for that matter?

@santigimeno
Copy link
Owner Author

@iboxgithub WIP implementation here: #34. Could you test it and see if it works for you?
Thanks!

@iboxgithub
Copy link

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.

@santigimeno
Copy link
Owner Author

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

@iboxgithub
Copy link

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

@LudovicRousseau
Copy link
Contributor

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.

@santigimeno
Copy link
Owner Author

@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).

@iboxgithub
Copy link

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);
    });

@iboxgithub
Copy link

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

@santigimeno
Copy link
Owner Author

@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

@iboxgithub
Copy link

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

@iboxgithub
Copy link

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?

@santigimeno
Copy link
Owner Author

@iboxgithub I'm not sure I follow... can you post code that causes the error?

@iboxgithub
Copy link

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).

@santigimeno
Copy link
Owner Author

@iboxgithub That's great news! Thanks for following up the issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants