changeset 1310:68e172d9791e

add missing files for the record Ignore-this: 8541c95ef1644cf85b311259602d2892 darcs-hash:1e575d63deb747c9c320daa32f27f0ce93621afb
author drewp <drewp@bigasterisk.com>
date Sun, 21 Apr 2019 03:28:21 -0700
parents b54164bcded3
children 93ce29b11779
files service/rfid_pn532/Dockerfile.graphserver service/rfid_pn532/Dockerfile.graphserver.pi service/rfid_pn532/ev.nim service/rfid_pn532/freefare_demo.nim service/rfid_pn532/graphserver.py service/rfid_pn532/hashobj.nim service/rfid_pn532/nfc-nim/freefare.nim service/rfid_pn532/nfc-nim/nfc-emulation.h service/rfid_pn532/nfc-nim/nfc-types.h service/rfid_pn532/nfc-nim/nfc.nim service/rfid_pn532/option_test.nim service/rfid_pn532/rdf.nim service/rfid_pn532/rdf_nodes.nim service/rfid_pn532/rdf_test.nim service/rfid_pn532/requirements.txt service/rfid_pn532/rfid.py
diffstat 16 files changed, 2494 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/Dockerfile.graphserver	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,12 @@
+FROM bang6:5000/base_x86
+
+WORKDIR /opt
+
+COPY requirements.txt ./
+RUN pip install -r requirements.txt
+
+COPY *.py *.html *.css *.js ./
+
+EXPOSE 10012:10012
+
+CMD [ "python", "./graphserver.py" ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/Dockerfile.graphserver.pi	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,12 @@
+FROM bang6:5000/base_pi
+
+WORKDIR /opt
+
+COPY requirements.txt ./
+RUN pip install -r requirements.txt
+
+COPY *.py *.html *.css *.js ./
+
+EXPOSE 10012:10012
+
+CMD [ "python", "./graphserver.py" ]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/ev.nim	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,10 @@
+import threadpool
+
+var events1: Channel[int]
+events1.send(1)
+
+proc main():
+  var events2: Channel[int]
+  events2.send(2)
+
+main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/freefare_demo.nim	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,18 @@
+import nfc-nim/nfc, nfc-nim/freefare
+
+var m = freefare.mad_new(0)
+
+echo(freefare.mad_get_version(m))
+
+freefare.mad_free(m)
+var context: ptr nfc.context
+nfc.init(addr context)
+
+var connstrings: array[10, nfc.connstring]
+var n = nfc.list_devices(context, cast[ptr nfc.connstring](addr connstrings), len(connstrings))
+echo(n)
+#var dev = nfc.open(context, "pn532_i2c:/dev/i2c-1")
+#echo(device_get_last_error(dev))
+
+#nfc.close(dev)
+nfc.exit(context)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/graphserver.py	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,34 @@
+import sys, datetime, cyclone.web, json
+from twisted.internet import reactor, task
+from rdflib import Namespace, Literal, ConjunctiveGraph
+import rdflib_jsonld.parser
+from patchablegraph import PatchableGraph, CycloneGraphEventsHandler, CycloneGraphHandler
+
+class CurrentGraph(cyclone.web.RequestHandler):
+    def put(self):
+        g = ConjunctiveGraph()
+        rdflib_jsonld.parser.to_rdf(json.loads(self.request.body), g)
+        self.settings.masterGraph.setToGraph(g)
+
+def main():
+    from twisted.python import log as twlog
+    twlog.startLogging(sys.stderr)
+    masterGraph = PatchableGraph()
+
+    class Application(cyclone.web.Application):
+        def __init__(self):
+            handlers = [
+                (r"/()", cyclone.web.StaticFileHandler,
+                 {"path": ".", "default_filename": "index.html"}),
+                (r'/graph', CycloneGraphHandler, {'masterGraph': masterGraph}),   
+                (r'/graph/events', CycloneGraphEventsHandler, {'masterGraph': masterGraph}),
+                (r'/currentGraph', CurrentGraph),
+            ]
+            cyclone.web.Application.__init__(self, handlers,
+                                             masterGraph=masterGraph)
+
+    reactor.listenTCP(10012, Application())
+    reactor.run()
+
+if __name__ == '__main__':
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/hashobj.nim	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,17 @@
+import sets
+import hashes
+
+type
+  RdfNode* = object of RootObj
+  Uri* = object of RdfNode
+    s2: string
+
+proc initUri*(s: string): Uri =
+  result.s2 = s
+  
+proc hash*(x: Uri): Hash =
+  hash(x.s2)
+
+
+  
+let uris = setOfUris([initUri("x")])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/nfc-nim/freefare.nim	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,893 @@
+const
+  freefareLib* = "libfreefare.so.0.0.0"
+  nfcHeader* = "nfc/nfc.h"
+  freefareHeader* = "freefare.h"
+
+{.deadCodeElim: on.}
+import nfc
+type
+  freefare_tag_type* {.size: sizeof(cint).} = enum
+    FELICA, MIFARE_MINI, MIFARE_CLASSIC_1K, MIFARE_CLASSIC_4K, MIFARE_DESFIRE, ##
+                                                                          ## MIFARE_PLUS_S2K,
+                                                                          ##
+                                                                          ## MIFARE_PLUS_S4K,
+                                                                          ##
+                                                                          ## MIFARE_PLUS_X2K,
+                                                                          ##
+                                                                          ## MIFARE_PLUS_X4K,
+    MIFARE_ULTRALIGHT, MIFARE_ULTRALIGHT_C, NTAG_21x
+
+
+type
+  freefare_tag* {.importc: "struct freefare_tag", header: freefareHeader, bycopy.} = object
+
+  FreefareTag* = ptr freefare_tag
+
+##  Replace any MifareTag by the generic FreefareTag.
+
+type
+  MifareTag* = ptr freefare_tag
+  mifare_desfire_key* {.importc: "struct mifare_desfire_key",
+                       header: freefareHeader, bycopy.} = object
+
+  MifareDESFireKey* = ptr mifare_desfire_key
+  ntag21x_key* {.importc: "struct ntag21x_key", header: freefareHeader, bycopy.} = object
+
+  NTAG21xKey* = ptr ntag21x_key
+  MifareUltralightPageNumber* = uint8
+  MifareUltralightPage* = array[4, cuchar]
+
+proc freefare_get_tags*(device: ptr device): ptr FreefareTag {.cdecl,
+    importc: "freefare_get_tags", dynlib: freefareLib.}
+proc freefare_tag_new*(device: ptr device; target: target): FreefareTag {.cdecl,
+    importc: "freefare_tag_new", dynlib: freefareLib.}
+proc freefare_get_tag_type*(tag: FreefareTag): freefare_tag_type {.cdecl,
+    importc: "freefare_get_tag_type", dynlib: freefareLib.}
+proc freefare_get_tag_friendly_name*(tag: FreefareTag): cstring {.cdecl,
+    importc: "freefare_get_tag_friendly_name", dynlib: freefareLib.}
+proc freefare_get_tag_uid*(tag: FreefareTag): cstring {.cdecl,
+    importc: "freefare_get_tag_uid", dynlib: freefareLib.}
+proc freefare_free_tag*(tag: FreefareTag) {.cdecl, importc: "freefare_free_tag",
+    dynlib: freefareLib.}
+proc freefare_free_tags*(tags: ptr FreefareTag) {.cdecl,
+    importc: "freefare_free_tags", dynlib: freefareLib.}
+proc freefare_selected_tag_is_present*(device: ptr device): bool {.cdecl,
+    importc: "freefare_selected_tag_is_present", dynlib: freefareLib.}
+proc freefare_strerror*(tag: FreefareTag): cstring {.cdecl,
+    importc: "freefare_strerror", dynlib: freefareLib.}
+proc freefare_strerror_r*(tag: FreefareTag; buffer: cstring; len: csize): cint {.cdecl,
+    importc: "freefare_strerror_r", dynlib: freefareLib.}
+proc freefare_perror*(tag: FreefareTag; string: cstring) {.cdecl,
+    importc: "freefare_perror", dynlib: freefareLib.}
+proc felica_taste*(device: ptr device; target: target): bool {.cdecl,
+    importc: "felica_taste", dynlib: freefareLib.}
+const
+  FELICA_SC_RW* = 0x00000009
+  FELICA_SC_RO* = 0x0000000B
+
+proc felica_tag_new*(device: ptr device; target: target): FreefareTag {.cdecl,
+    importc: "felica_tag_new", dynlib: freefareLib.}
+proc felica_tag_free*(tag: FreefareTag) {.cdecl, importc: "felica_tag_free",
+                                       dynlib: freefareLib.}
+proc felica_read*(tag: FreefareTag; service: uint16; `block`: uint8; data: ptr uint8;
+                 length: csize): int32 {.cdecl, importc: "felica_read",
+                                      dynlib: freefareLib.}
+proc felica_read_ex*(tag: FreefareTag; service: uint16; block_count: uint8;
+                    blocks: ptr uint8; data: ptr uint8; length: csize): int32 {.cdecl,
+    importc: "felica_read_ex", dynlib: freefareLib.}
+proc felica_write*(tag: FreefareTag; service: uint16; `block`: uint8; data: ptr uint8;
+                  length: csize): int32 {.cdecl, importc: "felica_write",
+                                       dynlib: freefareLib.}
+proc felica_write_ex*(tag: FreefareTag; service: uint16; block_count: uint8;
+                     blocks: ptr uint8; data: ptr uint8; length: csize): int32 {.cdecl,
+    importc: "felica_write_ex", dynlib: freefareLib.}
+proc mifare_ultralight_taste*(device: ptr device; target: target): bool {.cdecl,
+    importc: "mifare_ultralight_taste", dynlib: freefareLib.}
+proc mifare_ultralightc_taste*(device: ptr device; target: target): bool {.cdecl,
+    importc: "mifare_ultralightc_taste", dynlib: freefareLib.}
+proc mifare_ultralight_tag_new*(device: ptr device; target: target): FreefareTag {.
+    cdecl, importc: "mifare_ultralight_tag_new", dynlib: freefareLib.}
+proc mifare_ultralightc_tag_new*(device: ptr device; target: target): FreefareTag {.
+    cdecl, importc: "mifare_ultralightc_tag_new", dynlib: freefareLib.}
+proc mifare_ultralight_tag_free*(tag: FreefareTag) {.cdecl,
+    importc: "mifare_ultralight_tag_free", dynlib: freefareLib.}
+proc mifare_ultralightc_tag_free*(tag: FreefareTag) {.cdecl,
+    importc: "mifare_ultralightc_tag_free", dynlib: freefareLib.}
+proc mifare_ultralight_connect*(tag: FreefareTag): cint {.cdecl,
+    importc: "mifare_ultralight_connect", dynlib: freefareLib.}
+proc mifare_ultralight_disconnect*(tag: FreefareTag): cint {.cdecl,
+    importc: "mifare_ultralight_disconnect", dynlib: freefareLib.}
+proc mifare_ultralight_read*(tag: FreefareTag; page: MifareUltralightPageNumber;
+                            data: ptr MifareUltralightPage): cint {.cdecl,
+    importc: "mifare_ultralight_read", dynlib: freefareLib.}
+proc mifare_ultralight_write*(tag: FreefareTag; page: MifareUltralightPageNumber;
+                             data: MifareUltralightPage): cint {.cdecl,
+    importc: "mifare_ultralight_write", dynlib: freefareLib.}
+proc mifare_ultralightc_authenticate*(tag: FreefareTag; key: MifareDESFireKey): cint {.
+    cdecl, importc: "mifare_ultralightc_authenticate", dynlib: freefareLib.}
+proc mifare_ultralightc_set_key*(tag: FreefareTag; key: MifareDESFireKey): cint {.
+    cdecl, importc: "mifare_ultralightc_set_key", dynlib: freefareLib.}
+proc is_mifare_ultralight*(tag: FreefareTag): bool {.cdecl,
+    importc: "is_mifare_ultralight", dynlib: freefareLib.}
+proc is_mifare_ultralightc*(tag: FreefareTag): bool {.cdecl,
+    importc: "is_mifare_ultralightc", dynlib: freefareLib.}
+proc is_mifare_ultralightc_on_reader*(device: ptr device; nai: iso14443a_info): bool {.
+    cdecl, importc: "is_mifare_ultralightc_on_reader", dynlib: freefareLib.}
+proc ntag21x_taste*(device: ptr device; target: target): bool {.cdecl,
+    importc: "ntag21x_taste", dynlib: freefareLib.}
+proc ntag21x_last_error*(tag: FreefareTag): uint8 {.cdecl,
+    importc: "ntag21x_last_error", dynlib: freefareLib.}
+##  NTAG21x access features
+
+const
+  NTAG_PROT* = 0x00000080
+  NTAG_CFGLCK* = 0x00000040
+  NTAG_NFC_CNT_EN* = 0x00000020
+  NTAG_NFC_CNT_PWD_PROT* = 0x00000010
+  NTAG_AUTHLIM* = 0x00000007
+
+type
+  ntag_tag_subtype* {.size: sizeof(cint).} = enum
+    NTAG_UNKNOWN, NTAG_213, NTAG_215, NTAG_216
+
+
+proc ntag21x_tag_new*(device: ptr device; target: target): FreefareTag {.cdecl,
+    importc: "ntag21x_tag_new", dynlib: freefareLib.}
+proc ntag21x_tag_reuse*(tag: FreefareTag): FreefareTag {.cdecl,
+    importc: "ntag21x_tag_reuse", dynlib: freefareLib.}
+##  Copy data from Ultralight tag to new NTAG21x, don't forget to free your old tag
+
+proc ntag21x_key_new*(data: array[4, uint8]; pack: array[2, uint8]): NTAG21xKey {.cdecl,
+    importc: "ntag21x_key_new", dynlib: freefareLib.}
+##  Create new key
+
+proc ntag21x_key_free*(key: NTAG21xKey) {.cdecl, importc: "ntag21x_key_free",
+                                       dynlib: freefareLib.}
+##  Clear key from memory
+
+proc ntag21x_tag_free*(tag: FreefareTag) {.cdecl, importc: "ntag21x_tag_free",
+                                        dynlib: freefareLib.}
+proc ntag21x_connect*(tag: FreefareTag): cint {.cdecl, importc: "ntag21x_connect",
+    dynlib: freefareLib.}
+proc ntag21x_disconnect*(tag: FreefareTag): cint {.cdecl,
+    importc: "ntag21x_disconnect", dynlib: freefareLib.}
+proc ntag21x_get_info*(tag: FreefareTag): cint {.cdecl, importc: "ntag21x_get_info",
+    dynlib: freefareLib.}
+##  Get all information about tag (size,vendor ...)
+
+proc ntag21x_get_subtype*(tag: FreefareTag): ntag_tag_subtype {.cdecl,
+    importc: "ntag21x_get_subtype", dynlib: freefareLib.}
+##  Get subtype of tag
+
+proc ntag21x_get_last_page*(tag: FreefareTag): uint8 {.cdecl,
+    importc: "ntag21x_get_last_page", dynlib: freefareLib.}
+##  Get last page address based on gathered info from function above
+
+proc ntag21x_read_signature*(tag: FreefareTag; data: ptr uint8): cint {.cdecl,
+    importc: "ntag21x_read_signature", dynlib: freefareLib.}
+##  Get tag signature
+
+proc ntag21x_set_pwd*(tag: FreefareTag; data: array[4, uint8]): cint {.cdecl,
+    importc: "ntag21x_set_pwd", dynlib: freefareLib.}
+##  Set password
+
+proc ntag21x_set_pack*(tag: FreefareTag; data: array[2, uint8]): cint {.cdecl,
+    importc: "ntag21x_set_pack", dynlib: freefareLib.}
+##  Set pack
+
+proc ntag21x_set_key*(tag: FreefareTag; key: NTAG21xKey): cint {.cdecl,
+    importc: "ntag21x_set_key", dynlib: freefareLib.}
+##  Set key
+
+proc ntag21x_set_auth*(tag: FreefareTag; byte: uint8): cint {.cdecl,
+    importc: "ntag21x_set_auth", dynlib: freefareLib.}
+##  Set AUTH0 byte (from which page starts password protection)
+
+proc ntag21x_get_auth*(tag: FreefareTag; byte: ptr uint8): cint {.cdecl,
+    importc: "ntag21x_get_auth", dynlib: freefareLib.}
+##  Get AUTH0 byte
+
+proc ntag21x_access_enable*(tag: FreefareTag; byte: uint8): cint {.cdecl,
+    importc: "ntag21x_access_enable", dynlib: freefareLib.}
+##  Enable access feature in ACCESS byte
+
+proc ntag21x_access_disable*(tag: FreefareTag; byte: uint8): cint {.cdecl,
+    importc: "ntag21x_access_disable", dynlib: freefareLib.}
+##  Disable access feature in ACCESS byte
+
+proc ntag21x_get_access*(tag: FreefareTag; byte: ptr uint8): cint {.cdecl,
+    importc: "ntag21x_get_access", dynlib: freefareLib.}
+##  Get ACCESS byte
+
+proc ntag21x_check_access*(tag: FreefareTag; byte: uint8; result: ptr bool): cint {.
+    cdecl, importc: "ntag21x_check_access", dynlib: freefareLib.}
+##  Check if access feature is enabled
+
+proc ntag21x_get_authentication_limit*(tag: FreefareTag; byte: ptr uint8): cint {.
+    cdecl, importc: "ntag21x_get_authentication_limit", dynlib: freefareLib.}
+##  Get authentication limit
+
+proc ntag21x_set_authentication_limit*(tag: FreefareTag; byte: uint8): cint {.cdecl,
+    importc: "ntag21x_set_authentication_limit", dynlib: freefareLib.}
+##  Set authentication limit (0x00 = disabled, [0x01,0x07] = valid range, > 0x07 invalid range)
+
+proc ntag21x_read*(tag: FreefareTag; page: uint8; data: ptr uint8): cint {.cdecl,
+    importc: "ntag21x_read", dynlib: freefareLib.}
+##  Read 16 bytes starting from page
+
+proc ntag21x_read4*(tag: FreefareTag; page: uint8; data: ptr uint8): cint {.cdecl,
+    importc: "ntag21x_read4", dynlib: freefareLib.}
+##  Read 4 bytes on page
+
+proc ntag21x_fast_read*(tag: FreefareTag; start_page: uint8; end_page: uint8;
+                       data: ptr uint8): cint {.cdecl, importc: "ntag21x_fast_read",
+    dynlib: freefareLib.}
+##  Read n*4 bytes from range [start_page,end_page]
+
+proc ntag21x_fast_read4*(tag: FreefareTag; page: uint8; data: ptr uint8): cint {.cdecl,
+    importc: "ntag21x_fast_read4", dynlib: freefareLib.}
+##  Fast read certain page
+
+proc ntag21x_read_cnt*(tag: FreefareTag; data: ptr uint8): cint {.cdecl,
+    importc: "ntag21x_read_cnt", dynlib: freefareLib.}
+##  Read 3-byte NFC counter if enabled else it returns error
+
+proc ntag21x_write*(tag: FreefareTag; page: uint8; data: array[4, uint8]): cint {.cdecl,
+    importc: "ntag21x_write", dynlib: freefareLib.}
+##  Write 4 bytes to page
+
+proc ntag21x_compatibility_write*(tag: FreefareTag; page: uint8;
+                                 data: array[4, uint8]): cint {.cdecl,
+    importc: "ntag21x_compatibility_write", dynlib: freefareLib.}
+##  Writes 4 bytes to page with mifare classic write
+
+proc ntag21x_authenticate*(tag: FreefareTag; key: NTAG21xKey): cint {.cdecl,
+    importc: "ntag21x_authenticate", dynlib: freefareLib.}
+##  Authenticate with tag
+
+proc is_ntag21x*(tag: FreefareTag): bool {.cdecl, importc: "is_ntag21x",
+                                       dynlib: freefareLib.}
+##  Check if tag type is NTAG21x
+
+proc ntag21x_is_auth_supported*(device: ptr device; nai: iso14443a_info): bool {.cdecl,
+    importc: "ntag21x_is_auth_supported", dynlib: freefareLib.}
+##  Check if tag supports 21x commands
+
+proc mifare_mini_taste*(device: ptr device; target: target): bool {.cdecl,
+    importc: "mifare_mini_taste", dynlib: freefareLib.}
+proc mifare_classic1k_taste*(device: ptr device; target: target): bool {.cdecl,
+    importc: "mifare_classic1k_taste", dynlib: freefareLib.}
+proc mifare_classic4k_taste*(device: ptr device; target: target): bool {.cdecl,
+    importc: "mifare_classic4k_taste", dynlib: freefareLib.}
+proc mifare_mini_tag_new*(device: ptr device; target: target): FreefareTag {.cdecl,
+    importc: "mifare_mini_tag_new", dynlib: freefareLib.}
+proc mifare_classic1k_tag_new*(device: ptr device; target: target): FreefareTag {.
+    cdecl, importc: "mifare_classic1k_tag_new", dynlib: freefareLib.}
+proc mifare_classic4k_tag_new*(device: ptr device; target: target): FreefareTag {.
+    cdecl, importc: "mifare_classic4k_tag_new", dynlib: freefareLib.}
+proc mifare_classic_tag_free*(tag: FreefareTag) {.cdecl,
+    importc: "mifare_classic_tag_free", dynlib: freefareLib.}
+type
+  MifareClassicBlock* = array[16, cuchar]
+  MifareClassicSectorNumber* = uint8
+  MifareClassicBlockNumber* = cuchar
+  MifareClassicKeyType* {.size: sizeof(cint).} = enum
+    MFC_KEY_A, MFC_KEY_B
+  MifareClassicKey* = array[6, cuchar]
+
+
+##  NFC Forum public key
+
+var mifare_classic_nfcforum_public_key_a* {.
+    importc: "mifare_classic_nfcforum_public_key_a", dynlib: freefareLib.}: MifareClassicKey
+
+proc mifare_classic_connect*(tag: FreefareTag): cint {.cdecl,
+    importc: "mifare_classic_connect", dynlib: freefareLib.}
+proc mifare_classic_disconnect*(tag: FreefareTag): cint {.cdecl,
+    importc: "mifare_classic_disconnect", dynlib: freefareLib.}
+proc mifare_classic_authenticate*(tag: FreefareTag;
+                                 `block`: MifareClassicBlockNumber;
+                                 key: MifareClassicKey;
+                                 key_type: MifareClassicKeyType): cint {.cdecl,
+    importc: "mifare_classic_authenticate", dynlib: freefareLib.}
+proc mifare_classic_read*(tag: FreefareTag; `block`: MifareClassicBlockNumber;
+                         data: ptr MifareClassicBlock): cint {.cdecl,
+    importc: "mifare_classic_read", dynlib: freefareLib.}
+proc mifare_classic_init_value*(tag: FreefareTag;
+                               `block`: MifareClassicBlockNumber; value: int32;
+                               adr: MifareClassicBlockNumber): cint {.cdecl,
+    importc: "mifare_classic_init_value", dynlib: freefareLib.}
+proc mifare_classic_read_value*(tag: FreefareTag;
+                               `block`: MifareClassicBlockNumber;
+                               value: ptr int32; adr: ptr MifareClassicBlockNumber): cint {.
+    cdecl, importc: "mifare_classic_read_value", dynlib: freefareLib.}
+proc mifare_classic_write*(tag: FreefareTag; `block`: MifareClassicBlockNumber;
+                          data: MifareClassicBlock): cint {.cdecl,
+    importc: "mifare_classic_write", dynlib: freefareLib.}
+proc mifare_classic_increment*(tag: FreefareTag; `block`: MifareClassicBlockNumber;
+                              amount: uint32): cint {.cdecl,
+    importc: "mifare_classic_increment", dynlib: freefareLib.}
+proc mifare_classic_decrement*(tag: FreefareTag; `block`: MifareClassicBlockNumber;
+                              amount: uint32): cint {.cdecl,
+    importc: "mifare_classic_decrement", dynlib: freefareLib.}
+proc mifare_classic_restore*(tag: FreefareTag; `block`: MifareClassicBlockNumber): cint {.
+    cdecl, importc: "mifare_classic_restore", dynlib: freefareLib.}
+proc mifare_classic_transfer*(tag: FreefareTag; `block`: MifareClassicBlockNumber): cint {.
+    cdecl, importc: "mifare_classic_transfer", dynlib: freefareLib.}
+proc mifare_classic_get_trailer_block_permission*(tag: FreefareTag;
+    `block`: MifareClassicBlockNumber; permission: uint16;
+    key_type: MifareClassicKeyType): cint {.cdecl,
+    importc: "mifare_classic_get_trailer_block_permission", dynlib: freefareLib.}
+proc mifare_classic_get_data_block_permission*(tag: FreefareTag;
+    `block`: MifareClassicBlockNumber; permission: cuchar;
+    key_type: MifareClassicKeyType): cint {.cdecl,
+    importc: "mifare_classic_get_data_block_permission", dynlib: freefareLib.}
+proc mifare_classic_format_sector*(tag: FreefareTag;
+                                  sector: MifareClassicSectorNumber): cint {.cdecl,
+    importc: "mifare_classic_format_sector", dynlib: freefareLib.}
+proc mifare_classic_trailer_block*(`block`: ptr MifareClassicBlock;
+                                  key_a: MifareClassicKey; ab_0: uint8; ab_1: uint8;
+                                  ab_2: uint8; ab_tb: uint8; gpb: uint8;
+                                  key_b: MifareClassicKey) {.cdecl,
+    importc: "mifare_classic_trailer_block", dynlib: freefareLib.}
+proc mifare_classic_block_sector*(`block`: MifareClassicBlockNumber): MifareClassicSectorNumber {.
+    cdecl, importc: "mifare_classic_block_sector", dynlib: freefareLib.}
+proc mifare_classic_sector_first_block*(sector: MifareClassicSectorNumber): MifareClassicBlockNumber {.
+    cdecl, importc: "mifare_classic_sector_first_block", dynlib: freefareLib.}
+proc mifare_classic_sector_block_count*(sector: MifareClassicSectorNumber): csize {.
+    cdecl, importc: "mifare_classic_sector_block_count", dynlib: freefareLib.}
+proc mifare_classic_sector_last_block*(sector: MifareClassicSectorNumber): MifareClassicBlockNumber {.
+    cdecl, importc: "mifare_classic_sector_last_block", dynlib: freefareLib.}
+const
+  C_000* = 0
+  C_001* = 1
+  C_010* = 2
+  C_011* = 3
+  C_100* = 4
+  C_101* = 5
+  C_110* = 6
+  C_111* = 7
+  C_DEFAULT* = 255
+
+##  MIFARE Classic Access Bits
+
+const
+  MCAB_R* = 0x00000008
+  MCAB_W* = 0x00000004
+  MCAB_D* = 0x00000002
+  MCAB_I* = 0x00000001
+  MCAB_READ_KEYA* = 0x00000400
+  MCAB_WRITE_KEYA* = 0x00000100
+  MCAB_READ_ACCESS_BITS* = 0x00000040
+  MCAB_WRITE_ACCESS_BITS* = 0x00000010
+  MCAB_READ_KEYB* = 0x00000004
+  MCAB_WRITE_KEYB* = 0x00000001
+
+type
+  mad_aid* {.importc: "struct mad_aid", header: freefareHeader, bycopy.} = object
+    application_code* {.importc: "application_code".}: uint8
+    function_cluster_code* {.importc: "function_cluster_code".}: uint8
+
+  MadAid* = mad_aid
+  mad* {.importc: "struct mad", header: freefareHeader, bycopy.} = object
+
+  Mad* = ptr mad
+
+##  MAD Public read key A
+
+var mad_public_key_a* {.importc: "mad_public_key_a", dynlib: freefareLib.}: MifareClassicKey
+
+##  AID - Adminisration codes
+
+var mad_free_aid* {.importc: "mad_free_aid", dynlib: freefareLib.}: MadAid
+
+var mad_defect_aid* {.importc: "mad_defect_aid", dynlib: freefareLib.}: MadAid
+
+var mad_reserved_aid* {.importc: "mad_reserved_aid", dynlib: freefareLib.}: MadAid
+
+var mad_card_holder_aid* {.importc: "mad_card_holder_aid", dynlib: freefareLib.}: MadAid
+
+var mad_not_applicable_aid* {.importc: "mad_not_applicable_aid", dynlib: freefareLib.}: MadAid
+
+##  NFC Forum AID
+
+var mad_nfcforum_aid* {.importc: "mad_nfcforum_aid", dynlib: freefareLib.}: MadAid
+
+proc mad_new*(version: uint8): Mad {.cdecl, importc: "mad_new", dynlib: freefareLib.}
+proc mad_read*(tag: FreefareTag): Mad {.cdecl, importc: "mad_read", dynlib: freefareLib.}
+proc mad_write*(tag: FreefareTag; mad: Mad; key_b_sector_00: MifareClassicKey;
+               key_b_sector_10: MifareClassicKey): cint {.cdecl,
+    importc: "mad_write", dynlib: freefareLib.}
+proc mad_get_version*(mad: Mad): cint {.cdecl, importc: "mad_get_version",
+                                    dynlib: freefareLib.}
+proc mad_set_version*(mad: Mad; version: uint8) {.cdecl, importc: "mad_set_version",
+    dynlib: freefareLib.}
+proc mad_get_card_publisher_sector*(mad: Mad): MifareClassicSectorNumber {.cdecl,
+    importc: "mad_get_card_publisher_sector", dynlib: freefareLib.}
+proc mad_set_card_publisher_sector*(mad: Mad; cps: MifareClassicSectorNumber): cint {.
+    cdecl, importc: "mad_set_card_publisher_sector", dynlib: freefareLib.}
+proc mad_get_aid*(mad: Mad; sector: MifareClassicSectorNumber; aid: ptr MadAid): cint {.
+    cdecl, importc: "mad_get_aid", dynlib: freefareLib.}
+proc mad_set_aid*(mad: Mad; sector: MifareClassicSectorNumber; aid: MadAid): cint {.
+    cdecl, importc: "mad_set_aid", dynlib: freefareLib.}
+proc mad_sector_reserved*(sector: MifareClassicSectorNumber): bool {.cdecl,
+    importc: "mad_sector_reserved", dynlib: freefareLib.}
+proc mad_free*(mad: Mad) {.cdecl, importc: "mad_free", dynlib: freefareLib.}
+proc mifare_application_alloc*(mad: Mad; aid: MadAid; size: csize): ptr MifareClassicSectorNumber {.
+    cdecl, importc: "mifare_application_alloc", dynlib: freefareLib.}
+proc mifare_application_read*(tag: FreefareTag; mad: Mad; aid: MadAid; buf: pointer;
+                             nbytes: csize; key: MifareClassicKey;
+                             key_type: MifareClassicKeyType): int32 {.cdecl,
+    importc: "mifare_application_read", dynlib: freefareLib.}
+proc mifare_application_write*(tag: FreefareTag; mad: Mad; aid: MadAid; buf: pointer;
+                              nbytes: csize; key: MifareClassicKey;
+                              key_type: MifareClassicKeyType): int32 {.cdecl,
+    importc: "mifare_application_write", dynlib: freefareLib.}
+proc mifare_application_free*(mad: Mad; aid: MadAid): cint {.cdecl,
+    importc: "mifare_application_free", dynlib: freefareLib.}
+proc mifare_application_find*(mad: Mad; aid: MadAid): ptr MifareClassicSectorNumber {.
+    cdecl, importc: "mifare_application_find", dynlib: freefareLib.}
+proc mifare_desfire_taste*(device: ptr device; target: target): bool {.cdecl,
+    importc: "mifare_desfire_taste", dynlib: freefareLib.}
+##  File types
+
+type
+  mifare_desfire_file_types* {.size: sizeof(cint).} = enum
+    MDFT_STANDARD_DATA_FILE = 0x00000000, MDFT_BACKUP_DATA_FILE = 0x00000001,
+    MDFT_VALUE_FILE_WITH_BACKUP = 0x00000002,
+    MDFT_LINEAR_RECORD_FILE_WITH_BACKUP = 0x00000003,
+    MDFT_CYCLIC_RECORD_FILE_WITH_BACKUP = 0x00000004
+
+
+##  Communication mode
+
+const
+  MDCM_PLAIN* = 0x00000000
+  MDCM_MACED* = 0x00000001
+  MDCM_ENCIPHERED* = 0x00000003
+
+##  Mifare DESFire master key settings
+## bit 7 - 4: Always 0.
+## bit 3: PICC master key settings frozen = 0 (WARNING - this is irreversible); PICC master key settings changeable when authenticated with PICC master key = 1
+## bit 2: PICC master key authentication required for creating or deleting applications = 0; Authentication not required = 1
+## bit 1: PICC master key authentication required for listing of applications or reading key settings = 0; Free listing of applications and reading key settings = 1
+## bit 0: PICC master key frozen (reversible with configuration change or when formatting card) = 0; PICC master key changeable = 1
+##
+
+template MDMK_SETTINGS*(picc_master_key_settings_changeable,
+                       free_create_delete_application,
+                       free_listing_apps_and_key_settings,
+                       picc_master_key_changeable: untyped): untyped =
+  ((picc_master_key_settings_changeable shl 3) or
+      (free_create_delete_application shl 2) or
+      (free_listing_apps_and_key_settings shl 1) or (picc_master_key_changeable))
+
+##  Mifare DESFire EV1 Application crypto operations
+
+const
+  APPLICATION_CRYPTO_DES* = 0x00000000
+  APPLICATION_CRYPTO_3K3DES* = 0x00000040
+  APPLICATION_CRYPTO_AES* = 0x00000080
+
+##  Mifare DESFire Application settings
+##  bit 7 - 4: Number of key needed to change application keys (key 0 - 13; 0 = master key; 14 = key itself required for key change; 15 = all keys are frozen)
+##  bit 3: Application configuration frozen = 0; Application configuration changeable when authenticated with application master key = 1
+##  bit 2: Application master key authentication required for create/delete files = 0; Authentication not required = 1
+##  bit 1: GetFileIDs, GetFileSettings and GetKeySettings behavior: Master key authentication required = 0; No authentication required = 1
+##  bit 0 = Application master key frozen = 0; Application master key changeable = 1
+##
+
+template MDAPP_SETTINGS*(key_no_for_key_changing, config_changeable,
+                        free_create_delete_files, free_listing_contents,
+                        app_master_key_changeable: untyped): untyped =
+  ((key_no_for_key_changing shl 4) or (config_changeable shl 3) or
+      (free_create_delete_files shl 2) or (free_listing_contents shl 1) or
+      (app_master_key_changeable))
+
+##  Access right
+
+template MDAR*(read, write, read_write, change_access_rights: untyped): untyped =
+  ((read shl 12) or (write shl 8) or (read_write shl 4) or (change_access_rights))
+
+template MDAR_READ*(ar: untyped): untyped =
+  (((ar) shr 12) and 0x0000000F)
+
+template MDAR_WRITE*(ar: untyped): untyped =
+  (((ar) shr 8) and 0x0000000F)
+
+template MDAR_READ_WRITE*(ar: untyped): untyped =
+  (((ar) shr 4) and 0x0000000F)
+
+template MDAR_CHANGE_AR*(ar: untyped): untyped =
+  ((ar) and 0x0000000F)
+
+const
+  MDAR_KEY0* = 0x00000000
+  MDAR_KEY1* = 0x00000001
+  MDAR_KEY2* = 0x00000002
+  MDAR_KEY3* = 0x00000003
+  MDAR_KEY4* = 0x00000004
+  MDAR_KEY5* = 0x00000005
+  MDAR_KEY6* = 0x00000006
+  MDAR_KEY7* = 0x00000007
+  MDAR_KEY8* = 0x00000008
+  MDAR_KEY9* = 0x00000009
+  MDAR_KEY10* = 0x0000000A
+  MDAR_KEY11* = 0x0000000B
+  MDAR_KEY12* = 0x0000000C
+  MDAR_KEY13* = 0x0000000D
+  MDAR_FREE* = 0x0000000E
+  MDAR_DENY* = 0x0000000F
+
+##  Status and error codes
+
+const
+  OPERATION_OK* = 0x00000000
+  NO_CHANGES* = 0x0000000C
+  OUT_OF_EEPROM_ERROR* = 0x0000000E
+  ILLEGAL_COMMAND_CODE* = 0x0000001C
+  INTEGRITY_ERROR* = 0x0000001E
+  NO_SUCH_KEY* = 0x00000040
+  LENGTH_ERROR* = 0x0000007E
+  PERMISSION_ERROR* = 0x0000009D
+  PARAMETER_ERROR* = 0x0000009E
+  APPLICATION_NOT_FOUND* = 0x000000A0
+  APPL_INTEGRITY_ERROR* = 0x000000A1
+  AUTHENTICATION_ERROR* = 0x000000AE
+  ADDITIONAL_FRAME* = 0x000000AF
+  BOUNDARY_ERROR* = 0x000000BE
+  PICC_INTEGRITY_ERROR* = 0x000000C1
+  COMMAND_ABORTED* = 0x000000CA
+  PICC_DISABLED_ERROR* = 0x000000CD
+  COUNT_ERROR* = 0x000000CE
+  DUPLICATE_ERROR* = 0x000000DE
+  EEPROM_ERROR* = 0x000000EE
+  FILE_NOT_FOUND* = 0x000000F0
+  FILE_INTEGRITY_ERROR* = 0x000000F1
+
+##  Error code managed by the library
+
+const
+  CRYPTO_ERROR* = 0x00000001
+  TAG_INFO_MISSING_ERROR* = 0x000000BA
+  UNKNOWN_TAG_TYPE_ERROR* = 0x000000BB
+
+type
+  mifare_desfire_aid* {.importc: "struct mifare_desfire_aid",
+                       header: freefareHeader, bycopy.} = object
+
+  MifareDESFireAID* = ptr mifare_desfire_aid
+  mifare_desfire_df* {.importc: "struct mifare_desfire_df", header: freefareHeader,
+                      bycopy.} = object
+    aid* {.importc: "aid".}: uint32
+    fid* {.importc: "fid".}: uint16
+    df_name* {.importc: "df_name".}: array[16, uint8]
+    df_name_len* {.importc: "df_name_len".}: csize
+
+  MifareDESFireDF* = mifare_desfire_df
+
+proc mifare_desfire_aid_new*(aid: uint32): MifareDESFireAID {.cdecl,
+    importc: "mifare_desfire_aid_new", dynlib: freefareLib.}
+proc mifare_desfire_aid_new_with_mad_aid*(mad_aid: MadAid; n: uint8): MifareDESFireAID {.
+    cdecl, importc: "mifare_desfire_aid_new_with_mad_aid", dynlib: freefareLib.}
+proc mifare_desfire_aid_get_aid*(aid: MifareDESFireAID): uint32 {.cdecl,
+    importc: "mifare_desfire_aid_get_aid", dynlib: freefareLib.}
+proc mifare_desfire_last_pcd_error*(tag: FreefareTag): uint8 {.cdecl,
+    importc: "mifare_desfire_last_pcd_error", dynlib: freefareLib.}
+proc mifare_desfire_last_picc_error*(tag: FreefareTag): uint8 {.cdecl,
+    importc: "mifare_desfire_last_picc_error", dynlib: freefareLib.}
+type
+  INNER_C_STRUCT_freefare_420* {.importc: "struct no_name", header: freefareHeader,
+                                bycopy.} = object
+    vendor_id* {.importc: "vendor_id".}: uint8
+    `type`* {.importc: "type".}: uint8
+    subtype* {.importc: "subtype".}: uint8
+    version_major* {.importc: "version_major".}: uint8
+    version_minor* {.importc: "version_minor".}: uint8
+    storage_size* {.importc: "storage_size".}: uint8
+    protocol* {.importc: "protocol".}: uint8
+
+  INNER_C_STRUCT_freefare_429* {.importc: "struct no_name", header: freefareHeader,
+                                bycopy.} = object
+    vendor_id* {.importc: "vendor_id".}: uint8
+    `type`* {.importc: "type".}: uint8
+    subtype* {.importc: "subtype".}: uint8
+    version_major* {.importc: "version_major".}: uint8
+    version_minor* {.importc: "version_minor".}: uint8
+    storage_size* {.importc: "storage_size".}: uint8
+    protocol* {.importc: "protocol".}: uint8
+
+  mifare_desfire_version_info* {.importc: "struct mifare_desfire_version_info",
+                                header: freefareHeader, bycopy.} = object
+    hardware* {.importc: "hardware".}: INNER_C_STRUCT_freefare_420
+    software* {.importc: "software".}: INNER_C_STRUCT_freefare_429
+    uid* {.importc: "uid".}: array[7, uint8]
+    batch_number* {.importc: "batch_number".}: array[5, uint8]
+    production_week* {.importc: "production_week".}: uint8
+    production_year* {.importc: "production_year".}: uint8
+
+  INNER_C_STRUCT_freefare_450* {.importc: "struct no_name", header: freefareHeader,
+                                bycopy.} = object
+    file_size* {.importc: "file_size".}: uint32
+
+  INNER_C_STRUCT_freefare_453* {.importc: "struct no_name", header: freefareHeader,
+                                bycopy.} = object
+    lower_limit* {.importc: "lower_limit".}: int32
+    upper_limit* {.importc: "upper_limit".}: int32
+    limited_credit_value* {.importc: "limited_credit_value".}: int32
+    limited_credit_enabled* {.importc: "limited_credit_enabled".}: uint8
+
+  INNER_C_STRUCT_freefare_459* {.importc: "struct no_name", header: freefareHeader,
+                                bycopy.} = object
+    record_size* {.importc: "record_size".}: uint32
+    max_number_of_records* {.importc: "max_number_of_records".}: uint32
+    current_number_of_records* {.importc: "current_number_of_records".}: uint32
+
+  INNER_C_UNION_freefare_449* {.importc: "struct no_name", header: freefareHeader,
+                               bycopy.} = object {.union.}
+    standard_file* {.importc: "standard_file".}: INNER_C_STRUCT_freefare_450
+    value_file* {.importc: "value_file".}: INNER_C_STRUCT_freefare_453
+    linear_record_file* {.importc: "linear_record_file".}: INNER_C_STRUCT_freefare_459
+
+  mifare_desfire_file_settings* {.importc: "struct mifare_desfire_file_settings",
+                                 header: freefareHeader, bycopy.} = object
+    file_type* {.importc: "file_type".}: uint8
+    communication_settings* {.importc: "communication_settings".}: uint8
+    access_rights* {.importc: "access_rights".}: uint16
+    settings* {.importc: "settings".}: INNER_C_UNION_freefare_449
+
+
+proc mifare_desfire_tag_new*(device: ptr device; target: target): FreefareTag {.cdecl,
+    importc: "mifare_desfire_tag_new", dynlib: freefareLib.}
+proc mifare_desfire_tag_free*(tags: FreefareTag) {.cdecl,
+    importc: "mifare_desfire_tag_free", dynlib: freefareLib.}
+proc mifare_desfire_connect*(tag: FreefareTag): cint {.cdecl,
+    importc: "mifare_desfire_connect", dynlib: freefareLib.}
+proc mifare_desfire_disconnect*(tag: FreefareTag): cint {.cdecl,
+    importc: "mifare_desfire_disconnect", dynlib: freefareLib.}
+proc mifare_desfire_authenticate*(tag: FreefareTag; key_no: uint8;
+                                 key: MifareDESFireKey): cint {.cdecl,
+    importc: "mifare_desfire_authenticate", dynlib: freefareLib.}
+proc mifare_desfire_authenticate_iso*(tag: FreefareTag; key_no: uint8;
+                                     key: MifareDESFireKey): cint {.cdecl,
+    importc: "mifare_desfire_authenticate_iso", dynlib: freefareLib.}
+proc mifare_desfire_authenticate_aes*(tag: FreefareTag; key_no: uint8;
+                                     key: MifareDESFireKey): cint {.cdecl,
+    importc: "mifare_desfire_authenticate_aes", dynlib: freefareLib.}
+proc mifare_desfire_change_key_settings*(tag: FreefareTag; settings: uint8): cint {.
+    cdecl, importc: "mifare_desfire_change_key_settings", dynlib: freefareLib.}
+proc mifare_desfire_get_key_settings*(tag: FreefareTag; settings: ptr uint8;
+                                     max_keys: ptr uint8): cint {.cdecl,
+    importc: "mifare_desfire_get_key_settings", dynlib: freefareLib.}
+proc mifare_desfire_change_key*(tag: FreefareTag; key_no: uint8;
+                               new_key: MifareDESFireKey;
+                               old_key: MifareDESFireKey): cint {.cdecl,
+    importc: "mifare_desfire_change_key", dynlib: freefareLib.}
+proc mifare_desfire_get_key_version*(tag: FreefareTag; key_no: uint8;
+                                    version: ptr uint8): cint {.cdecl,
+    importc: "mifare_desfire_get_key_version", dynlib: freefareLib.}
+proc mifare_desfire_create_application*(tag: FreefareTag; aid: MifareDESFireAID;
+                                       settings: uint8; key_no: uint8): cint {.cdecl,
+    importc: "mifare_desfire_create_application", dynlib: freefareLib.}
+proc mifare_desfire_create_application_3k3des*(tag: FreefareTag;
+    aid: MifareDESFireAID; settings: uint8; key_no: uint8): cint {.cdecl,
+    importc: "mifare_desfire_create_application_3k3des", dynlib: freefareLib.}
+proc mifare_desfire_create_application_aes*(tag: FreefareTag;
+    aid: MifareDESFireAID; settings: uint8; key_no: uint8): cint {.cdecl,
+    importc: "mifare_desfire_create_application_aes", dynlib: freefareLib.}
+proc mifare_desfire_create_application_iso*(tag: FreefareTag;
+    aid: MifareDESFireAID; settings: uint8; key_no: uint8;
+    want_iso_file_identifiers: cint; iso_file_id: uint16; iso_file_name: ptr uint8;
+    iso_file_name_len: csize): cint {.cdecl, importc: "mifare_desfire_create_application_iso",
+                                   dynlib: freefareLib.}
+proc mifare_desfire_create_application_3k3des_iso*(tag: FreefareTag;
+    aid: MifareDESFireAID; settings: uint8; key_no: uint8;
+    want_iso_file_identifiers: cint; iso_file_id: uint16; iso_file_name: ptr uint8;
+    iso_file_name_len: csize): cint {.cdecl, importc: "mifare_desfire_create_application_3k3des_iso",
+                                   dynlib: freefareLib.}
+proc mifare_desfire_create_application_aes_iso*(tag: FreefareTag;
+    aid: MifareDESFireAID; settings: uint8; key_no: uint8;
+    want_iso_file_identifiers: cint; iso_file_id: uint16; iso_file_name: ptr uint8;
+    iso_file_name_len: csize): cint {.cdecl, importc: "mifare_desfire_create_application_aes_iso",
+                                   dynlib: freefareLib.}
+proc mifare_desfire_delete_application*(tag: FreefareTag; aid: MifareDESFireAID): cint {.
+    cdecl, importc: "mifare_desfire_delete_application", dynlib: freefareLib.}
+proc mifare_desfire_get_application_ids*(tag: FreefareTag;
+                                        aids: ptr ptr MifareDESFireAID;
+                                        count: ptr csize): cint {.cdecl,
+    importc: "mifare_desfire_get_application_ids", dynlib: freefareLib.}
+proc mifare_desfire_get_df_names*(tag: FreefareTag; dfs: ptr ptr MifareDESFireDF;
+                                 count: ptr csize): cint {.cdecl,
+    importc: "mifare_desfire_get_df_names", dynlib: freefareLib.}
+proc mifare_desfire_free_application_ids*(aids: ptr MifareDESFireAID) {.cdecl,
+    importc: "mifare_desfire_free_application_ids", dynlib: freefareLib.}
+proc mifare_desfire_select_application*(tag: FreefareTag; aid: MifareDESFireAID): cint {.
+    cdecl, importc: "mifare_desfire_select_application", dynlib: freefareLib.}
+proc mifare_desfire_format_picc*(tag: FreefareTag): cint {.cdecl,
+    importc: "mifare_desfire_format_picc", dynlib: freefareLib.}
+proc mifare_desfire_get_version*(tag: FreefareTag;
+                                version_info: ptr mifare_desfire_version_info): cint {.
+    cdecl, importc: "mifare_desfire_get_version", dynlib: freefareLib.}
+proc mifare_desfire_free_mem*(tag: FreefareTag; size: ptr uint32): cint {.cdecl,
+    importc: "mifare_desfire_free_mem", dynlib: freefareLib.}
+proc mifare_desfire_set_configuration*(tag: FreefareTag; disable_format: bool;
+                                      enable_random_uid: bool): cint {.cdecl,
+    importc: "mifare_desfire_set_configuration", dynlib: freefareLib.}
+proc mifare_desfire_set_default_key*(tag: FreefareTag; key: MifareDESFireKey): cint {.
+    cdecl, importc: "mifare_desfire_set_default_key", dynlib: freefareLib.}
+proc mifare_desfire_set_ats*(tag: FreefareTag; ats: ptr uint8): cint {.cdecl,
+    importc: "mifare_desfire_set_ats", dynlib: freefareLib.}
+proc mifare_desfire_get_card_uid*(tag: FreefareTag; uid: cstringArray): cint {.cdecl,
+    importc: "mifare_desfire_get_card_uid", dynlib: freefareLib.}
+proc mifare_desfire_get_card_uid_raw*(tag: FreefareTag; uid: array[7, uint8]): cint {.
+    cdecl, importc: "mifare_desfire_get_card_uid_raw", dynlib: freefareLib.}
+proc mifare_desfire_get_file_ids*(tag: FreefareTag; files: ptr ptr uint8;
+                                 count: ptr csize): cint {.cdecl,
+    importc: "mifare_desfire_get_file_ids", dynlib: freefareLib.}
+proc mifare_desfire_get_iso_file_ids*(tag: FreefareTag; files: ptr ptr uint16;
+                                     count: ptr csize): cint {.cdecl,
+    importc: "mifare_desfire_get_iso_file_ids", dynlib: freefareLib.}
+proc mifare_desfire_get_file_settings*(tag: FreefareTag; file_no: uint8; settings: ptr mifare_desfire_file_settings): cint {.
+    cdecl, importc: "mifare_desfire_get_file_settings", dynlib: freefareLib.}
+proc mifare_desfire_change_file_settings*(tag: FreefareTag; file_no: uint8;
+    communication_settings: uint8; access_rights: uint16): cint {.cdecl,
+    importc: "mifare_desfire_change_file_settings", dynlib: freefareLib.}
+proc mifare_desfire_create_std_data_file*(tag: FreefareTag; file_no: uint8;
+    communication_settings: uint8; access_rights: uint16; file_size: uint32): cint {.
+    cdecl, importc: "mifare_desfire_create_std_data_file", dynlib: freefareLib.}
+proc mifare_desfire_create_std_data_file_iso*(tag: FreefareTag; file_no: uint8;
+    communication_settings: uint8; access_rights: uint16; file_size: uint32;
+    iso_file_id: uint16): cint {.cdecl, importc: "mifare_desfire_create_std_data_file_iso",
+                              dynlib: freefareLib.}
+proc mifare_desfire_create_backup_data_file*(tag: FreefareTag; file_no: uint8;
+    communication_settings: uint8; access_rights: uint16; file_size: uint32): cint {.
+    cdecl, importc: "mifare_desfire_create_backup_data_file", dynlib: freefareLib.}
+proc mifare_desfire_create_backup_data_file_iso*(tag: FreefareTag; file_no: uint8;
+    communication_settings: uint8; access_rights: uint16; file_size: uint32;
+    iso_file_id: uint16): cint {.cdecl, importc: "mifare_desfire_create_backup_data_file_iso",
+                              dynlib: freefareLib.}
+proc mifare_desfire_create_value_file*(tag: FreefareTag; file_no: uint8;
+                                      communication_settings: uint8;
+                                      access_rights: uint16; lower_limit: int32;
+                                      upper_limit: int32; value: int32;
+                                      limited_credit_enable: uint8): cint {.cdecl,
+    importc: "mifare_desfire_create_value_file", dynlib: freefareLib.}
+proc mifare_desfire_create_linear_record_file*(tag: FreefareTag; file_no: uint8;
+    communication_settings: uint8; access_rights: uint16; record_size: uint32;
+    max_number_of_records: uint32): cint {.cdecl, importc: "mifare_desfire_create_linear_record_file",
+                                        dynlib: freefareLib.}
+proc mifare_desfire_create_linear_record_file_iso*(tag: FreefareTag;
+    file_no: uint8; communication_settings: uint8; access_rights: uint16;
+    record_size: uint32; max_number_of_records: uint32; iso_file_id: uint16): cint {.
+    cdecl, importc: "mifare_desfire_create_linear_record_file_iso",
+    dynlib: freefareLib.}
+proc mifare_desfire_create_cyclic_record_file*(tag: FreefareTag; file_no: uint8;
+    communication_settings: uint8; access_rights: uint16; record_size: uint32;
+    max_number_of_records: uint32): cint {.cdecl, importc: "mifare_desfire_create_cyclic_record_file",
+                                        dynlib: freefareLib.}
+proc mifare_desfire_create_cyclic_record_file_iso*(tag: FreefareTag;
+    file_no: uint8; communication_settings: uint8; access_rights: uint16;
+    record_size: uint32; max_number_of_records: uint32; iso_file_id: uint16): cint {.
+    cdecl, importc: "mifare_desfire_create_cyclic_record_file_iso",
+    dynlib: freefareLib.}
+proc mifare_desfire_delete_file*(tag: FreefareTag; file_no: uint8): cint {.cdecl,
+    importc: "mifare_desfire_delete_file", dynlib: freefareLib.}
+proc mifare_desfire_read_data*(tag: FreefareTag; file_no: uint8; offset: uint32;
+                              length: csize; data: pointer): int32 {.cdecl,
+    importc: "mifare_desfire_read_data", dynlib: freefareLib.}
+proc mifare_desfire_read_data_ex*(tag: FreefareTag; file_no: uint8; offset: uint32;
+                                 length: csize; data: pointer; cs: cint): int32 {.
+    cdecl, importc: "mifare_desfire_read_data_ex", dynlib: freefareLib.}
+proc mifare_desfire_write_data*(tag: FreefareTag; file_no: uint8; offset: uint32;
+                               length: csize; data: pointer): int32 {.cdecl,
+    importc: "mifare_desfire_write_data", dynlib: freefareLib.}
+proc mifare_desfire_write_data_ex*(tag: FreefareTag; file_no: uint8; offset: uint32;
+                                  length: csize; data: pointer; cs: cint): int32 {.
+    cdecl, importc: "mifare_desfire_write_data_ex", dynlib: freefareLib.}
+proc mifare_desfire_get_value*(tag: FreefareTag; file_no: uint8; value: ptr int32): cint {.
+    cdecl, importc: "mifare_desfire_get_value", dynlib: freefareLib.}
+proc mifare_desfire_get_value_ex*(tag: FreefareTag; file_no: uint8; value: ptr int32;
+                                 cs: cint): cint {.cdecl,
+    importc: "mifare_desfire_get_value_ex", dynlib: freefareLib.}
+proc mifare_desfire_credit*(tag: FreefareTag; file_no: uint8; amount: int32): cint {.
+    cdecl, importc: "mifare_desfire_credit", dynlib: freefareLib.}
+proc mifare_desfire_credit_ex*(tag: FreefareTag; file_no: uint8; amount: int32;
+                              cs: cint): cint {.cdecl,
+    importc: "mifare_desfire_credit_ex", dynlib: freefareLib.}
+proc mifare_desfire_debit*(tag: FreefareTag; file_no: uint8; amount: int32): cint {.
+    cdecl, importc: "mifare_desfire_debit", dynlib: freefareLib.}
+proc mifare_desfire_debit_ex*(tag: FreefareTag; file_no: uint8; amount: int32; cs: cint): cint {.
+    cdecl, importc: "mifare_desfire_debit_ex", dynlib: freefareLib.}
+proc mifare_desfire_limited_credit*(tag: FreefareTag; file_no: uint8; amount: int32): cint {.
+    cdecl, importc: "mifare_desfire_limited_credit", dynlib: freefareLib.}
+proc mifare_desfire_limited_credit_ex*(tag: FreefareTag; file_no: uint8;
+                                      amount: int32; cs: cint): cint {.cdecl,
+    importc: "mifare_desfire_limited_credit_ex", dynlib: freefareLib.}
+proc mifare_desfire_write_record*(tag: FreefareTag; file_no: uint8; offset: uint32;
+                                 length: csize; data: pointer): int32 {.cdecl,
+    importc: "mifare_desfire_write_record", dynlib: freefareLib.}
+proc mifare_desfire_write_record_ex*(tag: FreefareTag; file_no: uint8;
+                                    offset: uint32; length: csize; data: pointer;
+                                    cs: cint): int32 {.cdecl,
+    importc: "mifare_desfire_write_record_ex", dynlib: freefareLib.}
+proc mifare_desfire_read_records*(tag: FreefareTag; file_no: uint8; offset: uint32;
+                                 length: csize; data: pointer): int32 {.cdecl,
+    importc: "mifare_desfire_read_records", dynlib: freefareLib.}
+proc mifare_desfire_read_records_ex*(tag: FreefareTag; file_no: uint8;
+                                    offset: uint32; length: csize; data: pointer;
+                                    cs: cint): int32 {.cdecl,
+    importc: "mifare_desfire_read_records_ex", dynlib: freefareLib.}
+proc mifare_desfire_clear_record_file*(tag: FreefareTag; file_no: uint8): cint {.
+    cdecl, importc: "mifare_desfire_clear_record_file", dynlib: freefareLib.}
+proc mifare_desfire_commit_transaction*(tag: FreefareTag): cint {.cdecl,
+    importc: "mifare_desfire_commit_transaction", dynlib: freefareLib.}
+proc mifare_desfire_abort_transaction*(tag: FreefareTag): cint {.cdecl,
+    importc: "mifare_desfire_abort_transaction", dynlib: freefareLib.}
+proc mifare_desfire_des_key_new*(value: array[8, uint8]): MifareDESFireKey {.cdecl,
+    importc: "mifare_desfire_des_key_new", dynlib: freefareLib.}
+proc mifare_desfire_3des_key_new*(value: array[16, uint8]): MifareDESFireKey {.cdecl,
+    importc: "mifare_desfire_3des_key_new", dynlib: freefareLib.}
+proc mifare_desfire_des_key_new_with_version*(value: array[8, uint8]): MifareDESFireKey {.
+    cdecl, importc: "mifare_desfire_des_key_new_with_version", dynlib: freefareLib.}
+proc mifare_desfire_3des_key_new_with_version*(value: array[16, uint8]): MifareDESFireKey {.
+    cdecl, importc: "mifare_desfire_3des_key_new_with_version", dynlib: freefareLib.}
+proc mifare_desfire_3k3des_key_new*(value: array[24, uint8]): MifareDESFireKey {.
+    cdecl, importc: "mifare_desfire_3k3des_key_new", dynlib: freefareLib.}
+proc mifare_desfire_3k3des_key_new_with_version*(value: array[24, uint8]): MifareDESFireKey {.
+    cdecl, importc: "mifare_desfire_3k3des_key_new_with_version",
+    dynlib: freefareLib.}
+proc mifare_desfire_aes_key_new*(value: array[16, uint8]): MifareDESFireKey {.cdecl,
+    importc: "mifare_desfire_aes_key_new", dynlib: freefareLib.}
+proc mifare_desfire_aes_key_new_with_version*(value: array[16, uint8];
+    version: uint8): MifareDESFireKey {.cdecl, importc: "mifare_desfire_aes_key_new_with_version",
+                                     dynlib: freefareLib.}
+proc mifare_desfire_key_get_version*(key: MifareDESFireKey): uint8 {.cdecl,
+    importc: "mifare_desfire_key_get_version", dynlib: freefareLib.}
+proc mifare_desfire_key_set_version*(key: MifareDESFireKey; version: uint8) {.cdecl,
+    importc: "mifare_desfire_key_set_version", dynlib: freefareLib.}
+proc mifare_desfire_key_free*(key: MifareDESFireKey) {.cdecl,
+    importc: "mifare_desfire_key_free", dynlib: freefareLib.}
+proc tlv_encode*(`type`: uint8; istream: ptr uint8; isize: uint16; osize: ptr csize): ptr uint8 {.
+    cdecl, importc: "tlv_encode", dynlib: freefareLib.}
+proc tlv_decode*(istream: ptr uint8; `type`: ptr uint8; size: ptr uint16): ptr uint8 {.
+    cdecl, importc: "tlv_decode", dynlib: freefareLib.}
+proc tlv_record_length*(istream: ptr uint8; field_length_size: ptr csize;
+                       field_value_size: ptr csize): csize {.cdecl,
+    importc: "tlv_record_length", dynlib: freefareLib.}
+proc tlv_append*(a: ptr uint8; b: ptr uint8): ptr uint8 {.cdecl, importc: "tlv_append",
+    dynlib: freefareLib.}
+type
+  MifareKeyType* {.size: sizeof(cint).} = enum
+    MIFARE_KEY_DES, MIFARE_KEY_2K3DES, MIFARE_KEY_3K3DES, MIFARE_KEY_AES128
+
+const
+  MIFARE_KEY_LAST = MIFARE_KEY_AES128
+
+type
+  mifare_key_deriver* {.importc: "struct mifare_key_deriver",
+                       header: freefareHeader, bycopy.} = object
+
+  MifareKeyDeriver* = ptr mifare_key_deriver
+
+proc mifare_key_deriver_new_an10922*(master_key: MifareDESFireKey;
+                                    output_key_type: MifareKeyType): MifareKeyDeriver {.
+    cdecl, importc: "mifare_key_deriver_new_an10922", dynlib: freefareLib.}
+proc mifare_key_deriver_begin*(deriver: MifareKeyDeriver): cint {.cdecl,
+    importc: "mifare_key_deriver_begin", dynlib: freefareLib.}
+proc mifare_key_deriver_update_data*(deriver: MifareKeyDeriver; data: ptr uint8;
+                                    len: csize): cint {.cdecl,
+    importc: "mifare_key_deriver_update_data", dynlib: freefareLib.}
+proc mifare_key_deriver_update_uid*(deriver: MifareKeyDeriver; tag: FreefareTag): cint {.
+    cdecl, importc: "mifare_key_deriver_update_uid", dynlib: freefareLib.}
+proc mifare_key_deriver_update_aid*(deriver: MifareKeyDeriver;
+                                   aid: MifareDESFireAID): cint {.cdecl,
+    importc: "mifare_key_deriver_update_aid", dynlib: freefareLib.}
+proc mifare_key_deriver_update_cstr*(deriver: MifareKeyDeriver; cstr: cstring): cint {.
+    cdecl, importc: "mifare_key_deriver_update_cstr", dynlib: freefareLib.}
+proc mifare_key_deriver_end*(deriver: MifareKeyDeriver): MifareDESFireKey {.cdecl,
+    importc: "mifare_key_deriver_end", dynlib: freefareLib.}
+proc mifare_key_deriver_end_raw*(deriver: MifareKeyDeriver;
+                                diversified_bytes: ptr uint8; data_max_len: csize): cint {.
+    cdecl, importc: "mifare_key_deriver_end_raw", dynlib: freefareLib.}
+proc mifare_key_deriver_free*(state: MifareKeyDeriver) {.cdecl,
+    importc: "mifare_key_deriver_free", dynlib: freefareLib.}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/nfc-nim/nfc-emulation.h	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,71 @@
+/*-
+ * Free/Libre Near Field Communication (NFC) library
+ *
+ * Libnfc historical contributors:
+ * Copyright (C) 2009      Roel Verdult
+ * Copyright (C) 2009-2013 Romuald Conty
+ * Copyright (C) 2010-2012 Romain Tartière
+ * Copyright (C) 2010-2013 Philippe Teuwen
+ * Copyright (C) 2012-2013 Ludovic Rousseau
+ * See AUTHORS file for a more comprehensive list of contributors.
+ * Additional contributors of this file:
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * @file nfc-emulation.h
+ * @brief Provide a small API to ease emulation in libnfc
+ */
+
+#ifndef __NFC_EMULATION_H__
+#define __NFC_EMULATION_H__
+
+#include <sys/types.h>
+#include <nfc/nfc.h>
+
+#ifdef __cplusplus
+extern  "C" {
+#endif /* __cplusplus */
+
+struct nfc_emulator;
+struct nfc_emulation_state_machine;
+
+/**
+ * @struct nfc_emulator
+ * @brief NFC emulator structure
+ */
+struct nfc_emulator {
+  nfc_target *target;
+  struct nfc_emulation_state_machine *state_machine;
+  void *user_data;
+};
+
+/**
+ * @struct nfc_emulation_state_machine
+ * @brief  NFC emulation state machine structure
+ */
+struct nfc_emulation_state_machine {
+  int (*io)(struct nfc_emulator *emulator, const uint8_t *data_in, const size_t data_in_len, uint8_t *data_out, const size_t data_out_len);
+  void *data;
+};
+
+NFC_EXPORT int    nfc_emulate_target(nfc_device *pnd, struct nfc_emulator *emulator, const int timeout);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __NFC_EMULATION_H__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/nfc-nim/nfc-types.h	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,336 @@
+/*-
+ * Free/Libre Near Field Communication (NFC) library
+ *
+ * Libnfc historical contributors:
+ * Copyright (C) 2009      Roel Verdult
+ * Copyright (C) 2009-2013 Romuald Conty
+ * Copyright (C) 2010-2012 Romain Tartière
+ * Copyright (C) 2010-2013 Philippe Teuwen
+ * Copyright (C) 2012-2013 Ludovic Rousseau
+ * See AUTHORS file for a more comprehensive list of contributors.
+ * Additional contributors of this file:
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ * @file nfc-types.h
+ * @brief Define NFC types
+ */
+
+#ifndef __NFC_TYPES_H__
+#define __NFC_TYPES_H__
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#ifndef NFC_BUFSIZE_CONNSTRING
+#define NFC_BUFSIZE_CONNSTRING 1024
+#endif
+
+/**
+ * NFC context
+ */
+typedef struct nfc_context nfc_context;
+
+/**
+ * NFC device
+ */
+typedef struct nfc_device nfc_device;
+
+/**
+ * NFC device driver
+ */
+typedef struct nfc_driver nfc_driver;
+
+/**
+ * Connection string
+ */
+typedef char nfc_connstring[NFC_BUFSIZE_CONNSTRING];
+
+/**
+ * Properties
+ */
+typedef enum {
+  /**
+   * Default command processing timeout
+   * Property value's (duration) unit is ms and 0 means no timeout (infinite).
+   * Default value is set by driver layer
+   */
+  NP_TIMEOUT_COMMAND,
+  /**
+   * Timeout between ATR_REQ and ATR_RES
+   * When the device is in initiator mode, a target is considered as mute if no
+   * valid ATR_RES is received within this timeout value.
+   * Default value for this property is 103 ms on PN53x based devices.
+   */
+  NP_TIMEOUT_ATR,
+  /**
+   * Timeout value to give up reception from the target in case of no answer.
+   * Default value for this property is 52 ms).
+   */
+  NP_TIMEOUT_COM,
+  /** Let the PN53X chip handle the CRC bytes. This means that the chip appends
+  * the CRC bytes to the frames that are transmitted. It will parse the last
+  * bytes from received frames as incoming CRC bytes. They will be verified
+  * against the used modulation and protocol. If an frame is expected with
+  * incorrect CRC bytes this option should be disabled. Example frames where
+  * this is useful are the ATQA and UID+BCC that are transmitted without CRC
+  * bytes during the anti-collision phase of the ISO14443-A protocol. */
+  NP_HANDLE_CRC,
+  /** Parity bits in the network layer of ISO14443-A are by default generated and
+   * validated in the PN53X chip. This is a very convenient feature. On certain
+   * times though it is useful to get full control of the transmitted data. The
+   * proprietary MIFARE Classic protocol uses for example custom (encrypted)
+   * parity bits. For interoperability it is required to be completely
+   * compatible, including the arbitrary parity bits. When this option is
+   * disabled, the functions to communicating bits should be used. */
+  NP_HANDLE_PARITY,
+  /** This option can be used to enable or disable the electronic field of the
+   * NFC device. */
+  NP_ACTIVATE_FIELD,
+  /** The internal CRYPTO1 co-processor can be used to transmit messages
+   * encrypted. This option is automatically activated after a successful MIFARE
+   * Classic authentication. */
+  NP_ACTIVATE_CRYPTO1,
+  /** The default configuration defines that the PN53X chip will try indefinitely
+   * to invite a tag in the field to respond. This could be desired when it is
+   * certain a tag will enter the field. On the other hand, when this is
+   * uncertain, it will block the application. This option could best be compared
+   * to the (NON)BLOCKING option used by (socket)network programming. */
+  NP_INFINITE_SELECT,
+  /** If this option is enabled, frames that carry less than 4 bits are allowed.
+   * According to the standards these frames should normally be handles as
+   * invalid frames. */
+  NP_ACCEPT_INVALID_FRAMES,
+  /** If the NFC device should only listen to frames, it could be useful to let
+   * it gather multiple frames in a sequence. They will be stored in the internal
+   * FIFO of the PN53X chip. This could be retrieved by using the receive data
+   * functions. Note that if the chip runs out of bytes (FIFO = 64 bytes long),
+   * it will overwrite the first received frames, so quick retrieving of the
+   * received data is desirable. */
+  NP_ACCEPT_MULTIPLE_FRAMES,
+  /** This option can be used to enable or disable the auto-switching mode to
+   * ISO14443-4 is device is compliant.
+   * In initiator mode, it means that NFC chip will send RATS automatically when
+   * select and it will automatically poll for ISO14443-4 card when ISO14443A is
+   * requested.
+   * In target mode, with a NFC chip compliant (ie. PN532), the chip will
+   * emulate a 14443-4 PICC using hardware capability */
+  NP_AUTO_ISO14443_4,
+  /** Use automatic frames encapsulation and chaining. */
+  NP_EASY_FRAMING,
+  /** Force the chip to switch in ISO14443-A */
+  NP_FORCE_ISO14443_A,
+  /** Force the chip to switch in ISO14443-B */
+  NP_FORCE_ISO14443_B,
+  /** Force the chip to run at 106 kbps */
+  NP_FORCE_SPEED_106,
+} nfc_property;
+
+// Compiler directive, set struct alignment to 1 uint8_t for compatibility
+#  pragma pack(1)
+
+/**
+ * @enum nfc_dep_mode
+ * @brief NFC D.E.P. (Data Exchange Protocol) active/passive mode
+ */
+typedef enum {
+  NDM_UNDEFINED = 0,
+  NDM_PASSIVE,
+  NDM_ACTIVE,
+} nfc_dep_mode;
+
+/**
+ * @struct nfc_dep_info
+ * @brief NFC target information in D.E.P. (Data Exchange Protocol) see ISO/IEC 18092 (NFCIP-1)
+ */
+typedef struct {
+  /** NFCID3 */
+  uint8_t  abtNFCID3[10];
+  /** DID */
+  uint8_t  btDID;
+  /** Supported send-bit rate */
+  uint8_t  btBS;
+  /** Supported receive-bit rate */
+  uint8_t  btBR;
+  /** Timeout value */
+  uint8_t  btTO;
+  /** PP Parameters */
+  uint8_t  btPP;
+  /** General Bytes */
+  uint8_t  abtGB[48];
+  size_t  szGB;
+  /** DEP mode */
+  nfc_dep_mode ndm;
+} nfc_dep_info;
+
+/**
+ * @struct nfc_iso14443a_info
+ * @brief NFC ISO14443A tag (MIFARE) information
+ */
+typedef struct {
+  uint8_t  abtAtqa[2];
+  uint8_t  btSak;
+  size_t  szUidLen;
+  uint8_t  abtUid[10];
+  size_t  szAtsLen;
+  uint8_t  abtAts[254]; // Maximal theoretical ATS is FSD-2, FSD=256 for FSDI=8 in RATS
+} nfc_iso14443a_info;
+
+/**
+ * @struct nfc_felica_info
+ * @brief NFC FeLiCa tag information
+ */
+typedef struct {
+  size_t  szLen;
+  uint8_t  btResCode;
+  uint8_t  abtId[8];
+  uint8_t  abtPad[8];
+  uint8_t  abtSysCode[2];
+} nfc_felica_info;
+
+/**
+ * @struct nfc_iso14443b_info
+ * @brief NFC ISO14443B tag information
+ */
+typedef struct {
+  /** abtPupi store PUPI contained in ATQB (Answer To reQuest of type B) (see ISO14443-3) */
+  uint8_t abtPupi[4];
+  /** abtApplicationData store Application Data contained in ATQB (see ISO14443-3) */
+  uint8_t abtApplicationData[4];
+  /** abtProtocolInfo store Protocol Info contained in ATQB (see ISO14443-3) */
+  uint8_t abtProtocolInfo[3];
+  /** ui8CardIdentifier store CID (Card Identifier) attributted by PCD to the PICC */
+  uint8_t ui8CardIdentifier;
+} nfc_iso14443b_info;
+
+/**
+ * @struct nfc_iso14443bi_info
+ * @brief NFC ISO14443B' tag information
+ */
+typedef struct {
+  /** DIV: 4 LSBytes of tag serial number */
+  uint8_t abtDIV[4];
+  /** Software version & type of REPGEN */
+  uint8_t btVerLog;
+  /** Config Byte, present if long REPGEN */
+  uint8_t btConfig;
+  /** ATR, if any */
+  size_t szAtrLen;
+  uint8_t  abtAtr[33];
+} nfc_iso14443bi_info;
+
+/**
+ * @struct nfc_iso14443b2sr_info
+ * @brief NFC ISO14443-2B ST SRx tag information
+ */
+typedef struct {
+  uint8_t abtUID[8];
+} nfc_iso14443b2sr_info;
+
+/**
+ * @struct nfc_iso14443b2ct_info
+ * @brief NFC ISO14443-2B ASK CTx tag information
+ */
+typedef struct {
+  uint8_t abtUID[4];
+  uint8_t btProdCode;
+  uint8_t btFabCode;
+} nfc_iso14443b2ct_info;
+
+/**
+ * @struct nfc_jewel_info
+ * @brief NFC Jewel tag information
+ */
+typedef struct {
+  uint8_t  btSensRes[2];
+  uint8_t  btId[4];
+} nfc_jewel_info;
+
+/**
+ * @union nfc_target_info
+ * @brief Union between all kind of tags information structures.
+ */
+typedef union {
+  nfc_iso14443a_info nai;
+  nfc_felica_info nfi;
+  nfc_iso14443b_info nbi;
+  nfc_iso14443bi_info nii;
+  nfc_iso14443b2sr_info nsi;
+  nfc_iso14443b2ct_info nci;
+  nfc_jewel_info nji;
+  nfc_dep_info ndi;
+} nfc_target_info;
+
+/**
+ * @enum nfc_baud_rate
+ * @brief NFC baud rate enumeration
+ */
+typedef enum {
+  NBR_UNDEFINED = 0,
+  NBR_106,
+  NBR_212,
+  NBR_424,
+  NBR_847,
+} nfc_baud_rate;
+
+/**
+ * @enum nfc_modulation_type
+ * @brief NFC modulation type enumeration
+ */
+typedef enum {
+  NMT_ISO14443A = 1,
+  NMT_JEWEL,
+  NMT_ISO14443B,
+  NMT_ISO14443BI, // pre-ISO14443B aka ISO/IEC 14443 B' or Type B'
+  NMT_ISO14443B2SR, // ISO14443-2B ST SRx
+  NMT_ISO14443B2CT, // ISO14443-2B ASK CTx
+  NMT_FELICA,
+  NMT_DEP,
+} nfc_modulation_type;
+
+/**
+ * @enum nfc_mode
+ * @brief NFC mode type enumeration
+ */
+typedef enum {
+  N_TARGET,
+  N_INITIATOR,
+} nfc_mode;
+
+/**
+ * @struct nfc_modulation
+ * @brief NFC modulation structure
+ */
+typedef struct {
+  nfc_modulation_type nmt;
+  nfc_baud_rate nbr;
+} nfc_modulation;
+
+/**
+ * @struct nfc_target
+ * @brief NFC target structure
+ */
+typedef struct {
+  nfc_target_info nti;
+  nfc_modulation nm;
+} nfc_target;
+
+// Reset struct alignment to default
+#  pragma pack()
+
+#endif // _LIBNFC_TYPES_H_
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/nfc-nim/nfc.nim	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,605 @@
+## -
+##  Free/Libre Near Field Communication (NFC) library
+##
+##  Libnfc historical contributors:
+##  Copyright (C) 2009      Roel Verdult
+##  Copyright (C) 2009-2013 Romuald Conty
+##  Copyright (C) 2010-2012 Romain Tartière
+##  Copyright (C) 2010-2013 Philippe Teuwen
+##  Copyright (C) 2012-2013 Ludovic Rousseau
+##  See AUTHORS file for a more comprehensive list of contributors.
+##  Additional contributors of this file:
+##
+##  This program is free software: you can redistribute it and/or modify it
+##  under the terms of the GNU Lesser General Public License as published by the
+##  Free Software Foundation, either version 3 of the License, or (at your
+##  option) any later version.
+##
+##  This program is distributed in the hope that it will be useful, but WITHOUT
+##  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+##  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+##  more details.
+##
+##  You should have received a copy of the GNU Lesser General Public License
+##  along with this program.  If not, see <http://www.gnu.org/licenses/>
+##
+
+const
+  nfcLib* = "libnfc.so.5.0.1"
+
+{.deadCodeElim: on.}
+## *
+##  @file nfc.h
+##  @brief libnfc interface
+##
+##  Provide all usefull functions (API) to handle NFC devices.
+##
+
+## -
+##  Free/Libre Near Field Communication (NFC) library
+##
+##  Libnfc historical contributors:
+##  Copyright (C) 2009      Roel Verdult
+##  Copyright (C) 2009-2013 Romuald Conty
+##  Copyright (C) 2010-2012 Romain Tartière
+##  Copyright (C) 2010-2013 Philippe Teuwen
+##  Copyright (C) 2012-2013 Ludovic Rousseau
+##  See AUTHORS file for a more comprehensive list of contributors.
+##  Additional contributors of this file:
+##
+##  This program is free software: you can redistribute it and/or modify it
+##  under the terms of the GNU Lesser General Public License as published by the
+##  Free Software Foundation, either version 3 of the License, or (at your
+##  option) any later version.
+##
+##  This program is distributed in the hope that it will be useful, but WITHOUT
+##  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+##  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+##  more details.
+##
+##  You should have received a copy of the GNU Lesser General Public License
+##  along with this program.  If not, see <http://www.gnu.org/licenses/>
+##
+## *
+##  @file nfc-types.h
+##  @brief Define NFC types
+##
+
+const
+  NFC_BUFSIZE_CONNSTRING* = 1024
+
+## *
+##  NFC context
+##
+
+type
+  context* {.bycopy.} = object
+
+
+## *
+##  NFC device
+##
+
+type
+  device* {.bycopy.} = object
+
+
+## *
+##  NFC device driver
+##
+
+type
+  driver* {.bycopy.} = object
+
+
+## *
+##  Connection string
+##
+
+type
+  connstring* = array[NFC_BUFSIZE_CONNSTRING, char]
+
+## *
+##  Properties
+##
+
+type ## *
+    ##  Default command processing timeout
+    ##  Property value's (duration) unit is ms and 0 means no timeout (infinite).
+    ##  Default value is set by driver layer
+    ##
+  property* {.size: sizeof(cint).} = enum
+    NP_TIMEOUT_COMMAND, ## *
+                       ##  Timeout between ATR_REQ and ATR_RES
+                       ##  When the device is in initiator mode, a target is considered as mute if no
+                       ##  valid ATR_RES is received within this timeout value.
+                       ##  Default value for this property is 103 ms on PN53x based devices.
+                       ##
+    NP_TIMEOUT_ATR, ## *
+                   ##  Timeout value to give up reception from the target in case of no answer.
+                   ##  Default value for this property is 52 ms).
+                   ##
+    NP_TIMEOUT_COM, ## * Let the PN53X chip handle the CRC bytes. This means that the chip appends
+                   ##  the CRC bytes to the frames that are transmitted. It will parse the last
+                   ##  bytes from received frames as incoming CRC bytes. They will be verified
+                   ##  against the used modulation and protocol. If an frame is expected with
+                   ##  incorrect CRC bytes this option should be disabled. Example frames where
+                   ##  this is useful are the ATQA and UID+BCC that are transmitted without CRC
+                   ##  bytes during the anti-collision phase of the ISO14443-A protocol.
+    NP_HANDLE_CRC, ## * Parity bits in the network layer of ISO14443-A are by default generated and
+                  ##  validated in the PN53X chip. This is a very convenient feature. On certain
+                  ##  times though it is useful to get full control of the transmitted data. The
+                  ##  proprietary MIFARE Classic protocol uses for example custom (encrypted)
+                  ##  parity bits. For interoperability it is required to be completely
+                  ##  compatible, including the arbitrary parity bits. When this option is
+                  ##  disabled, the functions to communicating bits should be used.
+    NP_HANDLE_PARITY, ## * This option can be used to enable or disable the electronic field of the
+                     ##  NFC device.
+    NP_ACTIVATE_FIELD, ## * The internal CRYPTO1 co-processor can be used to transmit messages
+                      ##  encrypted. This option is automatically activated after a successful MIFARE
+                      ##  Classic authentication.
+    NP_ACTIVATE_CRYPTO1, ## * The default configuration defines that the PN53X chip will try indefinitely
+                        ##  to invite a tag in the field to respond. This could be desired when it is
+                        ##  certain a tag will enter the field. On the other hand, when this is
+                        ##  uncertain, it will block the application. This option could best be compared
+                        ##  to the (NON)BLOCKING option used by (socket)network programming.
+    NP_INFINITE_SELECT, ## * If this option is enabled, frames that carry less than 4 bits are allowed.
+                       ##  According to the standards these frames should normally be handles as
+                       ##  invalid frames.
+    NP_ACCEPT_INVALID_FRAMES, ## * If the NFC device should only listen to frames, it could be useful to let
+                             ##  it gather multiple frames in a sequence. They will be stored in the internal
+                             ##  FIFO of the PN53X chip. This could be retrieved by using the receive data
+                             ##  functions. Note that if the chip runs out of bytes (FIFO = 64 bytes long),
+                             ##  it will overwrite the first received frames, so quick retrieving of the
+                             ##  received data is desirable.
+    NP_ACCEPT_MULTIPLE_FRAMES, ## * This option can be used to enable or disable the auto-switching mode to
+                              ##  ISO14443-4 is device is compliant.
+                              ##  In initiator mode, it means that NFC chip will send RATS automatically when
+                              ##  select and it will automatically poll for ISO14443-4 card when ISO14443A is
+                              ##  requested.
+                              ##  In target mode, with a NFC chip compliant (ie. PN532), the chip will
+                              ##  emulate a 14443-4 PICC using hardware capability
+    NP_AUTO_ISO14443_4,       ## * Use automatic frames encapsulation and chaining.
+    NP_EASY_FRAMING,          ## * Force the chip to switch in ISO14443-A
+    NP_FORCE_ISO14443_A,      ## * Force the chip to switch in ISO14443-B
+    NP_FORCE_ISO14443_B,      ## * Force the chip to run at 106 kbps
+    NP_FORCE_SPEED_106
+
+
+##  Compiler directive, set struct alignment to 1 uint8_t for compatibility
+
+## *
+##  @enum nfc_dep_mode
+##  @brief NFC D.E.P. (Data Exchange Protocol) active/passive mode
+##
+
+type
+  dep_mode* {.size: sizeof(cint).} = enum
+    NDM_UNDEFINED = 0, NDM_PASSIVE, NDM_ACTIVE
+
+
+## *
+##  @struct nfc_dep_info
+##  @brief NFC target information in D.E.P. (Data Exchange Protocol) see ISO/IEC 18092 (NFCIP-1)
+##
+
+type
+  dep_info* {.bycopy.} = object
+    abtNFCID3*: array[10, uint8] ## * NFCID3
+    ## * DID
+    btDID*: uint8              ## * Supported send-bit rate
+    btBS*: uint8               ## * Supported receive-bit rate
+    btBR*: uint8               ## * Timeout value
+    btTO*: uint8               ## * PP Parameters
+    btPP*: uint8               ## * General Bytes
+    abtGB*: array[48, uint8]
+    szGB*: csize               ## * DEP mode
+    ndm*: dep_mode
+
+
+## *
+##  @struct nfc_iso14443a_info
+##  @brief NFC ISO14443A tag (MIFARE) information
+##
+
+type
+  iso14443a_info* {.bycopy.} = object
+    abtAtqa*: array[2, uint8]
+    btSak*: uint8
+    szUidLen*: csize
+    abtUid*: array[10, uint8]
+    szAtsLen*: csize
+    abtAts*: array[254, uint8]  ##  Maximal theoretical ATS is FSD-2, FSD=256 for FSDI=8 in RATS
+
+
+## *
+##  @struct nfc_felica_info
+##  @brief NFC FeLiCa tag information
+##
+
+type
+  felica_info* {.bycopy.} = object
+    szLen*: csize
+    btResCode*: uint8
+    abtId*: array[8, uint8]
+    abtPad*: array[8, uint8]
+    abtSysCode*: array[2, uint8]
+
+
+## *
+##  @struct nfc_iso14443b_info
+##  @brief NFC ISO14443B tag information
+##
+
+type
+  iso14443b_info* {.bycopy.} = object
+    abtPupi*: array[4, uint8]   ## * abtPupi store PUPI contained in ATQB (Answer To reQuest of type B) (see ISO14443-3)
+    ## * abtApplicationData store Application Data contained in ATQB (see ISO14443-3)
+    abtApplicationData*: array[4, uint8] ## * abtProtocolInfo store Protocol Info contained in ATQB (see ISO14443-3)
+    abtProtocolInfo*: array[3, uint8] ## * ui8CardIdentifier store CID (Card Identifier) attributted by PCD to the PICC
+    ui8CardIdentifier*: uint8
+
+
+## *
+##  @struct nfc_iso14443bi_info
+##  @brief NFC ISO14443B' tag information
+##
+
+type
+  iso14443bi_info* {.bycopy.} = object
+    abtDIV*: array[4, uint8]    ## * DIV: 4 LSBytes of tag serial number
+    ## * Software version & type of REPGEN
+    btVerLog*: uint8           ## * Config Byte, present if long REPGEN
+    btConfig*: uint8           ## * ATR, if any
+    szAtrLen*: csize
+    abtAtr*: array[33, uint8]
+
+
+## *
+##  @struct nfc_iso14443b2sr_info
+##  @brief NFC ISO14443-2B ST SRx tag information
+##
+
+type
+  iso14443b2sr_info* {.bycopy.} = object
+    abtUID*: array[8, uint8]
+
+
+## *
+##  @struct nfc_iso14443b2ct_info
+##  @brief NFC ISO14443-2B ASK CTx tag information
+##
+
+type
+  iso14443b2ct_info* {.bycopy.} = object
+    abtUID*: array[4, uint8]
+    btProdCode*: uint8
+    btFabCode*: uint8
+
+
+## *
+##  @struct nfc_jewel_info
+##  @brief NFC Jewel tag information
+##
+
+type
+  jewel_info* {.bycopy.} = object
+    btSensRes*: array[2, uint8]
+    btId*: array[4, uint8]
+
+
+## *
+##  @union nfc_target_info
+##  @brief Union between all kind of tags information structures.
+##
+
+type
+  target_info* {.bycopy.} = object {.union.}
+    nai*: iso14443a_info
+    nfi*: felica_info
+    nbi*: iso14443b_info
+    nii*: iso14443bi_info
+    nsi*: iso14443b2sr_info
+    nci*: iso14443b2ct_info
+    nji*: jewel_info
+    ndi*: dep_info
+
+
+## *
+##  @enum nfc_baud_rate
+##  @brief NFC baud rate enumeration
+##
+
+type
+  baud_rate* {.size: sizeof(cint).} = enum
+    NBR_UNDEFINED = 0, NBR_106, NBR_212, NBR_424, NBR_847
+
+
+## *
+##  @enum nfc_modulation_type
+##  @brief NFC modulation type enumeration
+##
+
+type
+  modulation_type* {.size: sizeof(cint).} = enum
+    NMT_ISO14443A = 1, NMT_JEWEL, NMT_ISO14443B, NMT_ISO14443BI, ##  pre-ISO14443B aka ISO/IEC 14443 B' or Type B'
+    NMT_ISO14443B2SR,         ##  ISO14443-2B ST SRx
+    NMT_ISO14443B2CT,         ##  ISO14443-2B ASK CTx
+    NMT_FELICA, NMT_DEP
+
+
+## *
+##  @enum nfc_mode
+##  @brief NFC mode type enumeration
+##
+
+type
+  mode* {.size: sizeof(cint).} = enum
+    N_TARGET, N_INITIATOR
+
+
+## *
+##  @struct nfc_modulation
+##  @brief NFC modulation structure
+##
+
+type
+  modulation* {.bycopy.} = object
+    nmt*: modulation_type
+    nbr*: baud_rate
+
+
+## *
+##  @struct nfc_target
+##  @brief NFC target structure
+##
+
+type
+  target* {.bycopy.} = object
+    nti*: target_info
+    nm*: modulation
+
+
+##  Reset struct alignment to default
+
+##  Library initialization/deinitialization
+
+proc init*(context: ptr ptr context) {.cdecl, importc: "nfc_init", dynlib: nfcLib.}
+proc exit*(context: ptr context) {.cdecl, importc: "nfc_exit", dynlib: nfcLib.}
+proc register_driver*(driver: ptr driver): cint {.cdecl,
+    importc: "nfc_register_driver", dynlib: nfcLib.}
+##  NFC Device/Hardware manipulation
+
+proc open*(context: ptr context; connstring: connstring): ptr device {.cdecl,
+    importc: "nfc_open", dynlib: nfcLib.}
+proc close*(pnd: ptr device) {.cdecl, importc: "nfc_close", dynlib: nfcLib.}
+proc abort_command*(pnd: ptr device): cint {.cdecl, importc: "nfc_abort_command",
+                                        dynlib: nfcLib.}
+proc list_devices*(context: ptr context; connstrings: ptr connstring;
+                  connstrings_len: csize): csize {.cdecl,
+    importc: "nfc_list_devices", dynlib: nfcLib.}
+proc idle*(pnd: ptr device): cint {.cdecl, importc: "nfc_idle", dynlib: nfcLib.}
+##  NFC initiator: act as "reader"
+
+proc initiator_init*(pnd: ptr device): cint {.cdecl, importc: "nfc_initiator_init",
+    dynlib: nfcLib.}
+proc initiator_init_secure_element*(pnd: ptr device): cint {.cdecl,
+    importc: "nfc_initiator_init_secure_element", dynlib: nfcLib.}
+proc initiator_select_passive_target*(pnd: ptr device; nm: modulation;
+                                     pbtInitData: ptr uint8; szInitData: csize;
+                                     pnt: ptr target): cint {.cdecl,
+    importc: "nfc_initiator_select_passive_target", dynlib: nfcLib.}
+proc initiator_list_passive_targets*(pnd: ptr device; nm: modulation; ant: ptr target;
+                                    szTargets: csize): cint {.cdecl,
+    importc: "nfc_initiator_list_passive_targets", dynlib: nfcLib.}
+proc initiator_poll_target*(pnd: ptr device; pnmTargetTypes: ptr modulation;
+                           szTargetTypes: csize; uiPollNr: uint8; uiPeriod: uint8;
+                           pnt: ptr target): cint {.cdecl,
+    importc: "nfc_initiator_poll_target", dynlib: nfcLib.}
+proc initiator_select_dep_target*(pnd: ptr device; ndm: dep_mode; nbr: baud_rate;
+                                 pndiInitiator: ptr dep_info; pnt: ptr target;
+                                 timeout: cint): cint {.cdecl,
+    importc: "nfc_initiator_select_dep_target", dynlib: nfcLib.}
+proc initiator_poll_dep_target*(pnd: ptr device; ndm: dep_mode; nbr: baud_rate;
+                               pndiInitiator: ptr dep_info; pnt: ptr target;
+                               timeout: cint): cint {.cdecl,
+    importc: "nfc_initiator_poll_dep_target", dynlib: nfcLib.}
+proc initiator_deselect_target*(pnd: ptr device): cint {.cdecl,
+    importc: "nfc_initiator_deselect_target", dynlib: nfcLib.}
+proc initiator_transceive_bytes*(pnd: ptr device; pbtTx: ptr uint8; szTx: csize;
+                                pbtRx: ptr uint8; szRx: csize; timeout: cint): cint {.
+    cdecl, importc: "nfc_initiator_transceive_bytes", dynlib: nfcLib.}
+proc initiator_transceive_bits*(pnd: ptr device; pbtTx: ptr uint8; szTxBits: csize;
+                               pbtTxPar: ptr uint8; pbtRx: ptr uint8; szRx: csize;
+                               pbtRxPar: ptr uint8): cint {.cdecl,
+    importc: "nfc_initiator_transceive_bits", dynlib: nfcLib.}
+proc initiator_transceive_bytes_timed*(pnd: ptr device; pbtTx: ptr uint8; szTx: csize;
+                                      pbtRx: ptr uint8; szRx: csize;
+                                      cycles: ptr uint32): cint {.cdecl,
+    importc: "nfc_initiator_transceive_bytes_timed", dynlib: nfcLib.}
+proc initiator_transceive_bits_timed*(pnd: ptr device; pbtTx: ptr uint8;
+                                     szTxBits: csize; pbtTxPar: ptr uint8;
+                                     pbtRx: ptr uint8; szRx: csize;
+                                     pbtRxPar: ptr uint8; cycles: ptr uint32): cint {.
+    cdecl, importc: "nfc_initiator_transceive_bits_timed", dynlib: nfcLib.}
+proc initiator_target_is_present*(pnd: ptr device; pnt: ptr target): cint {.cdecl,
+    importc: "nfc_initiator_target_is_present", dynlib: nfcLib.}
+##  NFC target: act as tag (i.e. MIFARE Classic) or NFC target device.
+
+proc target_init*(pnd: ptr device; pnt: ptr target; pbtRx: ptr uint8; szRx: csize;
+                 timeout: cint): cint {.cdecl, importc: "nfc_target_init",
+                                     dynlib: nfcLib.}
+proc target_send_bytes*(pnd: ptr device; pbtTx: ptr uint8; szTx: csize; timeout: cint): cint {.
+    cdecl, importc: "nfc_target_send_bytes", dynlib: nfcLib.}
+proc target_receive_bytes*(pnd: ptr device; pbtRx: ptr uint8; szRx: csize; timeout: cint): cint {.
+    cdecl, importc: "nfc_target_receive_bytes", dynlib: nfcLib.}
+proc target_send_bits*(pnd: ptr device; pbtTx: ptr uint8; szTxBits: csize;
+                      pbtTxPar: ptr uint8): cint {.cdecl,
+    importc: "nfc_target_send_bits", dynlib: nfcLib.}
+proc target_receive_bits*(pnd: ptr device; pbtRx: ptr uint8; szRx: csize;
+                         pbtRxPar: ptr uint8): cint {.cdecl,
+    importc: "nfc_target_receive_bits", dynlib: nfcLib.}
+##  Error reporting
+
+proc strerror*(pnd: ptr device): cstring {.cdecl, importc: "nfc_strerror",
+                                      dynlib: nfcLib.}
+proc strerror_r*(pnd: ptr device; buf: cstring; buflen: csize): cint {.cdecl,
+    importc: "nfc_strerror_r", dynlib: nfcLib.}
+proc perror*(pnd: ptr device; s: cstring) {.cdecl, importc: "nfc_perror", dynlib: nfcLib.}
+proc device_get_last_error*(pnd: ptr device): cint {.cdecl,
+    importc: "nfc_device_get_last_error", dynlib: nfcLib.}
+##  Special data accessors
+
+proc device_get_name*(pnd: ptr device): cstring {.cdecl,
+    importc: "nfc_device_get_name", dynlib: nfcLib.}
+proc device_get_connstring*(pnd: ptr device): cstring {.cdecl,
+    importc: "nfc_device_get_connstring", dynlib: nfcLib.}
+proc device_get_supported_modulation*(pnd: ptr device; mode: mode;
+                                     supported_mt: ptr ptr modulation_type): cint {.
+    cdecl, importc: "nfc_device_get_supported_modulation", dynlib: nfcLib.}
+proc device_get_supported_baud_rate*(pnd: ptr device; nmt: modulation_type;
+                                    supported_br: ptr ptr baud_rate): cint {.cdecl,
+    importc: "nfc_device_get_supported_baud_rate", dynlib: nfcLib.}
+##  Properties accessors
+
+proc device_set_property_int*(pnd: ptr device; property: property; value: cint): cint {.
+    cdecl, importc: "nfc_device_set_property_int", dynlib: nfcLib.}
+proc device_set_property_bool*(pnd: ptr device; property: property; bEnable: bool): cint {.
+    cdecl, importc: "nfc_device_set_property_bool", dynlib: nfcLib.}
+##  Misc. functions
+
+proc iso14443a_crc*(pbtData: ptr uint8; szLen: csize; pbtCrc: ptr uint8) {.cdecl,
+    importc: "iso14443a_crc", dynlib: nfcLib.}
+proc iso14443a_crc_append*(pbtData: ptr uint8; szLen: csize) {.cdecl,
+    importc: "iso14443a_crc_append", dynlib: nfcLib.}
+proc iso14443b_crc*(pbtData: ptr uint8; szLen: csize; pbtCrc: ptr uint8) {.cdecl,
+    importc: "iso14443b_crc", dynlib: nfcLib.}
+proc iso14443b_crc_append*(pbtData: ptr uint8; szLen: csize) {.cdecl,
+    importc: "iso14443b_crc_append", dynlib: nfcLib.}
+proc iso14443a_locate_historical_bytes*(pbtAts: ptr uint8; szAts: csize;
+                                       pszTk: ptr csize): ptr uint8 {.cdecl,
+    importc: "iso14443a_locate_historical_bytes", dynlib: nfcLib.}
+proc free*(p: pointer) {.cdecl, importc: "nfc_free", dynlib: nfcLib.}
+proc version*(): cstring {.cdecl, importc: "nfc_version", dynlib: nfcLib.}
+proc device_get_information_about*(pnd: ptr device; buf: cstringArray): cint {.cdecl,
+    importc: "nfc_device_get_information_about", dynlib: nfcLib.}
+##  String converter functions
+
+proc str_nfc_modulation_type*(nmt: modulation_type): cstring {.cdecl,
+    importc: "str_nfc_modulation_type", dynlib: nfcLib.}
+proc str_nfc_baud_rate*(nbr: baud_rate): cstring {.cdecl,
+    importc: "str_nfc_baud_rate", dynlib: nfcLib.}
+proc str_nfc_target*(buf: cstringArray; pnt: ptr target; verbose: bool): cint {.cdecl,
+    importc: "str_nfc_target", dynlib: nfcLib.}
+##  Error codes
+## * @ingroup error
+##  @hideinitializer
+##  Success (no error)
+##
+
+const
+  NFC_SUCCESS* = 0
+
+## * @ingroup error
+##  @hideinitializer
+##  Input / output error, device may not be usable anymore without re-open it
+##
+
+const
+  NFC_EIO* = -1
+
+## * @ingroup error
+##  @hideinitializer
+##  Invalid argument(s)
+##
+
+const
+  NFC_EINVARG* = -2
+
+## * @ingroup error
+##  @hideinitializer
+##   Operation not supported by device
+##
+
+const
+  NFC_EDEVNOTSUPP* = -3
+
+## * @ingroup error
+##  @hideinitializer
+##  No such device
+##
+
+const
+  NFC_ENOTSUCHDEV* = -4
+
+## * @ingroup error
+##  @hideinitializer
+##  Buffer overflow
+##
+
+const
+  NFC_EOVFLOW* = -5
+
+## * @ingroup error
+##  @hideinitializer
+##  Operation timed out
+##
+
+const
+  NFC_ETIMEOUT* = -6
+
+## * @ingroup error
+##  @hideinitializer
+##  Operation aborted (by user)
+##
+
+const
+  NFC_EOPABORTED* = -7
+
+## * @ingroup error
+##  @hideinitializer
+##  Not (yet) implemented
+##
+
+const
+  NFC_ENOTIMPL* = -8
+
+## * @ingroup error
+##  @hideinitializer
+##  Target released
+##
+
+const
+  NFC_ETGRELEASED* = -10
+
+## * @ingroup error
+##  @hideinitializer
+##  Error while RF transmission
+##
+
+const
+  NFC_ERFTRANS* = -20
+
+## * @ingroup error
+##  @hideinitializer
+##  MIFARE Classic: authentication failed
+##
+
+const
+  NFC_EMFCAUTHFAIL* = -30
+
+## * @ingroup error
+##  @hideinitializer
+##  Software error (allocation, file/pipe creation, etc.)
+##
+
+const
+  NFC_ESOFT* = -80
+
+## * @ingroup error
+##  @hideinitializer
+##  Device's internal chip error
+##
+
+const
+  NFC_ECHIP* = -90
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/option_test.nim	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,20 @@
+import options
+
+type
+  Base = ref object of RootObj
+  A = ref object of Base
+  B = ref object of Base
+    opt: Option[A]
+
+proc `==`(x: A, y: B): bool = false
+
+proc initA(): A =
+  new result
+
+proc initB(): B =
+  new result
+  result.opt = none(A)
+  echo "saved none"
+
+let x = initB()
+assert x.opt.isNone()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/rdf.nim	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,76 @@
+import algorithm
+import hashes
+import json
+import sequtils
+import sets
+import strformat
+import strutils
+
+import rdf_nodes
+
+type Namespace* = object of RootObj
+  prefix: string
+  
+proc initNamespace*(prefix: string): Namespace =
+  result.prefix = prefix
+
+proc `[]`*(self: Namespace, tail: string): Uri =
+  initUri(self.prefix & tail)
+
+
+type Quad* = tuple[s: Uri, p: Uri, o: RdfNode, g: Uri]
+     
+proc toJsonLd*(quads: HashSet[Quad]): string =
+  var graphs: HashSet[Uri] = toSet[Uri]([])
+  graphs.init()
+  for q in quads:
+    graphs.incl(q.g)
+  var graphUris = toSeq[Uri](graphs.items)
+  graphUris.sort(cmpUri)
+  var graphJson = newJArray()
+  for g in graphUris:
+    var quadsInGraph: seq[JsonNode]
+    for q in quads:
+      if q.g == g:
+        quadsInGraph.add(%* {"@id": $q.s, $q.p: [toJsonLdObject(q.o)]})
+      
+    graphJson.add(%* {"@graph": quadsInGraph, "@id": $g})
+  $graphJson
+    
+
+proc hash*(x: Quad): Hash =
+  hash(1)
+
+type Patch* = object of RootObj
+  addQuads*: HashSet[Quad]
+  delQuads*: HashSet[Quad]
+
+proc toJson*(self: Patch): string =
+  $ %* {"patch" : {"adds": self.addQuads.toJsonLd(),
+                   "deletes": self.delQuads.toJsonLd()}}
+  
+  
+type Graph* = object of RootObj
+  stmts*: HashSet[Quad]
+
+proc len*(self: Graph): int = len(self.stmts)
+  
+proc initGraph*(): Graph =
+  result.stmts.init()
+
+proc applyPatch*(self: var Graph, p: Patch) =
+  self.stmts.excl(p.delQuads)
+  self.stmts.incl(p.addQuads)
+
+proc toNquads*(self: var Graph): string =
+  var lines: seq[string] = @[]
+  for q in self.stmts:
+    lines.add(&"{q.s.toNt()} {q.p.toNt()} {q.o.toNt()} {q.g.toNt()} .\n")
+  return lines.join("")
+
+proc toNtriples*(stmts: openArray[Quad]): string =
+  var lines: seq[string] = @[]
+  for q in stmts:
+    lines.add(&"{q.s.toNt()} {q.p.toNt()} {q.o.toNt()} .\n")
+  return lines.join("")
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/rdf_nodes.nim	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,86 @@
+import options
+import hashes
+import strformat
+import json
+
+# consider https://nim-lang.org/docs/uri.html
+
+type
+  RdfNode* = ref object of RootObj
+  Uri* = ref object of RdfNode
+    s2: string
+  Literal* = ref object of RdfNode
+    value: string
+    dataType: Option[Uri]
+
+proc initUri*(s: string): Uri =
+  new result
+  result.s2 = s
+
+proc cmpUri*(x, y: Uri): int =
+  system.cmp(x.s2, y.s2)
+  
+proc `$`*(self: Uri): string =
+  return self.s2
+
+method toNt*(self: RdfNode): string {.base,gcsafe.} =
+  "<<rdfnode>>"
+
+method toNt*(self: Uri): string =
+  "<" & self.s2 & ">"
+
+proc hash*(x: RdfNode): Hash =
+  hash(0)
+  
+func hash*(x: Uri): Hash {.inline.} =
+  hash(x.s2)
+  
+#proc `==`*(x: Uri, y: Literal): bool = false
+#proc `==`*(x: Literal, y: Uri): bool = false
+#proc `==`*(x: RdfNode, y: RdfNode): bool =
+#  echo "rdfnode comp"
+#  true
+
+  
+proc initLiteral*(s: string): Literal =
+  new result
+  result.value = s
+  result.dataType = none(Uri)
+
+proc initLiteral*(s: cstring): Literal =
+  new result
+  result.value = $s
+  result.dataType = none(Uri)
+
+proc initLiteral*(s: string, dataType: Uri): Literal =
+  new result
+  result.value = s
+  result.dataType = some(dataType)
+
+# proc initLiteral*(x: int): Literal =
+# proc initLiteral*(x: float): Literal =
+# ...
+
+proc hash*(x: Literal): Hash =
+  hash(x.value) # maybe datatype
+
+method toNt*(self: Literal): string =
+  var dtPart: string = ""
+  if isSome(self.dataType):
+    let dt: Uri = self.dataType.get()
+    dtPart = "^^" & dt.toNt()
+
+  return "\"" & self.value & "\"" & dtPart
+
+
+method toJsonLdObject*(self: RdfNode): JsonNode {.base,gcsafe.} =
+  %* {"some": "rdfnode"}
+
+method toJsonLdObject*(self: Uri): JsonNode =
+  %* {"@id": self.s2}
+
+method toJsonLdObject*(self: Literal): JsonNode =
+  %* {"@value": $self.value}
+  # and datatype and lang
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/rdf_test.nim	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,44 @@
+import sets
+import unittest
+import rdf
+import rdf_nodes
+import strformat
+
+suite "rdf":
+  let EX = initNamespace("http://example.com/")
+  test "construct quad with uri obj":
+    let q: Quad = (EX["a"], EX["b"], EX["c"], EX["d"])
+
+  test "construct quad with string literal obj":
+    let q: Quad = (EX["a"], EX["b"], initLiteral("hi"), EX["d"])
+
+  test "construct quad with typed literal obj":
+    let q: Quad = (EX["a"], EX["b"], initLiteral("hi", EX["dt"]), EX["d"])
+
+  test "uri can be used in a set":
+    let uris = toSet[Uri]([EX["a"]])
+    
+  test "quad can be used in a set":
+    let q1 = Quad((EX["a"], EX["b"], EX["c"], EX["ctx"]))
+    let quads = toSet([q1])
+    
+  test "uri stringify":
+    require($EX["a"] == "http://example.com/a")
+
+  test "quads to json":
+    let q1 = Quad((EX["a"], EX["b"], EX["c"], EX["ctx"]))
+    let q2 = Quad((EX["a"], EX["b"], EX["c2"], EX["ctx2"]))
+    require(toJsonLd(toSet([q1, q2])) == """[{"@graph":[{"@id":"http://example.com/a","http://example.com/b":["http://example.com/c"]}],"@id":"http://example.com/ctx"},{"@graph":[{"@id":"http://example.com/a","http://example.com/b":["http://example.com/c2"]}],"@id":"http://example.com/ctx2"}]""")
+
+  test "uri toNt":
+    require(EX["a"].toNt() == "<http://example.com/a>")
+
+  test "string literal toNt":
+    let n = initLiteral("hi")
+    require(n.toNt() == "\"hi\"")
+
+  test "string literal with dataType toNt":
+    let n = initLiteral("3.14", initUri("http://www.w3.org/2001/XMLSchema#float"))
+    require(n.toNt() == "\"3.14\"^^<http://www.w3.org/2001/XMLSchema#float>")
+    
+    
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/requirements.txt	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,8 @@
+docopt
+rdflib-jsonld==0.4.0
+rdflib==4.2.2
+https://projects.bigasterisk.com/rdfdb/rdfdb-0.7.0.tar.gz
+git+http://github.com/drewp/scales.git@448d59fb491b7631877528e7695a93553bfaaa93#egg=scales
+#git+https://github.com/derboblan/pynfc.git@38ebcce26a982a50c96932ce1212f9376177ba1e#egg=pynfc
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532/rfid.py	Sun Apr 21 03:28:21 2019 -0700
@@ -0,0 +1,252 @@
+# not in use- see rfid.nim
+
+import os
+from docopt import docopt
+from rdfdb.patch import Patch
+from patchablegraph import PatchableGraph, CycloneGraphHandler, CycloneGraphEventsHandler
+from rdflib import Namespace, URIRef, Literal, Graph
+from rdflib.parser import StringInputSource
+from twisted.internet import reactor, task, defer
+import cyclone.web
+from cyclone.httpclient import fetch
+import logging, time, json, random, string
+from logsetup import log, enableTwistedLog
+import private
+from greplin import scales
+from greplin.scales.cyclonehandler import StatsHandler
+from pynfc.ntag_read import NTagReadWrite
+
+ROOM = Namespace('http://projects.bigasterisk.com/room/')
+
+ctx = ROOM['frontDoorWindowRfidCtx']
+
+cardOwner = {
+    URIRef('http://bigasterisk.com/rfidCard/93a7591a77'):
+    URIRef('http://bigasterisk.com/foaf.rdf#drewp'),
+}
+
+STATS = scales.collection('/web',
+                          scales.PmfStat('cardReadPoll'),
+)
+def rdfGraphBody(body, headers):
+    g = Graph()
+    g.parse(StringInputSource(body), format='nt')
+    return g
+
+class OutputPage(cyclone.web.RequestHandler):
+    def put(self):
+        user = URIRef(self.request.headers['x-foaf-agent'])
+        arg = self.request.arguments
+        if arg.get('s') and arg.get('p'):
+            subj = URIRef(arg['s'][-1])
+            pred = URIRef(arg['p'][-1])
+            obj = URIRef(self.request.body)
+            stmt = (subj, pred, obj)
+        else:
+            g = rdfGraphBody(self.request.body, self.request.headers)
+            assert len(g) == 1, len(g)
+            stmt = g.triples((None, None, None)).next()
+        self._onStatement(user, stmt)
+    post = put
+    
+    def _onStatement(self, user, stmt):
+        # write rfid to new key, etc.
+        if stmt[1] == ROOM['keyContents']:
+            return
+        log.warn("ignoring %s", stmt)
+
+def uidUri(card_id):
+    return URIRef('http://bigasterisk.com/rfidCard/%s' %
+                  binascii.hexlify(card_id))
+        
+def uidArray(uri):
+    prefix, h = uri.rsplit('/', 1)
+    if prefix != 'http://bigasterisk.com/rfidCard':
+        raise ValueError(uri)
+    return [int(h[i * 2: i * 2 + 2], 16) for i in range(0, len(h), 2)]
+        
+class Rewrite(cyclone.web.RequestHandler):
+    def post(self):
+        agent = URIRef(self.request.headers['x-foaf-agent'])
+        body = json.loads(self.request.body)
+
+        _, uid = reader.read_id()
+        log.info('current card id: %r %r', _, uid)
+        if uid is None:
+            self.set_status(404, "no card present")
+            # maybe retry a few more times since the card might be nearby
+            return
+            
+        text = ''.join(random.choice(string.uppercase) for n in range(32))
+        log.info('%s rewrites %s to %s, to be owned by %s', 
+                 agent, uid, text, body['user'])
+        
+        #reader.KEY = private.rfid_key
+        reader.write(uid, text)
+        log.info('done with write')
+
+    
+sensor = ROOM['frontDoorWindowRfid']
+from pynfc.ntag_read import TagType
+import binascii
+class ReadLoop(object):
+    def __init__(self, reader, masterGraph):
+        self.reader = reader
+        self.masterGraph = masterGraph
+        self.log = {} # cardIdUri : most recent seentime
+
+        self.pollPeriodSecs = .1
+        self.expireSecs = 2
+        
+        task.LoopingCall(self.poll).start(self.pollPeriodSecs)
+
+    @STATS.cardReadPoll.time()
+    def poll(self):
+        now = time.time()
+
+        self.flushOldReads(now)
+
+        log.info('scanning for cards')
+        uids = self.reader.list_targets()
+        log.info(f'reader sees {uids}')
+        if len(uids) > 1:
+            print("Found {count} uids: {uids}. Please remove all but one from the device".format(count=len(uids), uids=uids))
+            return
+
+        tt = TagType.NTAG_216
+
+        print('detrm tag type', self.reader.determine_tag_type())
+
+        
+        uid = self.reader.setup_target()
+        print("uid = {}".format(binascii.hexlify(uid)))
+
+        self.reader.set_easy_framing()
+        um_fast = self.reader.read_user_memory(tt)
+
+        print(f'read {um_fast} on {uids[0]}')
+        text = um_fast
+
+        cardIdUri = uidUri(uid)
+        textLit = Literal(text.rstrip().decode('ascii', 'replace'))
+
+        is_new = cardIdUri not in self.log
+        self.log[cardIdUri] = now
+        if is_new:
+            self.startCardRead(cardIdUri, textLit)
+        
+    def flushOldReads(self, now):
+        for uri in self.log.keys():
+            if self.log[uri] < now - self.expireSecs:
+                self.endCardRead(uri)
+                del self.log[uri]
+
+    def startCardRead(self, cardUri, text):
+        p = Patch(addQuads=[(sensor, ROOM['reading'], cardUri, ctx),
+                            (cardUri, ROOM['cardText'], text, ctx)],
+                  delQuads=[])
+        self.masterGraph.patch(p)
+        log.info('read card: id=%s %r', cardUri, str(text))
+        self._sendOneshot([(sensor, ROOM['startReading'], cardUri),
+                            (cardUri, ROOM['cardText'], text)])
+
+    def endCardRead(self, cardUri):
+        delQuads = []
+        for spo in self.masterGraph._graph.triples(
+                (sensor, ROOM['reading'], cardUri)):
+            delQuads.append(spo + (ctx,))
+        for spo in self.masterGraph._graph.triples(
+                (cardUri, ROOM['cardText'], None)):
+            delQuads.append(spo + (ctx,))
+            
+        self.masterGraph.patch(Patch(addQuads=[], delQuads=delQuads))
+        
+    def _sendOneshot(self, oneshot):
+        body = (' '.join('%s %s %s .' % (s.n3(), p.n3(), o.n3())
+                         for s,p,o in oneshot)).encode('utf8')
+        url = 'http://bang6:9071/oneShot'
+        d = fetch(method='POST',
+                  url=url,
+                  headers={'Content-Type': ['text/n3']},
+                  postdata=body,
+                  timeout=5)
+        def err(e):
+            log.info('oneshot post to %r failed:  %s',
+                     url, e.getErrorMessage())
+        d.addErrback(err)
+
+                                                              
+        
+if __name__ == '__main__':
+    arg = docopt("""
+    Usage: rfid.py [options]
+
+    -v   Verbose
+    """)
+    log.setLevel(logging.INFO)
+    if arg['-v']:
+        enableTwistedLog()
+        log.setLevel(logging.DEBUG)
+        defer.setDebugging(True)
+        print('defer log')
+
+    masterGraph = PatchableGraph()
+    os.environ['LIBNFC_DEFAULT_DEVICE'] = "pn532_i2c:/dev/i2c-1"
+
+
+    import ctypes
+    import pynfc.mifareauth
+    r = pynfc.mifareauth.NFCReader(log.info)
+    while True:
+        try:
+            r.run()
+        except IOError:
+            pass
+            
+#    import pynfc as nfc
+#    context = ctypes.pointer(nfc.nfc_context())
+#    nfc.nfc_init(ctypes.byref(context))
+#
+#    conn_strings = (nfc.nfc_connstring * 10)()
+#    devices_found = nfc.nfc_list_devices(context, conn_strings, 10)
+#    device = nfc.nfc_open(context, conn_strings[0])
+#    r.__device = device
+#    
+#    print('initd')
+#    try:
+#        print('selecting')
+#        uid = r.select_card()
+#        print('sel', uid)
+#        r.read_card(uid)
+#        
+#    finally:
+#        nfc.nfc_close(dev)
+    
+    #conn_strings = (nfc.nfc_connstring * 10)()
+    #devices_found = nfc.nfc_list_devices(
+    #    context, conn_strings, 10)
+    #if devices_found >= 1:
+    #    dev = nfc.nfc_open(context, conn_strings[0])
+    #try:
+    #    _ = nfc.nfc_initiator_init(dev)
+    #    print(f'found {dev.}')
+
+    1/0
+    reader = NTagReadWrite(log)
+
+    loop = ReadLoop(reader, masterGraph)
+
+    port = 10012
+    reactor.listenTCP(port, cyclone.web.Application([
+        (r"/()", cyclone.web.StaticFileHandler,
+         {"path": ".", "default_filename": "index.html"}),
+        (r"/graph", CycloneGraphHandler, {'masterGraph': masterGraph}),
+        (r"/graph/events", CycloneGraphEventsHandler,
+         {'masterGraph': masterGraph}),
+        (r'/output', OutputPage),
+        (r'/rewrite', Rewrite),
+        (r'/stats/(.*)', StatsHandler, {'serverName': 'rfid'}),
+        ], masterGraph=masterGraph, debug=arg['-v']), interface='::')
+    log.warn('serving on %s', port)
+
+    reactor.run()