# HG changeset patch # User drewp # Date 1555842501 25200 # Node ID 68e172d9791ebcafbae178fdb87e8f39ace22aed # Parent b54164bcded33b1c46703bb054695e95a4b702c5 add missing files for the record Ignore-this: 8541c95ef1644cf85b311259602d2892 darcs-hash:1e575d63deb747c9c320daa32f27f0ce93621afb diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/Dockerfile.graphserver --- /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" ] diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/Dockerfile.graphserver.pi --- /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" ] diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/ev.nim --- /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() diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/freefare_demo.nim --- /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) diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/graphserver.py --- /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() diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/hashobj.nim --- /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")]) diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/nfc-nim/freefare.nim --- /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 diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/nfc-nim/nfc-emulation.h --- /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 + */ + +/** + * @file nfc-emulation.h + * @brief Provide a small API to ease emulation in libnfc + */ + +#ifndef __NFC_EMULATION_H__ +#define __NFC_EMULATION_H__ + +#include +#include + +#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__ */ diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/nfc-nim/nfc-types.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 + */ + +/** + * @file nfc-types.h + * @brief Define NFC types + */ + +#ifndef __NFC_TYPES_H__ +#define __NFC_TYPES_H__ + +#include +#include +#include +#include + +#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_ diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/nfc-nim/nfc.nim --- /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 +## + +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 +## +## * +## @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 diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/option_test.nim --- /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() diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/rdf.nim --- /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("") + diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/rdf_nodes.nim --- /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.} = + "<>" + +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 + + diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/rdf_test.nim --- /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() == "") + + 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\"^^") + + diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/requirements.txt --- /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 + + diff -r b54164bcded3 -r 68e172d9791e service/rfid_pn532/rfid.py --- /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()