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

Control Error in LED Example #13

Closed
riseansmal opened this issue May 16, 2017 · 20 comments
Closed

Control Error in LED Example #13

riseansmal opened this issue May 16, 2017 · 20 comments

Comments

@riseansmal
Copy link

@riseansmal riseansmal commented May 16, 2017

Hey @pokusew,

Thanks for this great package!

I am getting this error when trying to run the led.js example on macOS 10.12.4:

*[master][~/Desktop/nfc-pcsc]$ node -r babel-register examples/led.js 
New reader detected ACS ACR122U
12:38:01 AM info ACS ACR122U  device attached
Setting AID to F222222222
AID parsed [ 242, 34, 34, 34, 34 ]

trying to connect CONNECT_MODE_DIRECT 3
status { state: 18, atr: <Buffer > }
changes 18
card removed
connected { type: 3, protocol: 3 }
<Buffer ff 00 52 00 00>
transmitting control <Buffer ff 00 52 00 00> 2
{ ControlError: An error occurred while transmitting control.
    at reader.control (/Users/risean/Desktop/nfc-pcsc/src/Reader.js:327:20)
    at /Users/risean/Desktop/nfc-pcsc/node_modules/@pokusew/pcsclite/lib/pcsclite.js:169:11
  name: 'ControlError',
  code: 'failure',
  previous: 
   Error: SCardControl error: Transaction failed.(0x80100016)
       at Error (native) }
@pokusew pokusew self-assigned this May 18, 2017
@pokusew
Copy link
Owner

@pokusew pokusew commented May 18, 2017

Hi @therealri,

I think that it caused by the special feature of standard PCSC drivers (in all OSs).

By default standard system PCSC driver doesn't allow to send any commands in direct mode (i.e. without any card present). You can still send LED control commands when a card is present but it is quite useless.

To allow sending control (i.e. escape) commands in direct mode, you have to set a special value in registry (when you are on Windows) or in Info.plist of driver (on macOS and Linux). Here is an article to this problematic, but it is quite old.

I was dealing with this problem too (I am also on macOS and btw using ACR122U too 😄).
So, I figured out the instructions how to enable this feature in macOS (OS X):

You have to set the value of ifdDriverOptions to 0x0001 (the default value is 0x0000 which disables control commands).
Unfortunately, this file is protected by System Integrity Protection (csrutil), so before editing you have to temporary disable it.

So step by step:

  1. disable System Integrity Protection
    1. Boot to Recovery OS by restarting your machine and holding down Command+R shortcut at startup.
    2. Launch Terminal from the Utilities menu.
    3. Enter the following command: csrutil disable
    4. Reboot back to normal OS
    5. (for more info see Apple docs here)
  2. locate driver's Info.plist file at /usr/libexec/SmartCardServices/drivers/ifd-ccid.bundle/Contents/Info.plist (Finder -> Go To Folder or Command-Shift-G)
  3. open Info.plist in your text editor
  4. set the value of ifdDriverOptions to 0x0001 and save the changes
    (now after rebooting the example and other control commands should work as expected)
  5. enable System Integrity Protection (as in step 1 just use csrutil enable)
  6. 🏁 You're done. Control commands should work.

Let me know if you have any problems.

Hope it helps.

@riseansmal
Copy link
Author

@riseansmal riseansmal commented May 27, 2017

Thanks so much @pokusew!

@razorxan
Copy link

@razorxan razorxan commented Oct 7, 2017

any help on how to enable this on win 10 x64?

@m-stilling
Copy link

@m-stilling m-stilling commented Apr 26, 2018

I figured out where to add the DWORD values, but I'm still unable to connect in direct mode. If anyone stumbles upon this and is able to figure it out, please let me know! Here's how to figure out where to add your values:

  1. Open the device manager
  2. Locate your device
  3. Open Properties and go to Details
  4. Find the vlaue for the property Device Instance Path
  5. Add your new DWORD values in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum + the path you got from step 4 as described in http://tech.springcard.com/2013/scardcontrol-linux-and-java/ at "Working with MS’ CCID driver"
  6. Reconnect the device / restart your PC
  7. Check if you can connect in DIRECT mode like in https://github.com/pokusew/nfc-pcsc/blob/master/examples/led.js

The error I get is:

{ ConnectError: An error occurred while connecting.
    at reader.connect (...\node_modules\nfc-pcsc\dist\Reader.js:217:20)
  name: 'ConnectError',
  code: 'failure',
  previous: Error: SCardConnect error: The smart card has been removed, so that further communication is not possible.
(0x80100069) }

Obviously changing port means you have to re-add the values for that entry.

I'm pretty confident this is the right place, but for some reason it just isn't working :/

@hakanpinar
Copy link

@hakanpinar hakanpinar commented Jun 25, 2018

Hey,

I'm also stuck in turning off the buzzer of the ACR122 reader.

Is it possible to turn it off in the code behind?

Anyone who can help me?

@carol-braileanu
Copy link

@carol-braileanu carol-braileanu commented Nov 12, 2018

@mich356c I am having the same issue with an ACR1222L. I tried your solution but it didn't work. Did you manage to find a solution?

@m-stilling
Copy link

@m-stilling m-stilling commented Nov 12, 2018

@carol-braileanu Unfortunately I haven’t

@JohnMcLear
Copy link
Contributor

@JohnMcLear JohnMcLear commented Jan 14, 2019

@pokusew Any docs for how to do this on linux? Debby based.

Edit: Editing the file should work

sudo nano /usr/lib/pcsc/drivers/ifd-ccid.bundle/Contents/Info.plist

Making the change as per above then

sudo reboot

Should do it :)

@IrakliTabagari
Copy link

@IrakliTabagari IrakliTabagari commented Jan 17, 2019

Hi,
Any progress connecting directly on Win 10?

{ ControlError: An error occurred while transmitting control.
at reader.control (C:\Users\Irakli.Tabagari\Desktop\fitness_backend_Geo\node
_modules\nfc-pcsc\dist\Reader.js:260:25)
at C:\Users\Irakli.Tabagari\Desktop\fitness_backend_Geo\node_modules@pokuse
w\pcsclite\lib\pcsclite.js:170:11
name: 'ControlError',
code: 'failure',
previous: Error: SCardControl error: Incorrect function.
(0x00000001) }

@GCBenlloch
Copy link

@GCBenlloch GCBenlloch commented Feb 25, 2019

Any update on windows 10? I'm getting:

{ ConnectError: An error occurred while connecting.
    at reader.connect (C:\Users\Gonzalo\Desktop\nfc-reader\node_modules\nfc-pcsc\dist\Reader.js:195:25)
  name: 'ConnectError',
  code: 'failure',
  previous: Error: SCardConnect error: Se ha quitado la tarjeta inteligente, por lo que ya no ser� posible la comunicaci�n.
(0x80100069) }

@Ionut-Milas
Copy link

@Ionut-Milas Ionut-Milas commented Feb 28, 2019

@carol-braileanu Any luck ?

@NAsejevs
Copy link

@NAsejevs NAsejevs commented Mar 16, 2019

I figured out where to add the DWORD values, but I'm still unable to connect in direct mode. If anyone stumbles upon this and is able to figure it out, please let me know! Here's how to figure out where to add your values:

  1. Open the device manager
  2. Locate your device
  3. Open Properties and go to Details
  4. Find the vlaue for the property Device Instance Path
  5. Add your new DWORD values in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum + the path you got from step 4 as described in http://tech.springcard.com/2013/scardcontrol-linux-and-java/ at "Working with MS’ CCID driver"
  6. Reconnect the device / restart your PC
  7. Check if you can connect in DIRECT mode like in https://github.com/pokusew/nfc-pcsc/blob/master/examples/led.js

The error I get is:

{ ConnectError: An error occurred while connecting.
    at reader.connect (...\node_modules\nfc-pcsc\dist\Reader.js:217:20)
  name: 'ConnectError',
  code: 'failure',
  previous: Error: SCardConnect error: The smart card has been removed, so that further communication is not possible.
(0x80100069) }

Obviously changing port means you have to re-add the values for that entry.

I'm pretty confident this is the right place, but for some reason it just isn't working :/

No luck here either. The problem (I think) lies in the manufacturer's driver itself. I was not able to disable the buzzer or the LEDs on Windows 10 even when using the provided ACR122UTool which is made by the same people that made the ACR122U reader/writer. Upon disabling the buzzer and applying changes, the reader responds with a "success" message, but the buzzer doesn't actually turn off.

I tried using older driver versions as well to no avail.

I was able to connect and disable the buzzer and manipulate the LEDs on Linux though (Raspberry Pi 3 using Raspbian).

Might be worth checking if this is possible on Windows 7 or even message the manufacturer to see if they have any suggestions. I'll get back with any more info.

@carol-braileanu
Copy link

@carol-braileanu carol-braileanu commented May 10, 2019

Any new info on this? :/

@doppioandante
Copy link

@doppioandante doppioandante commented Jul 17, 2019

Hello, I'm trying to disable the buzzer with the ACR122U on ubuntu.
I've modified the Info.plist as shown above, but the control operation still fails.

Sending the turn-off ADPU when a card is placed on the reader works but it will beep when the card is detected for the first time. Any idea?

@kvasdopil
Copy link

@kvasdopil kvasdopil commented Mar 20, 2020

Looks like it is possible to disable the speaker when using @pokesuw/pcslite library directly.

const connect = reader => new Promise((resolve, reject) =>
  reader.connect(
    { share_mode: reader.SCARD_SHARE_SHARED },
    (err, protocol) => err ? reject(err) : resolve(protocol)
  )
);
const send = (reader, data, protocol) => new Promise((resolve, reject) =>
  reader.transmit(
    Buffer.from(data),
    40, protocol,
    (err, data) => err ? reject(err) : resolve(data)
  )
);

const pcsc = pcsclite();
pcsc.on('reader', (reader) => {
  reader.on('status', async (status) => {
    // status changed to 'present'
    if (!(reader.state & reader.SCARD_STATE_PRESENT) && (status.state & reader.SCARD_STATE_PRESENT)) {
      try {
        const protocol = await connect(reader);
        const result = await send(reader, [0xFF, 0xCA, 0x00, 0x00, 0x00], protocol); // read id
        await send(reader, [0xFF, 0x00, 0x52, 0x00, 0x00], protocol); // mute speaker
        console.log("card present", result.subarray(0, result.length - 2).toString('hex'));
      } catch (e) {
        console.error('cannot read data', reader.name, e);
      }
    }
  });
});

@aximut
Copy link

@aximut aximut commented Aug 26, 2020

For me, the control commands do not work at all and a quick fix seems to be sending everything as a transmit command.
Then, the LED and buzzer control works at least while a card is present.

this.nfc.on('reader', async reader => {
  reader.control = reader.transmit;
  ...

  reader.on('card', async card => {
    await reader.led(0b01011101, [0x02, 0x01, 0x05, 0x01]);

UPDATE
The final fix on Windows was to change the following in the node module, file Reader.js:

this.reader.connect({
        share_mode: modes[mode]
      }

to

this.reader.connect({
        share_mode: modes[mode],
        protocol: (mode === CONNECT_MODE_DIRECT) ? 0 : this.reader.SCARD_PROTOCOL_UNDEFINED
      }

And in pcsclite change in cardreader.h
#define IOCTL_CCID_ESCAPE (0x42000000 + 3500)
to
#define IOCTL_CCID_ESCAPE (0x003136B0)
and run yarn to rebuild.

Maybe they released a new hardware version and by that the escape command changed?!

@AdamMcCormick
Copy link

@AdamMcCormick AdamMcCormick commented Aug 29, 2020

@aximut has the key solution but it's easier than they outline. I extracted the logic of Reader.js (https://github.com/pokusew/nfc-pcsc/blob/master/src/Reader.js#L215) into my own code and called reader.control directly. Using protocol 0 and 0x003136B0 instead of the constant value it works! How on earth did you discover that value?

@aximut
Copy link

@aximut aximut commented Aug 29, 2020

@aximut has the key solution but it's easier than they outline. I extracted the logic of Reader.js (https://github.com/pokusew/nfc-pcsc/blob/master/src/Reader.js#L215) into my own code and called reader.control directly. Using protocol 0 and 0x003136B0 instead of the constant value it works! How on earth did you discover that value?

@AdamMcCormick ACS included it in their card reader tool.

grafik

Nevertheless, they were lazy enough to not update their API docs and made me drain some hours on this.

Meanwhile, I did some other hacky improvements on this, e. g. do a repeated connect attempt in case it fails once, because if you reconnect to the card shortly after disconnecting from direct mode, it will fail undeterministically. I work with a lot of APIs, but this hardware and/or the Windows driver stack is really crap and a pain for developers, I would not want to be the one responsible for it.
I just wanted to make it work with my time management software and now the days pass on getting this "popular" reader to work as it is supposed to.

@marcin-chwedczuk
Copy link

@marcin-chwedczuk marcin-chwedczuk commented Apr 23, 2021

@pokusew workaround no longer works on Big Sur in which the system volume is mounted read only.

Related: https://apple.stackexchange.com/questions/395508/can-i-mount-the-root-system-filesystem-as-writable-in-big-sur

I asked on Apple Developers: https://developer.apple.com/forums/thread/678700 Maybe they will help...

@bra1nDump
Copy link

@bra1nDump bra1nDump commented Oct 6, 2021

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