hexdigest / ruby-nfc

NFC library for Ruby programming language
MIT License
34 stars 8 forks source link

fix: unknown MIFARE tag error. #5

Closed choongyong closed 7 years ago

choongyong commented 7 years ago

When I run the example script, after fixing it with the change in https://github.com/hexdigest/ruby-nfc/pull/4, I get the following error:

D, [2017-06-29T16:39:12.642460 #2212] DEBUG -- : Library version: libnfc-1.7.1-187-g14f48d0
D, [2017-06-29T16:39:12.644949 #2212] DEBUG -- : Available readers: [#<NFC::Reader:0x1851ca8 @name="acr122_usb:001:007", @ptr=nil>]
/usr/local/rvm/gems/ruby-2.4.0@nfctest/gems/ruby-nfc-1.3/lib/ruby-nfc/tags/mifare/tag.rb:42:in `initialize': Unknown mifare tag (Mifare::Error)
    from /usr/local/rvm/gems/ruby-2.4.0@nfctest/gems/ruby-nfc-1.3/lib/ruby-nfc/tags/mifare/classic.rb:38:in `initialize'
    from /usr/local/rvm/gems/ruby-2.4.0@nfctest/gems/ruby-nfc-1.3/lib/ruby-nfc/reader.rb:65:in `new'
    from /usr/local/rvm/gems/ruby-2.4.0@nfctest/gems/ruby-nfc-1.3/lib/ruby-nfc/reader.rb:65:in `block (3 levels) in poll'
    from /usr/local/rvm/gems/ruby-2.4.0@nfctest/gems/ruby-nfc-1.3/lib/ruby-nfc/reader.rb:63:in `each'
    from /usr/local/rvm/gems/ruby-2.4.0@nfctest/gems/ruby-nfc-1.3/lib/ruby-nfc/reader.rb:63:in `block (2 levels) in poll'
    from /usr/local/rvm/gems/ruby-2.4.0@nfctest/gems/ruby-nfc-1.3/lib/ruby-nfc/reader.rb:57:in `upto'
    from /usr/local/rvm/gems/ruby-2.4.0@nfctest/gems/ruby-nfc-1.3/lib/ruby-nfc/reader.rb:57:in `block in poll'
    from /usr/local/rvm/gems/ruby-2.4.0@nfctest/gems/ruby-nfc-1.3/lib/ruby-nfc/reader.rb:52:in `loop'
    from /usr/local/rvm/gems/ruby-2.4.0@nfctest/gems/ruby-nfc-1.3/lib/ruby-nfc/reader.rb:52:in `poll'
    from reader.rb:15:in `<main>'

After tracing the code, I found that in libfreefare/libfreefare/freefare.c, the method freefare_tag_new is defined as:

freefare_tag_new (nfc_device *device, nfc_target target)

However in `ruby-nfc/lib/tags/mifare/tag.rb, the following is defined:

attach_function :freefare_tag_new, [:pointer, LibNFC::ISO14443a.by_value], :pointer

And the method call is:

@pointer = Mifare.freefare_tag_new(reader.ptr, target[:nti][:nai])

The pointer type defined and pointer type passed in is not what C the code expects. I applied the changes in this PR, and the reader is able to read the cards properly now.

D, [2017-06-29T16:50:46.528022 #2224] DEBUG -- : Library version: libnfc-1.7.1-187-g14f48d0
D, [2017-06-29T16:50:46.530698 #2224] DEBUG -- : Available readers: [#<NFC::Reader:0x1105b90 @name="acr122_usb:001:007", @ptr=nil>]
D, [2017-06-29T16:50:48.417353 #2224] DEBUG -- : Applied Mifare::Classic::Tag: 93c333e3 Mifare Classic 1k SAK: 0x8
D, [2017-06-29T16:50:48.439208 #2224] DEBUG -- : Contents of block 0x04: f4326417358c9f84a5703218a46a18b9
D, [2017-06-29T16:50:48.455867 #2224] DEBUG -- : New value: 5d90abe77bfab41615cfbcca7bdff667
D, [2017-06-29T16:50:55.320939 #2224] DEBUG -- : Applied Mifare::Classic::Tag: 439356e3 Mifare Classic 1k SAK: 0x8
D, [2017-06-29T16:50:55.342727 #2224] DEBUG -- : Contents of block 0x04: 526e27bd7b22e7cf3d5a80b7f6341e88
D, [2017-06-29T16:50:55.359135 #2224] DEBUG -- : New value: 203d449520c98fd1ee74fa39288320ca
hexdigest commented 7 years ago

Hi @choongyong

Thank you for your PR! Where did you get a source code of libfreefare you're using? At the time when I was working on this gem there were few different and incompatible versions of libfreefare. I'm afraid that this change may affect other users of this gem because they may use different version of libfreefare.

choongyong commented 7 years ago

Hi, @hexdigest, I checked out libfreefare from this repository: https://github.com/nfc-tools/libfreefare

hexdigest commented 7 years ago

@choongyong

Here is what I found in libfreefare-dev Ubuntu's package (freefare.h):

struct mifare_tag;
typedef struct mifare_tag *MifareTag;
MifareTag    freefare_tag_new (nfc_device *device, nfc_iso14443a_info nai);

Here is what I found in the repository I pointed out in the documentation: https://github.com/nfc-tools/libfreefare/blob/master/libfreefare/freefare.h:

struct freefare_tag;
typedef struct freefare_tag *FreefareTag;
FreefareTag  freefare_tag_new(nfc_device *device, nfc_target target);

I believe at the point I was writing the documentation everything worked but at since then repositories diverged. Current ruby-nfc implementation works for Ubuntu users but doesn't work for those who install libfreefare from the git repository. I think ubuntu's version of libfreefare is outdated so let me check other functions signatures before I merge this PR.

choongyong commented 7 years ago

@hexdigest Thanks for checking :)

choongyong commented 7 years ago

Thanks!

On 1 Jul 2017, 02:18 +0800, Maxim Chechel notifications@github.com, wrote:

Merged #5. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

hexdigest commented 7 years ago

@choongyong thank you! I also removed reference to Ubuntu's version of libfreefare from the install doc and I'm going to update the gem today.