nfc 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,10 @@
1
+ === 2.0.0 / 2009-08-07
2
+
3
+ * 2 major enhancements
4
+
5
+ * Switched from FFI to a C backend
6
+ * Now depends on libnfc 1.2.x
7
+
1
8
  === 1.0.0 / 2009-06-01
2
9
 
3
10
  * 1 major enhancement
data/Manifest.txt CHANGED
@@ -4,6 +4,14 @@ Manifest.txt
4
4
  README.rdoc
5
5
  Rakefile
6
6
  bin/nfc
7
+ ext/nfc/extconf.rb
8
+ ext/nfc/nfc.c
9
+ ext/nfc/nfc.h
10
+ ext/nfc/nfc_device.c
11
+ ext/nfc/nfc_device.h
12
+ ext/nfc/nfc_iso14443a.c
13
+ ext/nfc/nfc_iso14443a.h
7
14
  lib/nfc.rb
8
- lib/nfc/lib_nfc.rb
15
+ lib/nfc/device.rb
16
+ lib/nfc/iso14443a.rb
9
17
  test/test_nfc.rb
data/README.rdoc CHANGED
@@ -10,26 +10,50 @@ lets you read RFID tags.
10
10
 
11
11
  == FEATURES/PROBLEMS:
12
12
 
13
- * Only supports ISO1443A tags (MIFARE) tags right now.
13
+ * Only supports ISO1443A (MIFARE) tags right now.
14
14
 
15
15
  == SYNOPSIS:
16
16
 
17
17
  require 'nfc'
18
18
 
19
- # Read your tag and print the info
19
+ # Read your tag and print the info.
20
20
  p NFC.instance.find
21
21
 
22
+ # NFC#find will return immidiately, which means you should have a tag
23
+ # sitting on the reader when running it. If you'd like it to block until
24
+ # it detects a tag, give find a block like so:
25
+
26
+ NFC.instance.find do |tag|
27
+ p tag
28
+ end
29
+
30
+ # You can even run in an infinite loop if you'd like to continually find
31
+ # tags:
32
+
33
+ loop do
34
+ NFC.instance.find do |tag|
35
+ p tag
36
+ end
37
+ end
38
+
22
39
  == REQUIREMENTS:
23
40
 
24
41
  * A USB RFID reader. I'm using the touchatag[http://touchatag.com].
25
- * ffi
26
42
  * libnfc
27
43
 
28
44
  == INSTALL:
29
45
 
30
- * First install libnfc[http://libnfc.org/]
31
- * Make sure libnfc.dylib or libnfc.so is in your library path
32
- * gem install nfc
46
+ First install libnfc[http://libnfc.org/]
47
+ I installed libnfc like this:
48
+
49
+ $ ./configure --prefix=/usr/local
50
+ $ make && make install
51
+
52
+ The install the gem:
53
+
54
+ $ sudo gem install nfc
55
+
56
+ NOTE!!!! The nfc gem requires libnfc version 1.2.0 or greater!
33
57
 
34
58
  == LICENSE:
35
59
 
data/Rakefile CHANGED
@@ -2,15 +2,20 @@
2
2
 
3
3
  require 'rubygems'
4
4
  require 'hoe'
5
- $: << "lib"
6
- require 'nfc'
5
+ gem 'rake-compiler', '>= 0.4.1'
6
+ require "rake/extensiontask"
7
7
 
8
- Hoe.new('nfc', NFC::VERSION) do |p|
9
- p.developer('Aaron Patterson', 'aaronp@rubyforge.org')
10
- p.readme_file = 'README.rdoc'
11
- p.history_file = 'CHANGELOG.rdoc'
12
- p.extra_rdoc_files = FileList['*.rdoc']
13
- p.extra_deps = ['ffi']
8
+ HOE = Hoe.spec('nfc') do
9
+ developer('Aaron Patterson', 'aaronp@rubyforge.org')
10
+ self.readme_file = 'README.rdoc'
11
+ self.history_file = 'CHANGELOG.rdoc'
12
+ self.extra_rdoc_files = FileList['*.rdoc']
13
+ self.spec_extras = { :extensions => ["ext/nfc/extconf.rb"] }
14
+ self.rubyforge_name = 'seattlerb'
15
+ end
16
+
17
+ RET = Rake::ExtensionTask.new("nfc", HOE.spec) do |ext|
18
+ ext.lib_dir = File.join('lib', 'nfc')
14
19
  end
15
20
 
16
21
  # vim: syntax=Ruby
data/bin/nfc CHANGED
@@ -6,4 +6,6 @@ nfc = NFC.instance
6
6
 
7
7
  puts "Connected to NFC reader: #{nfc.device.name}"
8
8
  puts
9
- p nfc.find
9
+ nfc.find do |tag|
10
+ p tag
11
+ end
@@ -0,0 +1,56 @@
1
+ ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/
2
+
3
+ # :stopdoc:
4
+
5
+ require 'mkmf'
6
+
7
+ LIBDIR = Config::CONFIG['libdir']
8
+ INCLUDEDIR = Config::CONFIG['includedir']
9
+
10
+ $CFLAGS << " -O3 -Wall -Wcast-qual -Wwrite-strings -Wconversion -Wmissing-noreturn -Winline"
11
+
12
+ HEADER_DIRS = [
13
+ # First search /opt/local for macports
14
+ '/opt/local/include',
15
+
16
+ # Then search /usr/local for people that installed from source
17
+ '/usr/local/include',
18
+
19
+ # Check the ruby install locations
20
+ INCLUDEDIR,
21
+
22
+ # Finally fall back to /usr
23
+ '/usr/include',
24
+ ]
25
+
26
+ LIB_DIRS = [
27
+ # First search /opt/local for macports
28
+ '/opt/local/lib',
29
+
30
+ # Then search /usr/local for people that installed from source
31
+ '/usr/local/lib',
32
+
33
+ # Check the ruby install locations
34
+ LIBDIR,
35
+
36
+ # Finally fall back to /usr
37
+ '/usr/lib',
38
+ ]
39
+
40
+ nfc_dirs = dir_config('nfc', '/opt/local/include', '/opt/local/lib')
41
+ unless ["", ""] == nfc_dirs
42
+ HEADER_DIRS.unshift nfc_dirs.first
43
+ LIB_DIRS.unshift nfc_dirs[1]
44
+ end
45
+
46
+ unless find_header('libnfc/libnfc.h', *HEADER_DIRS)
47
+ abort "libnfc is missing. please install libnfc: http://libnfc.org/"
48
+ end
49
+
50
+ unless find_library('nfc', 'nfc_connect', *LIB_DIRS)
51
+ abort "libnfc is missing. please install libnfc: http://libnfc.org/"
52
+ end
53
+
54
+ create_makefile('nfc/nfc')
55
+
56
+ # :startdoc:
data/ext/nfc/nfc.c ADDED
@@ -0,0 +1,11 @@
1
+ #include <nfc.h>
2
+
3
+ VALUE cNfc;
4
+
5
+ void Init_nfc()
6
+ {
7
+ cNfc = rb_define_class("NFC", rb_cObject);
8
+
9
+ init_device();
10
+ init_iso14443a();
11
+ }
data/ext/nfc/nfc.h ADDED
@@ -0,0 +1,12 @@
1
+ #ifndef NFC_H
2
+ #define NFC_H
3
+
4
+ #include <ruby.h>
5
+ #include <libnfc/libnfc.h>
6
+
7
+ extern VALUE cNfc;
8
+
9
+ #include <nfc_device.h>
10
+ #include <nfc_iso14443a.h>
11
+
12
+ #endif
@@ -0,0 +1,111 @@
1
+ #include <nfc_device.h>
2
+
3
+ /*
4
+ * call-seq:
5
+ * connect
6
+ *
7
+ * Connect to the NFC device
8
+ */
9
+ static VALUE connect(VALUE klass)
10
+ {
11
+ dev_info * dev = nfc_connect();
12
+ if(!nfc_initiator_init(dev))
13
+ rb_raise(rb_eRuntimeError, "oh snap, could not init");
14
+
15
+ return Data_Wrap_Struct(klass, 0, 0, dev);
16
+ }
17
+
18
+ /*
19
+ * call-seq:
20
+ * disconnect
21
+ *
22
+ * Disconnect from the NFC device
23
+ */
24
+ static VALUE disconnect(VALUE self)
25
+ {
26
+ dev_info * dev;
27
+ Data_Get_Struct(self, dev_info, dev);
28
+ nfc_disconnect(dev);
29
+
30
+ return self;
31
+ }
32
+
33
+ /*
34
+ * call-seq:
35
+ * configure(option, value)
36
+ *
37
+ * Configure the Device with +option+ and +value+
38
+ */
39
+ static VALUE configure(VALUE self, VALUE option, VALUE flag)
40
+ {
41
+ dev_info * dev;
42
+ Data_Get_Struct(self, dev_info, dev);
43
+
44
+ nfc_configure(
45
+ dev,
46
+ (const dev_config_option)NUM2INT(option),
47
+ (const bool)NUM2INT(flag)
48
+ );
49
+
50
+ return self;
51
+ }
52
+
53
+ /*
54
+ * call-seq:
55
+ * select(tag)
56
+ *
57
+ * Select the +tag+ type from the device
58
+ */
59
+ static VALUE dev_select(VALUE self, VALUE tag)
60
+ {
61
+ dev_info * dev;
62
+ Data_Get_Struct(self, dev_info, dev);
63
+
64
+ tag_info * ti = calloc(1, sizeof(tag_info));
65
+
66
+ nfc_initiator_select_tag(dev, IM_ISO14443A_106, NULL, 0, ti);
67
+
68
+ return Data_Wrap_Struct(cNfcISO14443A, 0, free, ti);
69
+ }
70
+
71
+ /*
72
+ * call-seq:
73
+ * name
74
+ *
75
+ * Get the name of the tag reader
76
+ */
77
+ static VALUE name(VALUE self)
78
+ {
79
+ dev_info * dev;
80
+ Data_Get_Struct(self, dev_info, dev);
81
+
82
+ return rb_str_new2(dev->acName);
83
+ }
84
+
85
+ /*
86
+ * call-seq:
87
+ * deselect
88
+ *
89
+ * Deselect the current tag
90
+ */
91
+ static VALUE dev_deselect(VALUE self)
92
+ {
93
+ dev_info * dev;
94
+ Data_Get_Struct(self, dev_info, dev);
95
+
96
+ nfc_initiator_deselect_tag(dev);
97
+
98
+ return self;
99
+ }
100
+
101
+ void init_device()
102
+ {
103
+ VALUE cNfcDevice = rb_define_class_under(cNfc, "Device", rb_cObject);
104
+
105
+ rb_define_singleton_method(cNfcDevice, "connect", connect, 0);
106
+ rb_define_method(cNfcDevice, "disconnect", disconnect, 0);
107
+ rb_define_method(cNfcDevice, "configure", configure, 2);
108
+ rb_define_method(cNfcDevice, "select", dev_select, 1);
109
+ rb_define_method(cNfcDevice, "deselect", dev_deselect, 0);
110
+ rb_define_method(cNfcDevice, "name", name, 0);
111
+ }
@@ -0,0 +1,8 @@
1
+ #ifndef NFC_DEVICE_H
2
+ #define NFC_DEVICE_H
3
+
4
+ #include <nfc.h>
5
+
6
+ void init_device();
7
+
8
+ #endif
@@ -0,0 +1,100 @@
1
+ #include <nfc_iso14443a.h>
2
+
3
+ VALUE cNfcISO14443A;
4
+
5
+ /*
6
+ * call-seq:
7
+ * uiUidLen
8
+ *
9
+ * Get the uiUidLen
10
+ */
11
+ static VALUE uiUidLen(VALUE self)
12
+ {
13
+ tag_info_iso14443a * tag;
14
+ Data_Get_Struct(self, tag_info_iso14443a, tag);
15
+
16
+ return INT2NUM(tag->uiUidLen);
17
+ }
18
+
19
+ /*
20
+ * call-seq:
21
+ * uiAtsLen
22
+ *
23
+ * Get the uiAtsLen
24
+ */
25
+ static VALUE uiAtsLen(VALUE self)
26
+ {
27
+ tag_info_iso14443a * tag;
28
+ Data_Get_Struct(self, tag_info_iso14443a, tag);
29
+
30
+ return INT2NUM(tag->uiAtsLen);
31
+ }
32
+
33
+ /*
34
+ * call-seq:
35
+ * abtUid
36
+ *
37
+ * Get the abtUid
38
+ */
39
+ static VALUE abtUid(VALUE self)
40
+ {
41
+ tag_info_iso14443a * tag;
42
+ Data_Get_Struct(self, tag_info_iso14443a, tag);
43
+
44
+ return rb_str_new(tag->abtUid, tag->uiUidLen);
45
+ }
46
+
47
+ /*
48
+ * call-seq:
49
+ * abtAts
50
+ *
51
+ * Get the abtAts
52
+ */
53
+ static VALUE abtAts(VALUE self)
54
+ {
55
+ tag_info_iso14443a * tag;
56
+ Data_Get_Struct(self, tag_info_iso14443a, tag);
57
+
58
+ return rb_str_new(tag->abtAts, tag->uiAtsLen);
59
+ }
60
+
61
+ /*
62
+ * call-seq:
63
+ * abtAtqa
64
+ *
65
+ * Get the abtAtqa
66
+ */
67
+ static VALUE abtAtqa(VALUE self)
68
+ {
69
+ tag_info_iso14443a * tag;
70
+ Data_Get_Struct(self, tag_info_iso14443a, tag);
71
+
72
+ return rb_str_new(tag->abtAtqa, 2);
73
+ }
74
+
75
+ /*
76
+ * call-seq:
77
+ * btSak
78
+ *
79
+ * Get the btSak
80
+ */
81
+ static VALUE btSak(VALUE self)
82
+ {
83
+ tag_info_iso14443a * tag;
84
+ Data_Get_Struct(self, tag_info_iso14443a, tag);
85
+
86
+ return INT2NUM(tag->btSak);
87
+ }
88
+
89
+ void init_iso14443a()
90
+ {
91
+ cNfcISO14443A = rb_define_class_under(cNfc, "ISO14443A", rb_cObject);
92
+
93
+ rb_define_method(cNfcISO14443A, "uiUidLen", uiUidLen, 0);
94
+ rb_define_method(cNfcISO14443A, "uiAtsLen", uiAtsLen, 0);
95
+ rb_define_method(cNfcISO14443A, "btSak", btSak, 0);
96
+
97
+ rb_define_private_method(cNfcISO14443A, "abtUid", abtUid, 0);
98
+ rb_define_private_method(cNfcISO14443A, "abtAts", abtAts, 0);
99
+ rb_define_private_method(cNfcISO14443A, "abtAtqa", abtAtqa, 0);
100
+ }
@@ -0,0 +1,10 @@
1
+ #ifndef NFC_ISO14443A
2
+ #define NFC_ISO14443A
3
+
4
+ #include <nfc.h>
5
+
6
+ extern VALUE cNfcISO14443A;
7
+
8
+ void init_iso14443a();
9
+
10
+ #endif
data/lib/nfc.rb CHANGED
@@ -1,60 +1,106 @@
1
1
  require 'singleton'
2
- require 'nfc/lib_nfc'
2
+ require 'thread'
3
+ require 'nfc/nfc'
4
+ require 'nfc/device'
5
+ require 'nfc/iso14443a'
3
6
 
7
+ ###
8
+ # NFC is a class for dealing with Near Field Communication systems. This
9
+ # library will read RFID tags from an RFID reader. You should start by reading
10
+ # NFC#find
4
11
  class NFC
5
- VERSION = '1.0.0'
6
-
7
- attr_reader :device
12
+ VERSION = '2.0.0'
8
13
 
9
14
  include Singleton
10
15
 
16
+ ###
17
+ # Create a new NFC class. This is private, do this instead:
18
+ # NFC.instance
11
19
  def initialize
12
- @device = NFC::LibNFC::Device.new(NFC::LibNFC.nfc_connect)
13
- LibNFC.nfc_reader_init(@device.pointer)
20
+ @device = nil
21
+ @mutex = Mutex.new
14
22
  end
15
23
 
24
+ ###
25
+ # Deactivate the detection field
16
26
  def deactivate_field
17
- LibNFC.nfc_configure @device.pointer, LibNFC::DCO_ACTIVATE_FIELD, 0
27
+ device.configure Device::DCO_ACTIVATE_FIELD, 0
18
28
  end
19
29
 
30
+ ###
31
+ # Activate the detection field
20
32
  def activate_field
21
- LibNFC.nfc_configure @device.pointer, LibNFC::DCO_ACTIVATE_FIELD, 1
33
+ device.configure Device::DCO_ACTIVATE_FIELD, 1
22
34
  end
23
35
 
36
+ ###
37
+ # Do CRC checks
24
38
  def crc= value
25
- LibNFC.nfc_configure @device.pointer, LibNFC::DCO_HANDLE_CRC, value ? 1 : 0
39
+ device.configure Device::DCO_HANDLE_CRC, value ? 1 : 0
26
40
  end
27
41
 
42
+ ###
43
+ # Parity checks
28
44
  def parity= v
29
- LibNFC.nfc_configure @device.pointer, LibNFC::DCO_HANDLE_PARITY, v ? 1 : 0
45
+ device.configure Device::DCO_HANDLE_PARITY, v ? 1 : 0
46
+ end
47
+
48
+ ###
49
+ # Get the device
50
+ def device
51
+ @device ||= NFC::Device.connect
30
52
  end
31
53
 
54
+ ###
55
+ # Block until a passive tag is detected
32
56
  def infinite_list_passive= v
33
- LibNFC.nfc_configure(
34
- @device.pointer,
35
- LibNFC::DCO_INFINITE_LIST_PASSIVE,
36
- v ? 1 : 0
37
- )
57
+ device.configure Device::DCO_INFINITE_LIST_PASSIVE, v ? 1 : 0
58
+ end
59
+
60
+ ###
61
+ # Select a tag
62
+ def select
63
+ device.select Device::IM_ISO14443A_106
38
64
  end
65
+ alias :detect :select
39
66
 
40
- def poll_mifare
41
- thing = LibNFC::ISO1443A.new
42
- LibNFC.nfc_reader_list_passive(
43
- @device.pointer,
44
- LibNFC::IM_ISO14443A_106,
45
- nil,
46
- 0,
47
- thing
48
- )
49
- thing
67
+ ###
68
+ # Deselect a tag
69
+ def deselect
70
+ device.deselect
50
71
  end
51
72
 
73
+ # Read your tag and print the info.
74
+ #
75
+ # p NFC.instance.find
76
+ #
77
+ # NFC#find will return immidiately, which means you should have a tag
78
+ # sitting on the reader when running it. If you'd like it to block until
79
+ # it detects a tag, give find a block like so:
80
+ #
81
+ # NFC.instance.find do |tag|
82
+ # p tag
83
+ # end
84
+ #
85
+ # You can even run in an infinite loop if you'd like to continually find
86
+ # tags:
87
+ #
88
+ # loop do
89
+ # NFC.instance.find do |tag|
90
+ # p tag
91
+ # end
92
+ # end
52
93
  def find
94
+ @mutex.lock
53
95
  deactivate_field
54
- self.infinite_list_passive = false
96
+ self.infinite_list_passive = block_given?
55
97
  self.crc = true
56
98
  self.parity = true
57
99
  activate_field
58
- poll_mifare
100
+ tag = detect
101
+ deselect
102
+ @mutex.unlock
103
+ yield tag if block_given?
104
+ tag
59
105
  end
60
106
  end
data/lib/nfc/device.rb ADDED
@@ -0,0 +1,10 @@
1
+ class NFC
2
+ class Device
3
+ DCO_HANDLE_CRC = 0x00
4
+ DCO_HANDLE_PARITY = 0x01
5
+ DCO_ACTIVATE_FIELD = 0x10
6
+ DCO_INFINITE_LIST_PASSIVE = 0x20
7
+
8
+ IM_ISO14443A_106 = 0x00
9
+ end
10
+ end
@@ -0,0 +1,39 @@
1
+ class NFC
2
+ class ISO14443A
3
+ ###
4
+ # Get the unique ID for this tag
5
+ def uid
6
+ abtUid.unpack 'C*'
7
+ end
8
+
9
+ ###
10
+ # Get the ATS for this tag
11
+ def ats
12
+ abtAts.unpack 'C*'
13
+ end
14
+
15
+ ###
16
+ # Get the atqa
17
+ def atqa
18
+ abtAtqa.unpack 'C*'
19
+ end
20
+
21
+ ###
22
+ # Inspect this tag
23
+ def inspect
24
+ uid = sprintf((['%02x'] * uiUidLen).join(' '), *self.uid)
25
+
26
+ string_ary =
27
+ [ "(NFC) ISO14443A Tag",
28
+ " ATQA (SENS_RES): #{sprintf("%02x %02x", *atqa)}",
29
+ " UID (NFCID1): #{uid}",
30
+ " SAK (SEL_RES): #{sprintf("%02x", btSak)}"
31
+ ]
32
+ if uiAtsLen > 0
33
+ ats = sprintf((['%02x'] * uiAtsLen).join(' '), *self.ats)
34
+ string_ary << " ATS (ATR): #{ats}"
35
+ end
36
+ string_ary.join "\n"
37
+ end
38
+ end
39
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nfc
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
@@ -9,19 +9,9 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-06-01 00:00:00 -07:00
12
+ date: 2009-08-07 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: ffi
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: "0"
24
- version:
25
15
  - !ruby/object:Gem::Dependency
26
16
  name: hoe
27
17
  type: :development
@@ -30,7 +20,7 @@ dependencies:
30
20
  requirements:
31
21
  - - ">="
32
22
  - !ruby/object:Gem::Version
33
- version: 1.12.1
23
+ version: 2.3.2
34
24
  version:
35
25
  description: |-
36
26
  NFC is a ruby wrapper for the Near Field Communication library. The Near
@@ -40,8 +30,8 @@ email:
40
30
  - aaronp@rubyforge.org
41
31
  executables:
42
32
  - nfc
43
- extensions: []
44
-
33
+ extensions:
34
+ - ext/nfc/extconf.rb
45
35
  extra_rdoc_files:
46
36
  - Manifest.txt
47
37
  - CHANGELOG.rdoc
@@ -53,8 +43,16 @@ files:
53
43
  - README.rdoc
54
44
  - Rakefile
55
45
  - bin/nfc
46
+ - ext/nfc/extconf.rb
47
+ - ext/nfc/nfc.c
48
+ - ext/nfc/nfc.h
49
+ - ext/nfc/nfc_device.c
50
+ - ext/nfc/nfc_device.h
51
+ - ext/nfc/nfc_iso14443a.c
52
+ - ext/nfc/nfc_iso14443a.h
56
53
  - lib/nfc.rb
57
- - lib/nfc/lib_nfc.rb
54
+ - lib/nfc/device.rb
55
+ - lib/nfc/iso14443a.rb
58
56
  - test/test_nfc.rb
59
57
  has_rdoc: true
60
58
  homepage: http://seattlerb.rubyforge.org
@@ -66,6 +64,7 @@ rdoc_options:
66
64
  - README.rdoc
67
65
  require_paths:
68
66
  - lib
67
+ - ext
69
68
  required_ruby_version: !ruby/object:Gem::Requirement
70
69
  requirements:
71
70
  - - ">="
@@ -80,8 +79,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
80
79
  version:
81
80
  requirements: []
82
81
 
83
- rubyforge_project: nfc
84
- rubygems_version: 1.3.3
82
+ rubyforge_project: seattlerb
83
+ rubygems_version: 1.3.4
85
84
  signing_key:
86
85
  specification_version: 3
87
86
  summary: NFC is a ruby wrapper for the Near Field Communication library
data/lib/nfc/lib_nfc.rb DELETED
@@ -1,66 +0,0 @@
1
- require 'ffi'
2
-
3
- class NFC
4
- class LibNFC
5
- extend FFI::Library
6
- ffi_lib 'nfc'
7
-
8
- attach_function :nfc_connect, [], :pointer
9
- attach_function :nfc_disconnect, [:pointer], :void
10
- attach_function :nfc_reader_init, [:pointer], :int
11
- attach_function :nfc_configure, [:pointer, :int, :int], :int
12
- attach_function :nfc_reader_list_passive, [:pointer, :int, :pointer, :int, :pointer], :int
13
-
14
- DCO_HANDLE_CRC = 0x00
15
- DCO_HANDLE_PARITY = 0x01
16
- DCO_ACTIVATE_FIELD = 0x10
17
- DCO_INFINITE_LIST_PASSIVE = 0x20
18
-
19
- IM_ISO14443A_106 = 0x00
20
-
21
- class Device < FFI::Struct
22
- layout(:name, [:char, 256])
23
-
24
- def name
25
- pointer.read_string
26
- end
27
-
28
- def self.release ptr
29
- LibNFC.nfc_disconnect ptr
30
- end
31
- end
32
-
33
- class ISO1443A < FFI::Struct
34
- layout(
35
- :abtAtqa, [:uchar, 2],
36
- :btSak, :uchar,
37
- :uiUidLen, :int,
38
- :abtUid, [:uchar, 10],
39
- :uiAtsLen, :int,
40
- :abtAts, [:uchar, 36]
41
- )
42
-
43
- def uid
44
- self[:abtUid].to_a.slice(0, self[:uiUidLen])
45
- end
46
-
47
- def inspect
48
- uid = sprintf((['%02x'] * self[:uiUidLen]).join(' '), *self.uid)
49
-
50
- string_ary =
51
- [ "(NFC) ISO14443A Tag",
52
- " ATQA (SENS_RES): #{sprintf("%02x %02x", *(self[:abtAtqa]))}",
53
- " UID (NFCID1): #{uid}",
54
- " SAK (SEL_RES): #{sprintf("%02x", self[:btSak])}"
55
- ]
56
- if self[:uiAtsLen] > 0
57
- ats =
58
- sprintf((['%02x'] * self[:uiAtsLen]).join(' '), *(self[:abtAts]))
59
- string_ary <<
60
- " ATS (ATR): #{ats}"
61
- end
62
- string_ary.join "\n"
63
- end
64
- end
65
- end
66
- end