Mercurial > code > home > repos > homeauto
changeset 1526:c476543e761e
rename rfid_pn532_py
Ignore-this: 89356f780bb5df4d9ec639c44d2a3a67
darcs-hash:212e7f3250cf67ce80922597188d33547d41b0f8
author | drewp <drewp@bigasterisk.com> |
---|---|
date | Wed, 05 Feb 2020 16:40:46 -0800 |
parents | ce118c7c06d9 |
children | ed3d29eb989a |
files | service/cardReader/Dockerfile.pi service/cardReader/Dockerfile.pyfreefare.pi service/cardReader/Dockerfile.pyfreefare.x86 service/cardReader/Dockerfile.x86 service/cardReader/build_ctypes_modules.sh service/cardReader/index.html service/cardReader/local.conf service/cardReader/makefile service/cardReader/pyfreefare/freefare.h service/cardReader/pyfreefare/nfc.h service/cardReader/requirements.txt service/cardReader/rfid-console.html service/cardReader/rfid.py service/cardReader/tags.py service/cardReader/tags_test.py service/rfid_pn532_py/Dockerfile.pi service/rfid_pn532_py/Dockerfile.pyfreefare.pi service/rfid_pn532_py/Dockerfile.pyfreefare.x86 service/rfid_pn532_py/Dockerfile.x86 service/rfid_pn532_py/build_ctypes_modules.sh service/rfid_pn532_py/index.html service/rfid_pn532_py/local.conf service/rfid_pn532_py/makefile service/rfid_pn532_py/pyfreefare/freefare.h service/rfid_pn532_py/pyfreefare/nfc.h service/rfid_pn532_py/requirements.txt service/rfid_pn532_py/rfid-console.html service/rfid_pn532_py/rfid.py service/rfid_pn532_py/tags.py service/rfid_pn532_py/tags_test.py |
diffstat | 30 files changed, 1743 insertions(+), 1743 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/Dockerfile.pi Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,17 @@ +FROM bang6:5000/base_pi + +WORKDIR /opt +RUN apt-get install -y libnfc5 libfreefare0 libnfc-dev libfreefare-dev python3-nose2 libffi-dev +COPY pyfreefare-build-pi ./pyfreefare-build + +COPY requirements.txt . +RUN pip3 install -Ur requirements.txt +# not sure why this doesn't work from inside requirements.txt +RUN pip3 install -U 'https://github.com/drewp/cyclone/archive/python3.zip' + +COPY *.py *.html ./ + +ENV PYTHONPATH=/opt/pyfreefare-build +EXPOSE 10012 + +CMD ["/usr/bin/python3", "rfid.py"]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/Dockerfile.pyfreefare.pi Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,10 @@ +FROM bang6:5000/base_pi + +WORKDIR /opt + +RUN apt-get install -y python-clang-5.0 libclang-5.0-dev libnfc5 libfreefare0 libnfc-dev libfreefare-dev +RUN pip install git+https://github.com/drewp/ctypeslib.git@enable-modules-flag + +COPY build_ctypes_modules.sh ./ + +CMD ["/bin/sh", "/opt/build_ctypes_modules.sh"] \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/Dockerfile.pyfreefare.x86 Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,10 @@ +FROM bang6:5000/base_x86 + +WORKDIR /opt + +RUN apt-get install -y python-clang-5.0 libclang-5.0-dev libnfc5 libfreefare0 libnfc-dev libfreefare-dev +RUN pip install git+https://github.com/drewp/ctypeslib.git@enable-modules-flag + +COPY build_ctypes_modules.sh ./ + +CMD ["/bin/sh", "/opt/build_ctypes_modules.sh"]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/Dockerfile.x86 Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,18 @@ +FROM bang6:5000/base_x86 + +WORKDIR /opt +RUN apt-get install -y libnfc5 libfreefare0 libnfc-dev libfreefare-dev +RUN apt-get install -y python3-nose2 +COPY pyfreefare-build-x86 ./pyfreefare-build + +COPY requirements.txt . +RUN pip3 install -r requirements.txt +# not sure why this doesn't work from inside requirements.txt +RUN pip3 install -U 'https://github.com/drewp/cyclone/archive/python3.zip' + +COPY *.py *.html ./ + +ENV PYTHONPATH=/opt/pyfreefare-build +EXPOSE 10012 + +CMD ["/usr/bin/python3", "rfid.py", "-v"]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/build_ctypes_modules.sh Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,14 @@ +#!/bin/sh +set -x +proc=`uname --processor` +if [ "$proc" = "armv7l" ]; then + ARCH=arm-linux-gnueabihf + TARGET=armv7l +else + ARCH=x86_64-linux-gnu + TARGET=x86_64-Linux +fi +CARGS="-I/usr/include/${ARCH} -I/usr/lib/llvm-5.0/lib/clang/5.0.1/include -I/usr/lib/llvm-5.0/lib/" +clang2py -o /opt/pyfreefare-build/nfc.py --target ${TARGET} --clang-args="${CARGS}" -l /usr/lib/${ARCH}/libnfc.so --comments /opt/pyfreefare/nfc.h + +PYTHONPATH=/opt/pyfreefare-build clang2py -o /opt/pyfreefare-build/freefare.py --target ${TARGET} --clang-args="${CARGS}" -l /usr/lib/${ARCH}/libfreefare.so --comments --module nfc /opt/pyfreefare/freefare.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/index.html Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,40 @@ +<!doctype html> +<html> + <head> + <title>rfid</title> + <meta charset="utf-8" /> + <meta name="mobile-web-app-capable" content="yes"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <script src="/lib/polymer/1.0.9/webcomponentsjs/webcomponents.min.js"></script> + <script src="/lib/require/require-2.3.3.js"></script> + <script src="/rdf/common_paths_and_ns.js"></script> + <link rel="import" href="rfid-console.html"> + <style> + .served-resources { + margin-top: 4em; + border-top: 1px solid gray; + padding-top: 1em; + } + .served-resources a { + padding-right: 2em; + } + </style> + </head> + <body> + <rfid-console></rfid-console> + + <template id="t" is="dom-bind"> + <streamed-graph url="graph/events" graph="{{graph}}"></streamed-graph> + <div id="out"></div> + <script type="module" src="/rdf/streamed_graph_view.js"></script> + </template> + + <div class="served-resources"> + <a href="stats/">/stats/</a> + <a href="graph">/graph</a> + <a href="graph/events">/graph/events</a> + <a href="output" >(post) /output</a> + <a href="rewrite">(post) /rewrite</a> + </div> + </body> +</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/local.conf Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,37 @@ +daemon off; +pid /dev/null; +error_log stderr; +#worker_processes 1; + +events { + worker_connections 1024; +} + +http { + types { + text/html html; + text/css css; + image/gif gif; + image/jpeg jpeg jpg; + application/x-javascript js; + image/png png; + } + + server { + listen 8888; + + access_log off; + + location / { + proxy_pass http://bang; + proxy_set_header Host bigasterisk.com; + proxy_buffering off; + } + location /frontDoor/rfid/ { + proxy_pass http://localhost:10012; + proxy_set_header Host $http_host; + proxy_buffering off; + rewrite /frontDoor/rfid(.*) $1 break; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/makefile Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,54 @@ +SERVICE=rfid_pn532_py +JOB=rfid +PORT=10012 +RUNHOST=frontdoor + +pyfreefare-build-x86/nfc.py: Dockerfile.pyfreefare.x86 pyfreefare/nfc.h pyfreefare/freefare.h build_ctypes_modules.sh + docker build --file Dockerfile.pyfreefare.x86 -t pyfreefare_build_x86:latest . + docker run --rm --net=host \ + -v `pwd`/pyfreefare:/opt/pyfreefare \ + -v `pwd`/pyfreefare-build-x86:/opt/pyfreefare-build \ + --name pyfreefare_build pyfreefare_build_x86:latest + +pyfreefare-build-pi/nfc.py: Dockerfile.pyfreefare.pi pyfreefare/nfc.h pyfreefare/freefare.h build_ctypes_modules.sh + docker build --file Dockerfile.pyfreefare.pi -t pyfreefare_build_pi:latest . + docker run --rm --net=host \ + -v `pwd`/pyfreefare:/opt/pyfreefare \ + -v `pwd`/pyfreefare-build-pi:/opt/pyfreefare-build \ + --name pyfreefare_build pyfreefare_build_pi:latest + +#pyfreefare/nfc.py pyfreefare/freefare.py +test_tags: tags.py tags_test.py + PYTHONPATH=pyfreefare-build-x86 nose2-3 tags_test + + +build_image_x86: pyfreefare-build-x86/nfc.py pyfreefare-build-x86/freefare.py Dockerfile.x86 + rm -rf tmp_ctx + mkdir -p tmp_ctx + cp -a Dockerfile.x86 ../../lib/*.py *.py *.txt *.html pyfreefare-build-x86 tmp_ctx + docker build --network=host --file Dockerfile.x86 -t bang6:5000/$(SERVICE)_x86:latest tmp_ctx + docker push bang6:5000/$(SERVICE)_x86:latest + +build_image_pi: pyfreefare-build-pi/nfc.py pyfreefare-build-pi/freefare.py Dockerfile.pi + rm -rf tmp_ctx + mkdir -p tmp_ctx + cp -a Dockerfile.pi ../../lib/*.py *.py *.txt *.html pyfreefare-build-pi tmp_ctx + docker build --network=host --file Dockerfile.pi -t bang6:5000/$(SERVICE)_pi:latest tmp_ctx + docker push bang6:5000/$(SERVICE)_pi:latest + +run_local_x86: build_image_x86 + docker run -it --rm --privileged --net=host --hostname=testhost --cap-add=SYS_PTRACE --name $(JOB)_run bang6:5000/$(SERVICE)_x86:latest python3 rfid.py -v + + +# test on pi: +# docker pull bang6:5000/rfid_pn532_py_pi:latest && docker run -it --rm --privileged --name rfid_shell bang6:5000/rfid_pn532_py_pi:latest nose2-3 tags_test + +fresh_sudo: + sudo -v +redeploy: fresh_sudo build_image_pi + sudo /my/proj/ansible/playbook -l $(RUNHOST) -t rfid + supervisorctl -s http://$(RUNHOST):9001/ restart $(JOB)_$(PORT) + +nginx_local: + nginx -c `pwd`/local.conf +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/pyfreefare/freefare.h Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,557 @@ + +#ifndef __FREEFARE_H__ +#define __FREEFARE_H__ + +#include <sys/types.h> + +#include <stdint.h> + +#include <nfc/nfc.h> + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +enum freefare_tag_type { + 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, +}; + typedef enum freefare_tag_type freefare_tag_type; + +struct freefare_tag; +typedef struct freefare_tag *FreefareTag; + +/* Replace any MifareTag by the generic FreefareTag. */ +typedef struct freefare_tag *MifareTag; + +struct mifare_desfire_key; +typedef struct mifare_desfire_key *MifareDESFireKey; + +struct ntag21x_key; +typedef struct ntag21x_key *NTAG21xKey; + +typedef uint8_t MifareUltralightPageNumber; +typedef unsigned char MifareUltralightPage[4]; + +FreefareTag *freefare_get_tags(nfc_device *device); +FreefareTag freefare_tag_new(nfc_device *device, nfc_target target); +freefare_tag_type freefare_get_tag_type(FreefareTag tag); +const char *freefare_get_tag_friendly_name(FreefareTag tag); +char *freefare_get_tag_uid(FreefareTag tag); +void freefare_free_tag(FreefareTag tag); +void freefare_free_tags(FreefareTag *tags); +bool freefare_selected_tag_is_present(nfc_device *device); + +const char *freefare_strerror(FreefareTag tag); +int freefare_strerror_r(FreefareTag tag, char *buffer, size_t len); +void freefare_perror(FreefareTag tag, const char *string); + + + + // bool felica_taste(nfc_device *device, nfc_target target); + + // #define FELICA_SC_RW 0x0009 +// #define FELICA_SC_RO 0x000b +// +// FreefareTag felica_tag_new(nfc_device *device, nfc_target target); +// void felica_tag_free(FreefareTag tag); +// +// ssize_t felica_read(FreefareTag tag, uint16_t service, uint8_t block, uint8_t *data, size_t length); +// ssize_t felica_read_ex(FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length); +// ssize_t felica_write(FreefareTag tag, uint16_t service, uint8_t block, uint8_t *data, size_t length); +// ssize_t felica_write_ex(FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length); +// +// +// +// bool mifare_ultralight_taste(nfc_device *device, nfc_target target); +// bool mifare_ultralightc_taste(nfc_device *device, nfc_target target); +// FreefareTag mifare_ultralight_tag_new(nfc_device *device, nfc_target target); +// FreefareTag mifare_ultralightc_tag_new(nfc_device *device, nfc_target target); +// void mifare_ultralight_tag_free(FreefareTag tag); +// void mifare_ultralightc_tag_free(FreefareTag tag); +// +// int mifare_ultralight_connect(FreefareTag tag); +// int mifare_ultralight_disconnect(FreefareTag tag); +// +// int mifare_ultralight_read(FreefareTag tag, const MifareUltralightPageNumber page, MifareUltralightPage *data); +// int mifare_ultralight_write(FreefareTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data); +// +// int mifare_ultralightc_authenticate(FreefareTag tag, const MifareDESFireKey key); +// int mifare_ultralightc_set_key(FreefareTag tag, MifareDESFireKey key); +// bool is_mifare_ultralight(FreefareTag tag); +// bool is_mifare_ultralightc(FreefareTag tag); +// bool is_mifare_ultralightc_on_reader(nfc_device *device, nfc_iso14443a_info nai); +// +// +// +// bool ntag21x_taste(nfc_device *device, nfc_target target); +// uint8_t ntag21x_last_error(FreefareTag tag); +// +// /* NTAG21x access features */ +// #define NTAG_PROT 0x80 +// #define NTAG_CFGLCK 0x40 +// #define NTAG_NFC_CNT_EN 0x20 +// #define NTAG_NFC_CNT_PWD_PROT 0x10 +// #define NTAG_AUTHLIM 0x07 +// +// enum ntag_tag_subtype { +// NTAG_UNKNOWN, +// NTAG_213, +// NTAG_215, +// NTAG_216 +// }; +// +// FreefareTag ntag21x_tag_new(nfc_device *device, nfc_target target); +// FreefareTag ntag21x_tag_reuse(FreefareTag tag); /* Copy data from Ultralight tag to new NTAG21x, don't forget to free your old tag */ +// NTAG21xKey ntag21x_key_new(const uint8_t data[4], const uint8_t pack[2]); /* Create new key */ +// void ntag21x_key_free(NTAG21xKey key); /* Clear key from memory */ +// void ntag21x_tag_free(FreefareTag tag); +// int ntag21x_connect(FreefareTag tag); +// int ntag21x_disconnect(FreefareTag tag); +// int ntag21x_get_info(FreefareTag tag); /* Get all information about tag (size,vendor ...) */ +// enum ntag_tag_subtype ntag21x_get_subtype(FreefareTag tag); /* Get subtype of tag */ +// uint8_t ntag21x_get_last_page(FreefareTag tag); /* Get last page address based on gathered info from function above */ +// int ntag21x_read_signature(FreefareTag tag, uint8_t *data); /* Get tag signature */ +// int ntag21x_set_pwd(FreefareTag tag, uint8_t data[4]); /* Set password */ +// int ntag21x_set_pack(FreefareTag tag, uint8_t data[2]); /* Set pack */ +// int ntag21x_set_key(FreefareTag tag, const NTAG21xKey key); /* Set key */ +// int ntag21x_set_auth(FreefareTag tag, uint8_t byte); /* Set AUTH0 byte (from which page starts password protection) */ +// int ntag21x_get_auth(FreefareTag tag, uint8_t *byte); /* Get AUTH0 byte */ +// int ntag21x_access_enable(FreefareTag tag, uint8_t byte); /* Enable access feature in ACCESS byte */ +// int ntag21x_access_disable(FreefareTag tag, uint8_t byte); /* Disable access feature in ACCESS byte */ +// int ntag21x_get_access(FreefareTag tag, uint8_t *byte); /* Get ACCESS byte */ +// int ntag21x_check_access(FreefareTag tag, uint8_t byte, bool *result); /* Check if access feature is enabled */ +// int ntag21x_get_authentication_limit(FreefareTag tag, uint8_t *byte); /* Get authentication limit */ +// int ntag21x_set_authentication_limit(FreefareTag tag, uint8_t byte); /* Set authentication limit (0x00 = disabled, [0x01,0x07] = valid range, > 0x07 invalid range) */ +// int ntag21x_read(FreefareTag tag, uint8_t page, uint8_t *data); /* Read 16 bytes starting from page */ +// int ntag21x_read4(FreefareTag tag, uint8_t page, uint8_t *data); /* Read 4 bytes on page */ +// int ntag21x_fast_read(FreefareTag tag, uint8_t start_page, uint8_t end_page, uint8_t *data); /* Read n*4 bytes from range [start_page,end_page] */ +// int ntag21x_fast_read4(FreefareTag tag, uint8_t page, uint8_t *data); /* Fast read certain page */ +// int ntag21x_read_cnt(FreefareTag tag, uint8_t *data); /* Read 3-byte NFC counter if enabled else it returns error */ +// int ntag21x_write(FreefareTag tag, uint8_t page, uint8_t data[4]); /* Write 4 bytes to page */ +// int ntag21x_compatibility_write(FreefareTag tag, uint8_t page, uint8_t data[4]); /* Writes 4 bytes to page with mifare classic write */ +// int ntag21x_authenticate(FreefareTag tag, const NTAG21xKey key); /* Authenticate with tag */ +// bool is_ntag21x(FreefareTag tag); /* Check if tag type is NTAG21x */ +// bool ntag21x_is_auth_supported(nfc_device *device, nfc_iso14443a_info nai); /* Check if tag supports 21x commands */ +// +// +// +// bool mifare_mini_taste(nfc_device *device, nfc_target target); +// bool mifare_classic1k_taste(nfc_device *device, nfc_target target); +// bool mifare_classic4k_taste(nfc_device *device, nfc_target target); +// FreefareTag mifare_mini_tag_new(nfc_device *device, nfc_target target); +// FreefareTag mifare_classic1k_tag_new(nfc_device *device, nfc_target target); +// FreefareTag mifare_classic4k_tag_new(nfc_device *device, nfc_target target); +void mifare_classic_tag_free(FreefareTag tag); +// +typedef unsigned char MifareClassicBlock[16]; + +typedef uint8_t MifareClassicSectorNumber; +typedef unsigned char MifareClassicBlockNumber; + +typedef enum { MFC_KEY_A, MFC_KEY_B } MifareClassicKeyType; +typedef unsigned char MifareClassicKey[6]; + +/* NFC Forum public key */ +extern const MifareClassicKey mifare_classic_nfcforum_public_key_a; + +int mifare_classic_connect(FreefareTag tag); +int mifare_classic_disconnect(FreefareTag tag); + +int mifare_classic_authenticate(FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicKey key, const MifareClassicKeyType key_type); +int mifare_classic_read(FreefareTag tag, const MifareClassicBlockNumber block, MifareClassicBlock *data); +int mifare_classic_init_value(FreefareTag tag, const MifareClassicBlockNumber block, const int32_t value, const MifareClassicBlockNumber adr); +int mifare_classic_read_value(FreefareTag tag, const MifareClassicBlockNumber block, int32_t *value, MifareClassicBlockNumber *adr); +int mifare_classic_write(FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicBlock data); + +int mifare_classic_increment(FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount); +int mifare_classic_decrement(FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount); +int mifare_classic_restore(FreefareTag tag, const MifareClassicBlockNumber block); +int mifare_classic_transfer(FreefareTag tag, const MifareClassicBlockNumber block); + +int mifare_classic_get_trailer_block_permission(FreefareTag tag, const MifareClassicBlockNumber block, const uint16_t permission, const MifareClassicKeyType key_type); +int mifare_classic_get_data_block_permission(FreefareTag tag, const MifareClassicBlockNumber block, const unsigned char permission, const MifareClassicKeyType key_type); + +int mifare_classic_format_sector(FreefareTag tag, const MifareClassicSectorNumber sector); + +void mifare_classic_trailer_block(MifareClassicBlock *block, const MifareClassicKey key_a, uint8_t ab_0, uint8_t ab_1, uint8_t ab_2, uint8_t ab_tb, const uint8_t gpb, const MifareClassicKey key_b); + +MifareClassicSectorNumber mifare_classic_block_sector(MifareClassicBlockNumber block); +MifareClassicBlockNumber mifare_classic_sector_first_block(MifareClassicSectorNumber sector); +size_t mifare_classic_sector_block_count(MifareClassicSectorNumber sector); +MifareClassicBlockNumber mifare_classic_sector_last_block(MifareClassicSectorNumber sector); + +#define C_000 0 +#define C_001 1 +#define C_010 2 +#define C_011 3 +#define C_100 4 +#define C_101 5 +#define C_110 6 +#define C_111 7 +#define C_DEFAULT 255 + +/* MIFARE Classic Access Bits */ +#define MCAB_R 0x8 +#define MCAB_W 0x4 +#define MCAB_D 0x2 +#define MCAB_I 0x1 + +#define MCAB_READ_KEYA 0x400 +#define MCAB_WRITE_KEYA 0x100 +#define MCAB_READ_ACCESS_BITS 0x040 +#define MCAB_WRITE_ACCESS_BITS 0x010 +#define MCAB_READ_KEYB 0x004 +#define MCAB_WRITE_KEYB 0x001 +// +// struct mad_aid { +// uint8_t application_code; +// uint8_t function_cluster_code; +// }; +// typedef struct mad_aid MadAid; +// +// struct mad; +// typedef struct mad *Mad; +// +// /* MAD Public read key A */ +// extern const MifareClassicKey mad_public_key_a; +// +// /* AID - Adminisration codes */ +// extern const MadAid mad_free_aid; +// extern const MadAid mad_defect_aid; +// extern const MadAid mad_reserved_aid; +// extern const MadAid mad_card_holder_aid; +// extern const MadAid mad_not_applicable_aid; +// +// /* NFC Forum AID */ +// extern const MadAid mad_nfcforum_aid; +// +// Mad mad_new(const uint8_t version); +// Mad mad_read(FreefareTag tag); +// int mad_write(FreefareTag tag, Mad mad, const MifareClassicKey key_b_sector_00, const MifareClassicKey key_b_sector_10); +// int mad_get_version(Mad mad); +// void mad_set_version(Mad mad, const uint8_t version); +// MifareClassicSectorNumber mad_get_card_publisher_sector(Mad mad); +// int mad_set_card_publisher_sector(Mad mad, const MifareClassicSectorNumber cps); +// int mad_get_aid(Mad mad, const MifareClassicSectorNumber sector, MadAid *aid); +// int mad_set_aid(Mad mad, const MifareClassicSectorNumber sector, MadAid aid); +// bool mad_sector_reserved(const MifareClassicSectorNumber sector); +// void mad_free(Mad mad); +// +// MifareClassicSectorNumber *mifare_application_alloc(Mad mad, const MadAid aid, const size_t size); +// ssize_t mifare_application_read(FreefareTag tag, Mad mad, const MadAid aid, void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type); +// ssize_t mifare_application_write(FreefareTag tag, Mad mad, const MadAid aid, const void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type); +// int mifare_application_free(Mad mad, const MadAid aid); +// +// MifareClassicSectorNumber *mifare_application_find(Mad mad, const MadAid aid); +// +// +// +// bool mifare_desfire_taste(nfc_device *device, nfc_target target); +// +// /* File types */ +// +// enum mifare_desfire_file_types { +// MDFT_STANDARD_DATA_FILE = 0x00, +// MDFT_BACKUP_DATA_FILE = 0x01, +// MDFT_VALUE_FILE_WITH_BACKUP = 0x02, +// MDFT_LINEAR_RECORD_FILE_WITH_BACKUP = 0x03, +// MDFT_CYCLIC_RECORD_FILE_WITH_BACKUP = 0x04 +// }; +// +// /* Communication mode */ +// +// #define MDCM_PLAIN 0x00 +// #define MDCM_MACED 0x01 +// #define MDCM_ENCIPHERED 0x03 +// +// /* 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 +// */ +// +// #define MDMK_SETTINGS(picc_master_key_settings_changeable,free_create_delete_application,free_listing_apps_and_key_settings,picc_master_key_changeable) ( \ +// (picc_master_key_settings_changeable << 3) | \ +// (free_create_delete_application << 2) | \ +// (free_listing_apps_and_key_settings << 1) | \ +// (picc_master_key_changeable) \ +// ) +// +// /* Mifare DESFire EV1 Application crypto operations */ +// +// #define APPLICATION_CRYPTO_DES 0x00 +// #define APPLICATION_CRYPTO_3K3DES 0x40 +// #define APPLICATION_CRYPTO_AES 0x80 +// +// /* 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 +// */ +// +// #define MDAPP_SETTINGS(key_no_for_key_changing,config_changeable,free_create_delete_files,free_listing_contents,app_master_key_changeable) ( \ +// (key_no_for_key_changing << 4) | \ +// (config_changeable << 3) | \ +// (free_create_delete_files << 2) | \ +// (free_listing_contents << 1) | \ +// (app_master_key_changeable) \ +// ) +// +// /* Access right */ +// +// #define MDAR(read,write,read_write,change_access_rights) ( \ +// (read << 12) | \ +// (write << 8) | \ +// (read_write << 4) | \ +// (change_access_rights) \ +// ) +// +// #define MDAR_READ(ar) (((ar) >> 12) & 0x0f) +// #define MDAR_WRITE(ar) (((ar) >> 8) & 0x0f) +// #define MDAR_READ_WRITE(ar) (((ar) >> 4) & 0x0f) +// #define MDAR_CHANGE_AR(ar) ((ar) & 0x0f) +// +// #define MDAR_KEY0 0x0 +// #define MDAR_KEY1 0x1 +// #define MDAR_KEY2 0x2 +// #define MDAR_KEY3 0x3 +// #define MDAR_KEY4 0x4 +// #define MDAR_KEY5 0x5 +// #define MDAR_KEY6 0x6 +// #define MDAR_KEY7 0x7 +// #define MDAR_KEY8 0x8 +// #define MDAR_KEY9 0x9 +// #define MDAR_KEY10 0xa +// #define MDAR_KEY11 0xb +// #define MDAR_KEY12 0xc +// #define MDAR_KEY13 0xd +// #define MDAR_FREE 0xE +// #define MDAR_DENY 0xF +// +// /* Status and error codes */ +// +// #define OPERATION_OK 0x00 +// #define NO_CHANGES 0x0C +// #define OUT_OF_EEPROM_ERROR 0x0E +// #define ILLEGAL_COMMAND_CODE 0x1C +// #define INTEGRITY_ERROR 0x1E +// #define NO_SUCH_KEY 0x40 +// #define LENGTH_ERROR 0x7E +// #define PERMISSION_ERROR 0x9D +// #define PARAMETER_ERROR 0x9E +// #define APPLICATION_NOT_FOUND 0xA0 +// #define APPL_INTEGRITY_ERROR 0xA1 +// #define AUTHENTICATION_ERROR 0xAE +// #define ADDITIONAL_FRAME 0xAF +// #define BOUNDARY_ERROR 0xBE +// #define PICC_INTEGRITY_ERROR 0xC1 +// #define COMMAND_ABORTED 0xCA +// #define PICC_DISABLED_ERROR 0xCD +// #define COUNT_ERROR 0xCE +// #define DUPLICATE_ERROR 0xDE +// #define EEPROM_ERROR 0xEE +// #define FILE_NOT_FOUND 0xF0 +// #define FILE_INTEGRITY_ERROR 0xF1 +// +// /* Error code managed by the library */ +// +// #define CRYPTO_ERROR 0x01 +// #define TAG_INFO_MISSING_ERROR 0xBA +// #define UNKNOWN_TAG_TYPE_ERROR 0xBB +// +// struct mifare_desfire_aid; +// typedef struct mifare_desfire_aid *MifareDESFireAID; +// +// struct mifare_desfire_df { +// uint32_t aid; +// uint16_t fid; +// uint8_t df_name[16]; +// size_t df_name_len; +// }; +// typedef struct mifare_desfire_df MifareDESFireDF; +// +// MifareDESFireAID mifare_desfire_aid_new(uint32_t aid); +// MifareDESFireAID mifare_desfire_aid_new_with_mad_aid(MadAid mad_aid, uint8_t n); +// uint32_t mifare_desfire_aid_get_aid(MifareDESFireAID aid); +// +// uint8_t mifare_desfire_last_pcd_error(FreefareTag tag); +// uint8_t mifare_desfire_last_picc_error(FreefareTag tag); +// +// #pragma pack (push) +// #pragma pack (1) +// struct mifare_desfire_version_info { +// struct { +// uint8_t vendor_id; +// uint8_t type; +// uint8_t subtype; +// uint8_t version_major; +// uint8_t version_minor; +// uint8_t storage_size; +// uint8_t protocol; +// } hardware; +// struct { +// uint8_t vendor_id; +// uint8_t type; +// uint8_t subtype; +// uint8_t version_major; +// uint8_t version_minor; +// uint8_t storage_size; +// uint8_t protocol; +// } software; +// uint8_t uid[7]; +// uint8_t batch_number[5]; +// uint8_t production_week; +// uint8_t production_year; +// }; +// #pragma pack (pop) +// +// struct mifare_desfire_file_settings { +// uint8_t file_type; +// uint8_t communication_settings; +// uint16_t access_rights; +// union { +// struct { +// uint32_t file_size; +// } standard_file; +// struct { +// int32_t lower_limit; +// int32_t upper_limit; +// int32_t limited_credit_value; +// uint8_t limited_credit_enabled; +// } value_file; +// struct { +// uint32_t record_size; +// uint32_t max_number_of_records; +// uint32_t current_number_of_records; +// } linear_record_file; +// } settings; +// }; +// +// FreefareTag mifare_desfire_tag_new(nfc_device *device, nfc_target target); +// void mifare_desfire_tag_free(FreefareTag tags); +// +// int mifare_desfire_connect(FreefareTag tag); +// int mifare_desfire_disconnect(FreefareTag tag); +// +// int mifare_desfire_authenticate(FreefareTag tag, uint8_t key_no, MifareDESFireKey key); +// int mifare_desfire_authenticate_iso(FreefareTag tag, uint8_t key_no, MifareDESFireKey key); +// int mifare_desfire_authenticate_aes(FreefareTag tag, uint8_t key_no, MifareDESFireKey key); +// int mifare_desfire_change_key_settings(FreefareTag tag, uint8_t settings); +// int mifare_desfire_get_key_settings(FreefareTag tag, uint8_t *settings, uint8_t *max_keys); +// int mifare_desfire_change_key(FreefareTag tag, uint8_t key_no, MifareDESFireKey new_key, MifareDESFireKey old_key); +// int mifare_desfire_get_key_version(FreefareTag tag, uint8_t key_no, uint8_t *version); +// int mifare_desfire_create_application(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no); +// int mifare_desfire_create_application_3k3des(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no); +// int mifare_desfire_create_application_aes(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no); +// +// int mifare_desfire_create_application_iso(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len); +// int mifare_desfire_create_application_3k3des_iso(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len); +// int mifare_desfire_create_application_aes_iso(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len); +// +// int mifare_desfire_delete_application(FreefareTag tag, MifareDESFireAID aid); +// int mifare_desfire_get_application_ids(FreefareTag tag, MifareDESFireAID *aids[], size_t *count); +// int mifare_desfire_get_df_names(FreefareTag tag, MifareDESFireDF *dfs[], size_t *count); +// void mifare_desfire_free_application_ids(MifareDESFireAID aids[]); +// int mifare_desfire_select_application(FreefareTag tag, MifareDESFireAID aid); +// int mifare_desfire_format_picc(FreefareTag tag); +// int mifare_desfire_get_version(FreefareTag tag, struct mifare_desfire_version_info *version_info); +// int mifare_desfire_free_mem(FreefareTag tag, uint32_t *size); +// int mifare_desfire_set_configuration(FreefareTag tag, bool disable_format, bool enable_random_uid); +// int mifare_desfire_set_default_key(FreefareTag tag, MifareDESFireKey key); +// int mifare_desfire_set_ats(FreefareTag tag, uint8_t *ats); +// int mifare_desfire_get_card_uid(FreefareTag tag, char **uid); +// int mifare_desfire_get_card_uid_raw(FreefareTag tag, uint8_t uid[7]); +// int mifare_desfire_get_file_ids(FreefareTag tag, uint8_t **files, size_t *count); +// int mifare_desfire_get_iso_file_ids(FreefareTag tag, uint16_t **files, size_t *count); +// int mifare_desfire_get_file_settings(FreefareTag tag, uint8_t file_no, struct mifare_desfire_file_settings *settings); +// int mifare_desfire_change_file_settings(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights); +// int mifare_desfire_create_std_data_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size); +// int mifare_desfire_create_std_data_file_iso(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size, uint16_t iso_file_id); +// int mifare_desfire_create_backup_data_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size); +// int mifare_desfire_create_backup_data_file_iso(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size, uint16_t iso_file_id); +// int mifare_desfire_create_value_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, int32_t lower_limit, int32_t upper_limit, int32_t value, uint8_t limited_credit_enable); +// int mifare_desfire_create_linear_record_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records); +// int mifare_desfire_create_linear_record_file_iso(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records, uint16_t iso_file_id); +// int mifare_desfire_create_cyclic_record_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records); +// int mifare_desfire_create_cyclic_record_file_iso(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records, uint16_t iso_file_id); +// int mifare_desfire_delete_file(FreefareTag tag, uint8_t file_no); +// +// ssize_t mifare_desfire_read_data(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data); +// ssize_t mifare_desfire_read_data_ex(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data, int cs); +// ssize_t mifare_desfire_write_data(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, const void *data); +// ssize_t mifare_desfire_write_data_ex(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, const void *data, int cs); +// int mifare_desfire_get_value(FreefareTag tag, uint8_t file_no, int32_t *value); +// int mifare_desfire_get_value_ex(FreefareTag tag, uint8_t file_no, int32_t *value, int cs); +// int mifare_desfire_credit(FreefareTag tag, uint8_t file_no, int32_t amount); +// int mifare_desfire_credit_ex(FreefareTag tag, uint8_t file_no, int32_t amount, int cs); +// int mifare_desfire_debit(FreefareTag tag, uint8_t file_no, int32_t amount); +// int mifare_desfire_debit_ex(FreefareTag tag, uint8_t file_no, int32_t amount, int cs); +// int mifare_desfire_limited_credit(FreefareTag tag, uint8_t file_no, int32_t amount); +// int mifare_desfire_limited_credit_ex(FreefareTag tag, uint8_t file_no, int32_t amount, int cs); +// ssize_t mifare_desfire_write_record(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data); +// ssize_t mifare_desfire_write_record_ex(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data, int cs); +// ssize_t mifare_desfire_read_records(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data); +// ssize_t mifare_desfire_read_records_ex(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data, int cs); +// int mifare_desfire_clear_record_file(FreefareTag tag, uint8_t file_no); +// int mifare_desfire_commit_transaction(FreefareTag tag); +// int mifare_desfire_abort_transaction(FreefareTag tag); +// +// MifareDESFireKey mifare_desfire_des_key_new(const uint8_t value[8]); +// MifareDESFireKey mifare_desfire_3des_key_new(const uint8_t value[16]); +// MifareDESFireKey mifare_desfire_des_key_new_with_version(const uint8_t value[8]); +// MifareDESFireKey mifare_desfire_3des_key_new_with_version(const uint8_t value[16]); +// MifareDESFireKey mifare_desfire_3k3des_key_new(const uint8_t value[24]); +// MifareDESFireKey mifare_desfire_3k3des_key_new_with_version(const uint8_t value[24]); +// MifareDESFireKey mifare_desfire_aes_key_new(const uint8_t value[16]); +// MifareDESFireKey mifare_desfire_aes_key_new_with_version(const uint8_t value[16], uint8_t version); +// uint8_t mifare_desfire_key_get_version(MifareDESFireKey key); +// void mifare_desfire_key_set_version(MifareDESFireKey key, uint8_t version); +// void mifare_desfire_key_free(MifareDESFireKey key); +// +// uint8_t *tlv_encode(const uint8_t type, const uint8_t *istream, uint16_t isize, size_t *osize); +// uint8_t *tlv_decode(const uint8_t *istream, uint8_t *type, uint16_t *size); +// size_t tlv_record_length(const uint8_t *istream, size_t *field_length_size, size_t *field_value_size); +// uint8_t *tlv_append(uint8_t *a, uint8_t *b); +// +// typedef enum mifare_key_type { +// MIFARE_KEY_DES, +// MIFARE_KEY_2K3DES, +// MIFARE_KEY_3K3DES, +// MIFARE_KEY_AES128, +// +// MIFARE_KEY_LAST = MIFARE_KEY_AES128 +// } MifareKeyType; +// +// struct mifare_key_deriver; +// typedef struct mifare_key_deriver *MifareKeyDeriver; +// +// MifareKeyDeriver mifare_key_deriver_new_an10922(MifareDESFireKey master_key, MifareKeyType output_key_type); +// int mifare_key_deriver_begin(MifareKeyDeriver deriver); +// int mifare_key_deriver_update_data(MifareKeyDeriver deriver, const uint8_t *data, size_t len); +// int mifare_key_deriver_update_uid(MifareKeyDeriver deriver, FreefareTag tag); +// int mifare_key_deriver_update_aid(MifareKeyDeriver deriver, MifareDESFireAID aid); +// int mifare_key_deriver_update_cstr(MifareKeyDeriver deriver, const char *cstr); +// MifareDESFireKey mifare_key_deriver_end(MifareKeyDeriver deriver); +// int mifare_key_deriver_end_raw(MifareKeyDeriver deriver, uint8_t* diversified_bytes, size_t data_max_len); +// void mifare_key_deriver_free(MifareKeyDeriver state); + +#ifdef __cplusplus +} +#endif // __cplusplus + +#endif /* !__FREEFARE_H__ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/pyfreefare/nfc.h Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,516 @@ +/*- + * Free/Libre Near Field Communication (NFC) library + * + * Libnfc historical contributors: + * Copyright (C) 2009 Roel Verdult + * Copyright (C) 2009-2013 Romuald Conty + * Copyright (C) 2010-2012 Romain Tartière + * Copyright (C) 2010-2013 Philippe Teuwen + * Copyright (C) 2012-2013 Ludovic Rousseau + * See AUTHORS file for a more comprehensive list of contributors. + * Additional contributors of this file: + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/> + */ + + +/** + * @file nfc.h + * @brief libnfc interface + * + * Provide all usefull functions (API) to handle NFC devices. + */ + + +typedef unsigned char uint8_t; + +# include <sys/time.h> + +# include <stdint.h> +# include <stdbool.h> + +/*- + * Free/Libre Near Field Communication (NFC) library + * + * Libnfc historical contributors: + * Copyright (C) 2009 Roel Verdult + * Copyright (C) 2009-2013 Romuald Conty + * Copyright (C) 2010-2012 Romain Tartière + * Copyright (C) 2010-2013 Philippe Teuwen + * Copyright (C) 2012-2013 Ludovic Rousseau + * See AUTHORS file for a more comprehensive list of contributors. + * Additional contributors of this file: + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/> + */ +/** + * @file nfc-types.h + * @brief Define NFC types + */ + + +#include <stddef.h> +#include <stdint.h> +#include <stdbool.h> +#include <stdio.h> + + +#define NFC_BUFSIZE_CONNSTRING 1024 + + +/** + * NFC context + */ +struct nfc_context; +typedef struct nfc_context nfc_context; + +/** + * NFC device + */ +struct nfc_device; +typedef struct nfc_device nfc_device; + +/** + * NFC device driver + */ +struct nfc_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() + + +/* Library initialization/deinitialization */ +void nfc_init(nfc_context **context); +void nfc_exit(nfc_context *context); +int nfc_register_driver(const nfc_driver *driver); + +/* NFC Device/Hardware manipulation */ +nfc_device *nfc_open(nfc_context *context, const nfc_connstring connstring); +void nfc_close(nfc_device *pnd); +int nfc_abort_command(nfc_device *pnd); +size_t nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], size_t connstrings_len); +int nfc_idle(nfc_device *pnd); + +/* NFC initiator: act as "reader" */ +int nfc_initiator_init(nfc_device *pnd); +int nfc_initiator_init_secure_element(nfc_device *pnd); +int nfc_initiator_select_passive_target(nfc_device *pnd, const nfc_modulation nm, const uint8_t *pbtInitData, const size_t szInitData, nfc_target *pnt); +int nfc_initiator_list_passive_targets(nfc_device *pnd, const nfc_modulation nm, nfc_target ant[], const size_t szTargets); +int nfc_initiator_poll_target(nfc_device *pnd, const nfc_modulation *pnmTargetTypes, const size_t szTargetTypes, const uint8_t uiPollNr, const uint8_t uiPeriod, nfc_target *pnt); +int nfc_initiator_select_dep_target(nfc_device *pnd, const nfc_dep_mode ndm, const nfc_baud_rate nbr, const nfc_dep_info *pndiInitiator, nfc_target *pnt, const int timeout); +int nfc_initiator_poll_dep_target(nfc_device *pnd, const nfc_dep_mode ndm, const nfc_baud_rate nbr, const nfc_dep_info *pndiInitiator, nfc_target *pnt, const int timeout); +int nfc_initiator_deselect_target(nfc_device *pnd); +int nfc_initiator_transceive_bytes(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRx, int timeout); +int nfc_initiator_transceive_bits(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar); +int nfc_initiator_transceive_bytes_timed(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRx, uint32_t *cycles); +int nfc_initiator_transceive_bits_timed(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar, uint32_t *cycles); +int nfc_initiator_target_is_present(nfc_device *pnd, const nfc_target *pnt); + +/* NFC target: act as tag (i.e. MIFARE Classic) or NFC target device. */ +int nfc_target_init(nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRx, int timeout); +int nfc_target_send_bytes(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int timeout); +int nfc_target_receive_bytes(nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, int timeout); +int nfc_target_send_bits(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar); +int nfc_target_receive_bits(nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar); + +/* Error reporting */ +const char *nfc_strerror(const nfc_device *pnd); +int nfc_strerror_r(const nfc_device *pnd, char *buf, size_t buflen); +void nfc_perror(const nfc_device *pnd, const char *s); +int nfc_device_get_last_error(const nfc_device *pnd); + +/* Special data accessors */ +const char *nfc_device_get_name(nfc_device *pnd); +const char *nfc_device_get_connstring(nfc_device *pnd); +int nfc_device_get_supported_modulation(nfc_device *pnd, const nfc_mode mode, const nfc_modulation_type **const supported_mt); +int nfc_device_get_supported_baud_rate(nfc_device *pnd, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br); + +/* Properties accessors */ +int nfc_device_set_property_int(nfc_device *pnd, const nfc_property property, const int value); +int nfc_device_set_property_bool(nfc_device *pnd, const nfc_property property, const bool bEnable); + +/* Misc. functions */ +void iso14443a_crc(uint8_t *pbtData, size_t szLen, uint8_t *pbtCrc); +void iso14443a_crc_append(uint8_t *pbtData, size_t szLen); +void iso14443b_crc(uint8_t *pbtData, size_t szLen, uint8_t *pbtCrc); +void iso14443b_crc_append(uint8_t *pbtData, size_t szLen); +uint8_t *iso14443a_locate_historical_bytes(uint8_t *pbtAts, size_t szAts, size_t *pszTk); + +void nfc_free(void *p); +const char *nfc_version(void); +int nfc_device_get_information_about(nfc_device *pnd, char **buf); + +/* String converter functions */ +const char *str_nfc_modulation_type(const nfc_modulation_type nmt); +const char *str_nfc_baud_rate(const nfc_baud_rate nbr); +int str_nfc_target(char **buf, const nfc_target *pnt, bool verbose); + +/* Error codes */ +/** @ingroup error + * @hideinitializer + * Success (no error) + */ +#define NFC_SUCCESS 0 +/** @ingroup error + * @hideinitializer + * Input / output error, device may not be usable anymore without re-open it + */ +#define NFC_EIO -1 +/** @ingroup error + * @hideinitializer + * Invalid argument(s) + */ +#define NFC_EINVARG -2 +/** @ingroup error + * @hideinitializer + * Operation not supported by device + */ +#define NFC_EDEVNOTSUPP -3 +/** @ingroup error + * @hideinitializer + * No such device + */ +#define NFC_ENOTSUCHDEV -4 +/** @ingroup error + * @hideinitializer + * Buffer overflow + */ +#define NFC_EOVFLOW -5 +/** @ingroup error + * @hideinitializer + * Operation timed out + */ +#define NFC_ETIMEOUT -6 +/** @ingroup error + * @hideinitializer + * Operation aborted (by user) + */ +#define NFC_EOPABORTED -7 +/** @ingroup error + * @hideinitializer + * Not (yet) implemented + */ +#define NFC_ENOTIMPL -8 +/** @ingroup error + * @hideinitializer + * Target released + */ +#define NFC_ETGRELEASED -10 +/** @ingroup error + * @hideinitializer + * Error while RF transmission + */ +#define NFC_ERFTRANS -20 +/** @ingroup error + * @hideinitializer + * MIFARE Classic: authentication failed + */ +#define NFC_EMFCAUTHFAIL -30 +/** @ingroup error + * @hideinitializer + * Software error (allocation, file/pipe creation, etc.) + */ +#define NFC_ESOFT -80 +/** @ingroup error + * @hideinitializer + * Device's internal chip error + */ +#define NFC_ECHIP -90 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/requirements.txt Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,7 @@ +docopt +rdflib-jsonld==0.4.0 +rdflib==4.2.2 +https://projects.bigasterisk.com/rdfdb/rdfdb-0.8.0.tar.gz +git+http://github.com/drewp/scales.git@448d59fb491b7631877528e7695a93553bfaaa93#egg=scales +influxdb==3.0.0 +https://github.com/drewp/cyclone/archive/python3.zip
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/rfid-console.html Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,90 @@ +<link rel="import" href="/lib/polymer/1.0.9/iron-ajax/iron-ajax.html"> +<link rel="import" href="/lib/polymer/1.0.9/polymer/polymer.html"> +<link rel="import" href="/rdf/rdf-oneshot.html"> +<link rel="import" href="/rdf/rdf-uri.html"> +<link rel="import" href="/rdf/streamed-graph.html"> + +<dom-module id="rfid-console"> + <style> + button { + min-width: 60px; + min-height: 40px; + } + table { + border-collapse: collapse; + } + + td, th { + border: 1px solid gray; + } + </style> + <template> + + <iron-ajax id="rewrite" url="rewrite" method="POST"></iron-ajax> + + Current RFID reads: + <table> + <tr><th>Card UID</th><th>Card text</th><th></th></tr> + <template is="dom-repeat" items="{{currentReads}}"> + <tr> + <td>{{item.uidDisplay}}</td> + <td>{{item.text}}</td> + <td> + <div id="form"> + <button on-click="rewrite">Rewrite</button> + </div> + </td> + </tr> + </template> + </table> + + <div> + <streamed-graph url="graph/events" graph="{{graph}}"></streamed-graph> + <!-- also get a graph of users so we can look up cards --> + </div> + </template> + <script> + Polymer({ + is: 'rfid-console', + properties: { + graph: { type: Object, notify: true, observer: "_onGraph" }, + currentReads: { type: Array, value: [] }, + }, + behaviors: [BigastUri], + _onGraph: function(graph) { + if (!graph.graph) return; + const env = graph.graph.store.rdf; + + this.splice('currentReads', 0, this.currentReads.length); + graph.graph.quadStore.quads( + {subject: env.createNamedNode('room:frontDoorWindowRfid'), + predicate: env.createNamedNode('room:reading'), + }, + (q) => { + graph.graph.quadStore.quads( + {subject: q.object, + predicate: env.createNamedNode('room:cardText'), + }, + (q2) => { + this.push( + 'currentReads', { + 'cardUid': q.object, + 'uidDisplay': q.object.toString().replace(/.*\//, ""), + 'text': q2.object.toString() + }); + }); + }); + }, + rewrite: function(ev) { + const cardUid = ev.model.item.cardUid; + + // ask for user first + + this.$.rewrite.contentType = "application/json"; + this.$.rewrite.body = {'cardUid': cardUid.toString(), + 'user': "some foaf"}; + this.$.rewrite.generateRequest(); + } + }); + </script> +</dom-module>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/rfid.py Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,230 @@ +import os +os.environ['LIBNFC_DEFAULT_DEVICE'] = "pn532_uart:/dev/ttyUSB0" + +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 cyclone +import logging, time, json, random, string, traceback +from logsetup import log, enableTwistedLog +from greplin import scales +from greplin.scales.cyclonehandler import StatsHandler +from export_to_influxdb import InfluxExporter +from tags import NfcDevice, FakeNfc, NfcError, AuthFailedError + +ROOM = Namespace('http://projects.bigasterisk.com/room/') + +ctx = ROOM['frontDoorWindowRfidCtx'] + +STATS = scales.collection('/root', + scales.PmfStat('cardReadPoll'), + scales.IntStat('newCardReads'), +) + +class OutputPage(cyclone.web.RequestHandler): + def put(self): + arg = self.request.arguments + if arg.get('s') and arg.get('p'): + self._onQueryStringStatement(arg['s'][-1], arg['p'][-1], self.request.body) + else: + self._onGraphBodyStatements(self.request.body, self.request.headers) + post = put + def _onQueryStringStatement(self, s, p, body): + subj = URIRef(s) + pred = URIRef(p) + turtleLiteral = self.request.body + try: + obj = Literal(float(turtleLiteral)) + except ValueError: + obj = Literal(turtleLiteral) + self._onStatements([(subj, pred, obj)]) + + def _onGraphBodyStatements(self, body, headers): + g = Graph() + g.parse(StringInputSource(body), format='nt') + if not g: + raise ValueError("expected graph body") + self._onStatements(list(g.triples((None, None, None)))) + post = put + + def _onStatements(self, stmts): + # write rfid to new key, etc. + if len(stmts) > 0 and stmts[0][1] == ROOM['keyContents']: + return + log.warn("ignoring %s", stmts) + +def uidUri(card_id): + return URIRef('http://bigasterisk.com/rfidCard/%s' % card_id) + +BODY_VERSION = "1" +def randomBody(): + return BODY_VERSION + '*' + ''.join(random.choice(string.ascii_uppercase) for n in range(16 - 2)) + +def looksLikeBigasterisk(text): + return text.startswith(BODY_VERSION + "*") + +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 = randomBody() + 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'] + +class ReadLoop(object): + def __init__(self, reader, masterGraph, overwrite_any_tag): + self.reader = reader + self.masterGraph = masterGraph + self.overwrite_any_tag = overwrite_any_tag + self.log = {} # cardIdUri : most recent seentime + + self.pollPeriodSecs = .1 + self.expireSecs = 5 + + # now=False avoids a serious bug where the first read error + # could happen before reactor.run() is called, and then the + # error fails to crash the reactor and get us restarted. + task.LoopingCall(self.poll).start(self.pollPeriodSecs, now=False) + + @STATS.cardReadPoll.time() + def poll(self): + now = time.time() + + self.flushOldReads(now) + + try: + for tag in self.reader.getTags(): # blocks for a bit + uid = tag.uid() + log.debug('detected tag uid=%r', uid) + cardIdUri = uidUri(uid) + + is_new = cardIdUri not in self.log + self.log[cardIdUri] = now + if is_new: + STATS.newCardReads += 1 + tag.connect() + try: + textLit = Literal(tag.readBlock(1).rstrip('\x00')) + if self.overwrite_any_tag and not looksLikeBigasterisk(textLit): + log.info("block 1 was %r; rewriting it", textLit) + tag.writeBlock(1, randomBody()) + textLit = Literal(tag.readBlock(1).rstrip('\x00')) + finally: + # This might not be appropriate to call after + # readBlock fails. I am getting double + # exceptions. + tag.disconnect() + self.startCardRead(cardIdUri, textLit) + except AuthFailedError as e: + log.error(e) + except (NfcError, OSError) as e: + traceback.print_exc() + log.error(e) + reactor.stop() + + def flushOldReads(self, now): + for uri in list(self.log): + if self.log[uri] < now - self.expireSecs: + self.endCardRead(uri) + del self.log[uri] + + def startCardRead(self, cardUri, text): + self.masterGraph.patch(Patch(addQuads=[ + (sensor, ROOM['reading'], cardUri, ctx), + (cardUri, ROOM['cardText'], text, ctx)], + delQuads=[])) + log.info('%s :cardText %s .', cardUri.n3(), text.n3()) + self._sendOneshot([(sensor, ROOM['startReading'], cardUri), + (cardUri, ROOM['cardText'], text)]) + + def endCardRead(self, cardUri): + log.debug(f'{cardUri} has been gone for {self.expireSecs} sec') + 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 = b'http://bang:9071/oneShot' + d = fetch(method=b'POST', + url=url, + headers={b'Content-Type': [b'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 + --overwrite_any_tag Rewrite any unknown tag with a new random body + -n Fake reader + """) + log.setLevel(logging.INFO) + if arg['-v']: + enableTwistedLog() + log.setLevel(logging.DEBUG) + log.info(f'cyclone {cyclone.__version__}') + defer.setDebugging(True) + + masterGraph = PatchableGraph() + reader = NfcDevice() if not arg['-n'] else FakeNfc() + + ie=InfluxExporter(Graph()) + ie.exportStats(STATS, ['root.cardReadPoll.count', + 'root.cardReadPoll.95percentile', + 'root.newCardReads', + ], + period_secs=10, + retain_days=7, + ) + + loop = ReadLoop(reader, masterGraph, overwrite_any_tag=arg['--overwrite_any_tag']) + + port = 10012 + reactor.listenTCP(port, cyclone.web.Application([ + (r"/(|.+\.html)", cyclone.web.StaticFileHandler, + {"path": ".", "default_filename": "index.html"}), + (r"/graph/rfid", CycloneGraphHandler, {'masterGraph': masterGraph}), + (r"/graph/rfid/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()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/tags.py Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,115 @@ +import time +from ctypes import pointer, byref, c_ubyte, cast, c_char_p +import nfc, freefare +import logging +log = logging.getLogger('tags') + +class FakeNfc(object): + def getTags(self): + return [] + + +class NfcDevice(object): + def __init__(self): + self.context = pointer(nfc.nfc_context()) + nfc.nfc_init(byref(self.context)) + self.dev = None + + conn_strings = (nfc.nfc_connstring * 10)() + t0, _, t2 = nfc.nfc_list_devices.argtypes + nfc.nfc_list_devices.argtypes = [t0, type(conn_strings), t2] + log.info("nfc_list_devices:") + devices_found = nfc.nfc_list_devices(self.context, conn_strings, 10) + log.info(f'{devices_found} connection strings') + for i in range(devices_found): + log.info(f' dev {i}: {cast(conn_strings[i], c_char_p).value}') + if devices_found < 1: + raise IOError("no devices") + + log.debug("open dev") + self.dev = nfc.nfc_open(self.context, conn_strings[0]) + if not self.dev or nfc.nfc_device_get_last_error(self.dev): + raise IOError(f'nfc.open failed on {cast(conn_strings[0], c_char_p).value}') + + def __del__(self): + if self.dev: + nfc.nfc_close(self.dev) + nfc.nfc_exit(self.context) + + def getTags(self): + log.debug("getting tags") + t0 = time.time() + # see https://github.com/nfc-tools/libfreefare/blob/master/libfreefare/freefare.c + # for how this might waste time on felica tags + ret = freefare.freefare_get_tags(self.dev) + if not ret: + raise IOError("freefare_get_tags returned null") + try: + log.debug(f"found tags in {time.time() - t0}") + for t in ret: + if not t: + break + yield NfcTag(t) + finally: + freefare.freefare_free_tags(ret) + +pubkey = b'\xff\xff\xff\xff\xff\xff' + +class NfcError(Exception): + def __init__(self, code, strerror): + Exception.__init__(self, "%s [%s]" % (strerror, code)) + self.code = code + +class AuthFailedError(NfcError): pass + +class NfcTag(object): + def __init__(self, tag): #FreefareTag + self.tag = tag + + def _check(self, ret: int): + if ret == 0: + return + + msg = cast(freefare.freefare_strerror(self.tag), c_char_p).value + if msg == b'Mifare Authentication Failed': + # return code is -1 (!). I was excpecting + # AUTHENTICATION_ERROR=0xAE or something. + raise AuthFailedError(ret, msg) + + raise NfcError(ret, msg) + + def tagType(self) -> str: + typeNum = freefare.freefare_get_tag_type(self.tag) + return freefare.freefare_tag_type__enumvalues[typeNum] + + def uid(self) -> str: + return cast(freefare.freefare_get_tag_uid(self.tag), + c_char_p).value.decode('ascii') + + def connect(self): + self._check(freefare.mifare_classic_connect(self.tag)) + + def disconnect(self): + self._check(freefare.mifare_classic_disconnect(self.tag)) + + def readBlock(self, blockNumber: int) -> bytes: + blockNum = freefare.MifareClassicBlockNumber(blockNumber) + self._check(freefare.mifare_classic_authenticate( + self.tag, blockNum, (c_ubyte*6)(*pubkey), freefare.MFC_KEY_A)) + + data = freefare.MifareClassicBlock() + self._check(freefare.mifare_classic_read(self.tag, blockNum, pointer(data))) + return ''.join(map(chr, data)) # with trailing nulls + + def writeBlock(self, blockNumber: int, data: str): + blocknum = freefare.MifareClassicBlockNumber(blockNumber) + self._check(freefare.mifare_classic_authenticate( + self.tag, blocknum, (c_ubyte*6)(*pubkey), freefare.MFC_KEY_A)) + + dataBytes = data.encode('utf8') + if len(dataBytes) > 16: + raise ValueError('too long') + dataBlock = (c_ubyte*16)(*dataBytes) + + self._check(freefare.mifare_classic_write(self.tag, blocknum, dataBlock)) + log.info(f" wrote block {blocknum}: {dataBlock}")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/service/cardReader/tags_test.py Wed Feb 05 16:40:46 2020 -0800 @@ -0,0 +1,28 @@ +import unittest +import tags +import time +import os +os.environ['LIBNFC_DEFAULT_DEVICE'] = "pn532_i2c:/dev/i2c-1" +import logging +logging.basicConfig(level=logging.DEBUG) +log = logging.getLogger() + +class TestNfc(unittest.TestCase): + def test_open_close(self): + n = tags.NfcDevice() + del n + + def test_update_tag(self): # writes to the current tag! + n = tags.NfcDevice() + for t in n.getTags(): + print('tag', t) + print(' tagType', t.tagType()) + print(' uid %r' % t.uid()) + t.connect() + try: + print(' block 1', t.readBlock(1)) + print('write') + t.writeBlock(1, 'hello %s' % int(time.time())) + print(' block 1', t.readBlock(1)) + finally: + t.disconnect()
--- a/service/rfid_pn532_py/Dockerfile.pi Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,17 +0,0 @@ -FROM bang6:5000/base_pi - -WORKDIR /opt -RUN apt-get install -y libnfc5 libfreefare0 libnfc-dev libfreefare-dev python3-nose2 libffi-dev -COPY pyfreefare-build-pi ./pyfreefare-build - -COPY requirements.txt . -RUN pip3 install -Ur requirements.txt -# not sure why this doesn't work from inside requirements.txt -RUN pip3 install -U 'https://github.com/drewp/cyclone/archive/python3.zip' - -COPY *.py *.html ./ - -ENV PYTHONPATH=/opt/pyfreefare-build -EXPOSE 10012 - -CMD ["/usr/bin/python3", "rfid.py"]
--- a/service/rfid_pn532_py/Dockerfile.pyfreefare.pi Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -FROM bang6:5000/base_pi - -WORKDIR /opt - -RUN apt-get install -y python-clang-5.0 libclang-5.0-dev libnfc5 libfreefare0 libnfc-dev libfreefare-dev -RUN pip install git+https://github.com/drewp/ctypeslib.git@enable-modules-flag - -COPY build_ctypes_modules.sh ./ - -CMD ["/bin/sh", "/opt/build_ctypes_modules.sh"] \ No newline at end of file
--- a/service/rfid_pn532_py/Dockerfile.pyfreefare.x86 Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,10 +0,0 @@ -FROM bang6:5000/base_x86 - -WORKDIR /opt - -RUN apt-get install -y python-clang-5.0 libclang-5.0-dev libnfc5 libfreefare0 libnfc-dev libfreefare-dev -RUN pip install git+https://github.com/drewp/ctypeslib.git@enable-modules-flag - -COPY build_ctypes_modules.sh ./ - -CMD ["/bin/sh", "/opt/build_ctypes_modules.sh"]
--- a/service/rfid_pn532_py/Dockerfile.x86 Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,18 +0,0 @@ -FROM bang6:5000/base_x86 - -WORKDIR /opt -RUN apt-get install -y libnfc5 libfreefare0 libnfc-dev libfreefare-dev -RUN apt-get install -y python3-nose2 -COPY pyfreefare-build-x86 ./pyfreefare-build - -COPY requirements.txt . -RUN pip3 install -r requirements.txt -# not sure why this doesn't work from inside requirements.txt -RUN pip3 install -U 'https://github.com/drewp/cyclone/archive/python3.zip' - -COPY *.py *.html ./ - -ENV PYTHONPATH=/opt/pyfreefare-build -EXPOSE 10012 - -CMD ["/usr/bin/python3", "rfid.py", "-v"]
--- a/service/rfid_pn532_py/build_ctypes_modules.sh Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -#!/bin/sh -set -x -proc=`uname --processor` -if [ "$proc" = "armv7l" ]; then - ARCH=arm-linux-gnueabihf - TARGET=armv7l -else - ARCH=x86_64-linux-gnu - TARGET=x86_64-Linux -fi -CARGS="-I/usr/include/${ARCH} -I/usr/lib/llvm-5.0/lib/clang/5.0.1/include -I/usr/lib/llvm-5.0/lib/" -clang2py -o /opt/pyfreefare-build/nfc.py --target ${TARGET} --clang-args="${CARGS}" -l /usr/lib/${ARCH}/libnfc.so --comments /opt/pyfreefare/nfc.h - -PYTHONPATH=/opt/pyfreefare-build clang2py -o /opt/pyfreefare-build/freefare.py --target ${TARGET} --clang-args="${CARGS}" -l /usr/lib/${ARCH}/libfreefare.so --comments --module nfc /opt/pyfreefare/freefare.h
--- a/service/rfid_pn532_py/index.html Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -<!doctype html> -<html> - <head> - <title>rfid</title> - <meta charset="utf-8" /> - <meta name="mobile-web-app-capable" content="yes"> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <script src="/lib/polymer/1.0.9/webcomponentsjs/webcomponents.min.js"></script> - <script src="/lib/require/require-2.3.3.js"></script> - <script src="/rdf/common_paths_and_ns.js"></script> - <link rel="import" href="rfid-console.html"> - <style> - .served-resources { - margin-top: 4em; - border-top: 1px solid gray; - padding-top: 1em; - } - .served-resources a { - padding-right: 2em; - } - </style> - </head> - <body> - <rfid-console></rfid-console> - - <template id="t" is="dom-bind"> - <streamed-graph url="graph/events" graph="{{graph}}"></streamed-graph> - <div id="out"></div> - <script type="module" src="/rdf/streamed_graph_view.js"></script> - </template> - - <div class="served-resources"> - <a href="stats/">/stats/</a> - <a href="graph">/graph</a> - <a href="graph/events">/graph/events</a> - <a href="output" >(post) /output</a> - <a href="rewrite">(post) /rewrite</a> - </div> - </body> -</html>
--- a/service/rfid_pn532_py/local.conf Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -daemon off; -pid /dev/null; -error_log stderr; -#worker_processes 1; - -events { - worker_connections 1024; -} - -http { - types { - text/html html; - text/css css; - image/gif gif; - image/jpeg jpeg jpg; - application/x-javascript js; - image/png png; - } - - server { - listen 8888; - - access_log off; - - location / { - proxy_pass http://bang; - proxy_set_header Host bigasterisk.com; - proxy_buffering off; - } - location /frontDoor/rfid/ { - proxy_pass http://localhost:10012; - proxy_set_header Host $http_host; - proxy_buffering off; - rewrite /frontDoor/rfid(.*) $1 break; - } - } -}
--- a/service/rfid_pn532_py/makefile Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -SERVICE=rfid_pn532_py -JOB=rfid -PORT=10012 -RUNHOST=frontdoor - -pyfreefare-build-x86/nfc.py: Dockerfile.pyfreefare.x86 pyfreefare/nfc.h pyfreefare/freefare.h build_ctypes_modules.sh - docker build --file Dockerfile.pyfreefare.x86 -t pyfreefare_build_x86:latest . - docker run --rm --net=host \ - -v `pwd`/pyfreefare:/opt/pyfreefare \ - -v `pwd`/pyfreefare-build-x86:/opt/pyfreefare-build \ - --name pyfreefare_build pyfreefare_build_x86:latest - -pyfreefare-build-pi/nfc.py: Dockerfile.pyfreefare.pi pyfreefare/nfc.h pyfreefare/freefare.h build_ctypes_modules.sh - docker build --file Dockerfile.pyfreefare.pi -t pyfreefare_build_pi:latest . - docker run --rm --net=host \ - -v `pwd`/pyfreefare:/opt/pyfreefare \ - -v `pwd`/pyfreefare-build-pi:/opt/pyfreefare-build \ - --name pyfreefare_build pyfreefare_build_pi:latest - -#pyfreefare/nfc.py pyfreefare/freefare.py -test_tags: tags.py tags_test.py - PYTHONPATH=pyfreefare-build-x86 nose2-3 tags_test - - -build_image_x86: pyfreefare-build-x86/nfc.py pyfreefare-build-x86/freefare.py Dockerfile.x86 - rm -rf tmp_ctx - mkdir -p tmp_ctx - cp -a Dockerfile.x86 ../../lib/*.py *.py *.txt *.html pyfreefare-build-x86 tmp_ctx - docker build --network=host --file Dockerfile.x86 -t bang6:5000/$(SERVICE)_x86:latest tmp_ctx - docker push bang6:5000/$(SERVICE)_x86:latest - -build_image_pi: pyfreefare-build-pi/nfc.py pyfreefare-build-pi/freefare.py Dockerfile.pi - rm -rf tmp_ctx - mkdir -p tmp_ctx - cp -a Dockerfile.pi ../../lib/*.py *.py *.txt *.html pyfreefare-build-pi tmp_ctx - docker build --network=host --file Dockerfile.pi -t bang6:5000/$(SERVICE)_pi:latest tmp_ctx - docker push bang6:5000/$(SERVICE)_pi:latest - -run_local_x86: build_image_x86 - docker run -it --rm --privileged --net=host --hostname=testhost --cap-add=SYS_PTRACE --name $(JOB)_run bang6:5000/$(SERVICE)_x86:latest python3 rfid.py -v - - -# test on pi: -# docker pull bang6:5000/rfid_pn532_py_pi:latest && docker run -it --rm --privileged --name rfid_shell bang6:5000/rfid_pn532_py_pi:latest nose2-3 tags_test - -fresh_sudo: - sudo -v -redeploy: fresh_sudo build_image_pi - sudo /my/proj/ansible/playbook -l $(RUNHOST) -t rfid - supervisorctl -s http://$(RUNHOST):9001/ restart $(JOB)_$(PORT) - -nginx_local: - nginx -c `pwd`/local.conf -
--- a/service/rfid_pn532_py/pyfreefare/freefare.h Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,557 +0,0 @@ - -#ifndef __FREEFARE_H__ -#define __FREEFARE_H__ - -#include <sys/types.h> - -#include <stdint.h> - -#include <nfc/nfc.h> - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -enum freefare_tag_type { - 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, -}; - typedef enum freefare_tag_type freefare_tag_type; - -struct freefare_tag; -typedef struct freefare_tag *FreefareTag; - -/* Replace any MifareTag by the generic FreefareTag. */ -typedef struct freefare_tag *MifareTag; - -struct mifare_desfire_key; -typedef struct mifare_desfire_key *MifareDESFireKey; - -struct ntag21x_key; -typedef struct ntag21x_key *NTAG21xKey; - -typedef uint8_t MifareUltralightPageNumber; -typedef unsigned char MifareUltralightPage[4]; - -FreefareTag *freefare_get_tags(nfc_device *device); -FreefareTag freefare_tag_new(nfc_device *device, nfc_target target); -freefare_tag_type freefare_get_tag_type(FreefareTag tag); -const char *freefare_get_tag_friendly_name(FreefareTag tag); -char *freefare_get_tag_uid(FreefareTag tag); -void freefare_free_tag(FreefareTag tag); -void freefare_free_tags(FreefareTag *tags); -bool freefare_selected_tag_is_present(nfc_device *device); - -const char *freefare_strerror(FreefareTag tag); -int freefare_strerror_r(FreefareTag tag, char *buffer, size_t len); -void freefare_perror(FreefareTag tag, const char *string); - - - - // bool felica_taste(nfc_device *device, nfc_target target); - - // #define FELICA_SC_RW 0x0009 -// #define FELICA_SC_RO 0x000b -// -// FreefareTag felica_tag_new(nfc_device *device, nfc_target target); -// void felica_tag_free(FreefareTag tag); -// -// ssize_t felica_read(FreefareTag tag, uint16_t service, uint8_t block, uint8_t *data, size_t length); -// ssize_t felica_read_ex(FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length); -// ssize_t felica_write(FreefareTag tag, uint16_t service, uint8_t block, uint8_t *data, size_t length); -// ssize_t felica_write_ex(FreefareTag tag, uint16_t service, uint8_t block_count, uint8_t blocks[], uint8_t *data, size_t length); -// -// -// -// bool mifare_ultralight_taste(nfc_device *device, nfc_target target); -// bool mifare_ultralightc_taste(nfc_device *device, nfc_target target); -// FreefareTag mifare_ultralight_tag_new(nfc_device *device, nfc_target target); -// FreefareTag mifare_ultralightc_tag_new(nfc_device *device, nfc_target target); -// void mifare_ultralight_tag_free(FreefareTag tag); -// void mifare_ultralightc_tag_free(FreefareTag tag); -// -// int mifare_ultralight_connect(FreefareTag tag); -// int mifare_ultralight_disconnect(FreefareTag tag); -// -// int mifare_ultralight_read(FreefareTag tag, const MifareUltralightPageNumber page, MifareUltralightPage *data); -// int mifare_ultralight_write(FreefareTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data); -// -// int mifare_ultralightc_authenticate(FreefareTag tag, const MifareDESFireKey key); -// int mifare_ultralightc_set_key(FreefareTag tag, MifareDESFireKey key); -// bool is_mifare_ultralight(FreefareTag tag); -// bool is_mifare_ultralightc(FreefareTag tag); -// bool is_mifare_ultralightc_on_reader(nfc_device *device, nfc_iso14443a_info nai); -// -// -// -// bool ntag21x_taste(nfc_device *device, nfc_target target); -// uint8_t ntag21x_last_error(FreefareTag tag); -// -// /* NTAG21x access features */ -// #define NTAG_PROT 0x80 -// #define NTAG_CFGLCK 0x40 -// #define NTAG_NFC_CNT_EN 0x20 -// #define NTAG_NFC_CNT_PWD_PROT 0x10 -// #define NTAG_AUTHLIM 0x07 -// -// enum ntag_tag_subtype { -// NTAG_UNKNOWN, -// NTAG_213, -// NTAG_215, -// NTAG_216 -// }; -// -// FreefareTag ntag21x_tag_new(nfc_device *device, nfc_target target); -// FreefareTag ntag21x_tag_reuse(FreefareTag tag); /* Copy data from Ultralight tag to new NTAG21x, don't forget to free your old tag */ -// NTAG21xKey ntag21x_key_new(const uint8_t data[4], const uint8_t pack[2]); /* Create new key */ -// void ntag21x_key_free(NTAG21xKey key); /* Clear key from memory */ -// void ntag21x_tag_free(FreefareTag tag); -// int ntag21x_connect(FreefareTag tag); -// int ntag21x_disconnect(FreefareTag tag); -// int ntag21x_get_info(FreefareTag tag); /* Get all information about tag (size,vendor ...) */ -// enum ntag_tag_subtype ntag21x_get_subtype(FreefareTag tag); /* Get subtype of tag */ -// uint8_t ntag21x_get_last_page(FreefareTag tag); /* Get last page address based on gathered info from function above */ -// int ntag21x_read_signature(FreefareTag tag, uint8_t *data); /* Get tag signature */ -// int ntag21x_set_pwd(FreefareTag tag, uint8_t data[4]); /* Set password */ -// int ntag21x_set_pack(FreefareTag tag, uint8_t data[2]); /* Set pack */ -// int ntag21x_set_key(FreefareTag tag, const NTAG21xKey key); /* Set key */ -// int ntag21x_set_auth(FreefareTag tag, uint8_t byte); /* Set AUTH0 byte (from which page starts password protection) */ -// int ntag21x_get_auth(FreefareTag tag, uint8_t *byte); /* Get AUTH0 byte */ -// int ntag21x_access_enable(FreefareTag tag, uint8_t byte); /* Enable access feature in ACCESS byte */ -// int ntag21x_access_disable(FreefareTag tag, uint8_t byte); /* Disable access feature in ACCESS byte */ -// int ntag21x_get_access(FreefareTag tag, uint8_t *byte); /* Get ACCESS byte */ -// int ntag21x_check_access(FreefareTag tag, uint8_t byte, bool *result); /* Check if access feature is enabled */ -// int ntag21x_get_authentication_limit(FreefareTag tag, uint8_t *byte); /* Get authentication limit */ -// int ntag21x_set_authentication_limit(FreefareTag tag, uint8_t byte); /* Set authentication limit (0x00 = disabled, [0x01,0x07] = valid range, > 0x07 invalid range) */ -// int ntag21x_read(FreefareTag tag, uint8_t page, uint8_t *data); /* Read 16 bytes starting from page */ -// int ntag21x_read4(FreefareTag tag, uint8_t page, uint8_t *data); /* Read 4 bytes on page */ -// int ntag21x_fast_read(FreefareTag tag, uint8_t start_page, uint8_t end_page, uint8_t *data); /* Read n*4 bytes from range [start_page,end_page] */ -// int ntag21x_fast_read4(FreefareTag tag, uint8_t page, uint8_t *data); /* Fast read certain page */ -// int ntag21x_read_cnt(FreefareTag tag, uint8_t *data); /* Read 3-byte NFC counter if enabled else it returns error */ -// int ntag21x_write(FreefareTag tag, uint8_t page, uint8_t data[4]); /* Write 4 bytes to page */ -// int ntag21x_compatibility_write(FreefareTag tag, uint8_t page, uint8_t data[4]); /* Writes 4 bytes to page with mifare classic write */ -// int ntag21x_authenticate(FreefareTag tag, const NTAG21xKey key); /* Authenticate with tag */ -// bool is_ntag21x(FreefareTag tag); /* Check if tag type is NTAG21x */ -// bool ntag21x_is_auth_supported(nfc_device *device, nfc_iso14443a_info nai); /* Check if tag supports 21x commands */ -// -// -// -// bool mifare_mini_taste(nfc_device *device, nfc_target target); -// bool mifare_classic1k_taste(nfc_device *device, nfc_target target); -// bool mifare_classic4k_taste(nfc_device *device, nfc_target target); -// FreefareTag mifare_mini_tag_new(nfc_device *device, nfc_target target); -// FreefareTag mifare_classic1k_tag_new(nfc_device *device, nfc_target target); -// FreefareTag mifare_classic4k_tag_new(nfc_device *device, nfc_target target); -void mifare_classic_tag_free(FreefareTag tag); -// -typedef unsigned char MifareClassicBlock[16]; - -typedef uint8_t MifareClassicSectorNumber; -typedef unsigned char MifareClassicBlockNumber; - -typedef enum { MFC_KEY_A, MFC_KEY_B } MifareClassicKeyType; -typedef unsigned char MifareClassicKey[6]; - -/* NFC Forum public key */ -extern const MifareClassicKey mifare_classic_nfcforum_public_key_a; - -int mifare_classic_connect(FreefareTag tag); -int mifare_classic_disconnect(FreefareTag tag); - -int mifare_classic_authenticate(FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicKey key, const MifareClassicKeyType key_type); -int mifare_classic_read(FreefareTag tag, const MifareClassicBlockNumber block, MifareClassicBlock *data); -int mifare_classic_init_value(FreefareTag tag, const MifareClassicBlockNumber block, const int32_t value, const MifareClassicBlockNumber adr); -int mifare_classic_read_value(FreefareTag tag, const MifareClassicBlockNumber block, int32_t *value, MifareClassicBlockNumber *adr); -int mifare_classic_write(FreefareTag tag, const MifareClassicBlockNumber block, const MifareClassicBlock data); - -int mifare_classic_increment(FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount); -int mifare_classic_decrement(FreefareTag tag, const MifareClassicBlockNumber block, const uint32_t amount); -int mifare_classic_restore(FreefareTag tag, const MifareClassicBlockNumber block); -int mifare_classic_transfer(FreefareTag tag, const MifareClassicBlockNumber block); - -int mifare_classic_get_trailer_block_permission(FreefareTag tag, const MifareClassicBlockNumber block, const uint16_t permission, const MifareClassicKeyType key_type); -int mifare_classic_get_data_block_permission(FreefareTag tag, const MifareClassicBlockNumber block, const unsigned char permission, const MifareClassicKeyType key_type); - -int mifare_classic_format_sector(FreefareTag tag, const MifareClassicSectorNumber sector); - -void mifare_classic_trailer_block(MifareClassicBlock *block, const MifareClassicKey key_a, uint8_t ab_0, uint8_t ab_1, uint8_t ab_2, uint8_t ab_tb, const uint8_t gpb, const MifareClassicKey key_b); - -MifareClassicSectorNumber mifare_classic_block_sector(MifareClassicBlockNumber block); -MifareClassicBlockNumber mifare_classic_sector_first_block(MifareClassicSectorNumber sector); -size_t mifare_classic_sector_block_count(MifareClassicSectorNumber sector); -MifareClassicBlockNumber mifare_classic_sector_last_block(MifareClassicSectorNumber sector); - -#define C_000 0 -#define C_001 1 -#define C_010 2 -#define C_011 3 -#define C_100 4 -#define C_101 5 -#define C_110 6 -#define C_111 7 -#define C_DEFAULT 255 - -/* MIFARE Classic Access Bits */ -#define MCAB_R 0x8 -#define MCAB_W 0x4 -#define MCAB_D 0x2 -#define MCAB_I 0x1 - -#define MCAB_READ_KEYA 0x400 -#define MCAB_WRITE_KEYA 0x100 -#define MCAB_READ_ACCESS_BITS 0x040 -#define MCAB_WRITE_ACCESS_BITS 0x010 -#define MCAB_READ_KEYB 0x004 -#define MCAB_WRITE_KEYB 0x001 -// -// struct mad_aid { -// uint8_t application_code; -// uint8_t function_cluster_code; -// }; -// typedef struct mad_aid MadAid; -// -// struct mad; -// typedef struct mad *Mad; -// -// /* MAD Public read key A */ -// extern const MifareClassicKey mad_public_key_a; -// -// /* AID - Adminisration codes */ -// extern const MadAid mad_free_aid; -// extern const MadAid mad_defect_aid; -// extern const MadAid mad_reserved_aid; -// extern const MadAid mad_card_holder_aid; -// extern const MadAid mad_not_applicable_aid; -// -// /* NFC Forum AID */ -// extern const MadAid mad_nfcforum_aid; -// -// Mad mad_new(const uint8_t version); -// Mad mad_read(FreefareTag tag); -// int mad_write(FreefareTag tag, Mad mad, const MifareClassicKey key_b_sector_00, const MifareClassicKey key_b_sector_10); -// int mad_get_version(Mad mad); -// void mad_set_version(Mad mad, const uint8_t version); -// MifareClassicSectorNumber mad_get_card_publisher_sector(Mad mad); -// int mad_set_card_publisher_sector(Mad mad, const MifareClassicSectorNumber cps); -// int mad_get_aid(Mad mad, const MifareClassicSectorNumber sector, MadAid *aid); -// int mad_set_aid(Mad mad, const MifareClassicSectorNumber sector, MadAid aid); -// bool mad_sector_reserved(const MifareClassicSectorNumber sector); -// void mad_free(Mad mad); -// -// MifareClassicSectorNumber *mifare_application_alloc(Mad mad, const MadAid aid, const size_t size); -// ssize_t mifare_application_read(FreefareTag tag, Mad mad, const MadAid aid, void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type); -// ssize_t mifare_application_write(FreefareTag tag, Mad mad, const MadAid aid, const void *buf, size_t nbytes, const MifareClassicKey key, const MifareClassicKeyType key_type); -// int mifare_application_free(Mad mad, const MadAid aid); -// -// MifareClassicSectorNumber *mifare_application_find(Mad mad, const MadAid aid); -// -// -// -// bool mifare_desfire_taste(nfc_device *device, nfc_target target); -// -// /* File types */ -// -// enum mifare_desfire_file_types { -// MDFT_STANDARD_DATA_FILE = 0x00, -// MDFT_BACKUP_DATA_FILE = 0x01, -// MDFT_VALUE_FILE_WITH_BACKUP = 0x02, -// MDFT_LINEAR_RECORD_FILE_WITH_BACKUP = 0x03, -// MDFT_CYCLIC_RECORD_FILE_WITH_BACKUP = 0x04 -// }; -// -// /* Communication mode */ -// -// #define MDCM_PLAIN 0x00 -// #define MDCM_MACED 0x01 -// #define MDCM_ENCIPHERED 0x03 -// -// /* 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 -// */ -// -// #define MDMK_SETTINGS(picc_master_key_settings_changeable,free_create_delete_application,free_listing_apps_and_key_settings,picc_master_key_changeable) ( \ -// (picc_master_key_settings_changeable << 3) | \ -// (free_create_delete_application << 2) | \ -// (free_listing_apps_and_key_settings << 1) | \ -// (picc_master_key_changeable) \ -// ) -// -// /* Mifare DESFire EV1 Application crypto operations */ -// -// #define APPLICATION_CRYPTO_DES 0x00 -// #define APPLICATION_CRYPTO_3K3DES 0x40 -// #define APPLICATION_CRYPTO_AES 0x80 -// -// /* 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 -// */ -// -// #define MDAPP_SETTINGS(key_no_for_key_changing,config_changeable,free_create_delete_files,free_listing_contents,app_master_key_changeable) ( \ -// (key_no_for_key_changing << 4) | \ -// (config_changeable << 3) | \ -// (free_create_delete_files << 2) | \ -// (free_listing_contents << 1) | \ -// (app_master_key_changeable) \ -// ) -// -// /* Access right */ -// -// #define MDAR(read,write,read_write,change_access_rights) ( \ -// (read << 12) | \ -// (write << 8) | \ -// (read_write << 4) | \ -// (change_access_rights) \ -// ) -// -// #define MDAR_READ(ar) (((ar) >> 12) & 0x0f) -// #define MDAR_WRITE(ar) (((ar) >> 8) & 0x0f) -// #define MDAR_READ_WRITE(ar) (((ar) >> 4) & 0x0f) -// #define MDAR_CHANGE_AR(ar) ((ar) & 0x0f) -// -// #define MDAR_KEY0 0x0 -// #define MDAR_KEY1 0x1 -// #define MDAR_KEY2 0x2 -// #define MDAR_KEY3 0x3 -// #define MDAR_KEY4 0x4 -// #define MDAR_KEY5 0x5 -// #define MDAR_KEY6 0x6 -// #define MDAR_KEY7 0x7 -// #define MDAR_KEY8 0x8 -// #define MDAR_KEY9 0x9 -// #define MDAR_KEY10 0xa -// #define MDAR_KEY11 0xb -// #define MDAR_KEY12 0xc -// #define MDAR_KEY13 0xd -// #define MDAR_FREE 0xE -// #define MDAR_DENY 0xF -// -// /* Status and error codes */ -// -// #define OPERATION_OK 0x00 -// #define NO_CHANGES 0x0C -// #define OUT_OF_EEPROM_ERROR 0x0E -// #define ILLEGAL_COMMAND_CODE 0x1C -// #define INTEGRITY_ERROR 0x1E -// #define NO_SUCH_KEY 0x40 -// #define LENGTH_ERROR 0x7E -// #define PERMISSION_ERROR 0x9D -// #define PARAMETER_ERROR 0x9E -// #define APPLICATION_NOT_FOUND 0xA0 -// #define APPL_INTEGRITY_ERROR 0xA1 -// #define AUTHENTICATION_ERROR 0xAE -// #define ADDITIONAL_FRAME 0xAF -// #define BOUNDARY_ERROR 0xBE -// #define PICC_INTEGRITY_ERROR 0xC1 -// #define COMMAND_ABORTED 0xCA -// #define PICC_DISABLED_ERROR 0xCD -// #define COUNT_ERROR 0xCE -// #define DUPLICATE_ERROR 0xDE -// #define EEPROM_ERROR 0xEE -// #define FILE_NOT_FOUND 0xF0 -// #define FILE_INTEGRITY_ERROR 0xF1 -// -// /* Error code managed by the library */ -// -// #define CRYPTO_ERROR 0x01 -// #define TAG_INFO_MISSING_ERROR 0xBA -// #define UNKNOWN_TAG_TYPE_ERROR 0xBB -// -// struct mifare_desfire_aid; -// typedef struct mifare_desfire_aid *MifareDESFireAID; -// -// struct mifare_desfire_df { -// uint32_t aid; -// uint16_t fid; -// uint8_t df_name[16]; -// size_t df_name_len; -// }; -// typedef struct mifare_desfire_df MifareDESFireDF; -// -// MifareDESFireAID mifare_desfire_aid_new(uint32_t aid); -// MifareDESFireAID mifare_desfire_aid_new_with_mad_aid(MadAid mad_aid, uint8_t n); -// uint32_t mifare_desfire_aid_get_aid(MifareDESFireAID aid); -// -// uint8_t mifare_desfire_last_pcd_error(FreefareTag tag); -// uint8_t mifare_desfire_last_picc_error(FreefareTag tag); -// -// #pragma pack (push) -// #pragma pack (1) -// struct mifare_desfire_version_info { -// struct { -// uint8_t vendor_id; -// uint8_t type; -// uint8_t subtype; -// uint8_t version_major; -// uint8_t version_minor; -// uint8_t storage_size; -// uint8_t protocol; -// } hardware; -// struct { -// uint8_t vendor_id; -// uint8_t type; -// uint8_t subtype; -// uint8_t version_major; -// uint8_t version_minor; -// uint8_t storage_size; -// uint8_t protocol; -// } software; -// uint8_t uid[7]; -// uint8_t batch_number[5]; -// uint8_t production_week; -// uint8_t production_year; -// }; -// #pragma pack (pop) -// -// struct mifare_desfire_file_settings { -// uint8_t file_type; -// uint8_t communication_settings; -// uint16_t access_rights; -// union { -// struct { -// uint32_t file_size; -// } standard_file; -// struct { -// int32_t lower_limit; -// int32_t upper_limit; -// int32_t limited_credit_value; -// uint8_t limited_credit_enabled; -// } value_file; -// struct { -// uint32_t record_size; -// uint32_t max_number_of_records; -// uint32_t current_number_of_records; -// } linear_record_file; -// } settings; -// }; -// -// FreefareTag mifare_desfire_tag_new(nfc_device *device, nfc_target target); -// void mifare_desfire_tag_free(FreefareTag tags); -// -// int mifare_desfire_connect(FreefareTag tag); -// int mifare_desfire_disconnect(FreefareTag tag); -// -// int mifare_desfire_authenticate(FreefareTag tag, uint8_t key_no, MifareDESFireKey key); -// int mifare_desfire_authenticate_iso(FreefareTag tag, uint8_t key_no, MifareDESFireKey key); -// int mifare_desfire_authenticate_aes(FreefareTag tag, uint8_t key_no, MifareDESFireKey key); -// int mifare_desfire_change_key_settings(FreefareTag tag, uint8_t settings); -// int mifare_desfire_get_key_settings(FreefareTag tag, uint8_t *settings, uint8_t *max_keys); -// int mifare_desfire_change_key(FreefareTag tag, uint8_t key_no, MifareDESFireKey new_key, MifareDESFireKey old_key); -// int mifare_desfire_get_key_version(FreefareTag tag, uint8_t key_no, uint8_t *version); -// int mifare_desfire_create_application(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no); -// int mifare_desfire_create_application_3k3des(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no); -// int mifare_desfire_create_application_aes(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no); -// -// int mifare_desfire_create_application_iso(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len); -// int mifare_desfire_create_application_3k3des_iso(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len); -// int mifare_desfire_create_application_aes_iso(FreefareTag tag, MifareDESFireAID aid, uint8_t settings, uint8_t key_no, int want_iso_file_identifiers, uint16_t iso_file_id, uint8_t *iso_file_name, size_t iso_file_name_len); -// -// int mifare_desfire_delete_application(FreefareTag tag, MifareDESFireAID aid); -// int mifare_desfire_get_application_ids(FreefareTag tag, MifareDESFireAID *aids[], size_t *count); -// int mifare_desfire_get_df_names(FreefareTag tag, MifareDESFireDF *dfs[], size_t *count); -// void mifare_desfire_free_application_ids(MifareDESFireAID aids[]); -// int mifare_desfire_select_application(FreefareTag tag, MifareDESFireAID aid); -// int mifare_desfire_format_picc(FreefareTag tag); -// int mifare_desfire_get_version(FreefareTag tag, struct mifare_desfire_version_info *version_info); -// int mifare_desfire_free_mem(FreefareTag tag, uint32_t *size); -// int mifare_desfire_set_configuration(FreefareTag tag, bool disable_format, bool enable_random_uid); -// int mifare_desfire_set_default_key(FreefareTag tag, MifareDESFireKey key); -// int mifare_desfire_set_ats(FreefareTag tag, uint8_t *ats); -// int mifare_desfire_get_card_uid(FreefareTag tag, char **uid); -// int mifare_desfire_get_card_uid_raw(FreefareTag tag, uint8_t uid[7]); -// int mifare_desfire_get_file_ids(FreefareTag tag, uint8_t **files, size_t *count); -// int mifare_desfire_get_iso_file_ids(FreefareTag tag, uint16_t **files, size_t *count); -// int mifare_desfire_get_file_settings(FreefareTag tag, uint8_t file_no, struct mifare_desfire_file_settings *settings); -// int mifare_desfire_change_file_settings(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights); -// int mifare_desfire_create_std_data_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size); -// int mifare_desfire_create_std_data_file_iso(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size, uint16_t iso_file_id); -// int mifare_desfire_create_backup_data_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size); -// int mifare_desfire_create_backup_data_file_iso(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t file_size, uint16_t iso_file_id); -// int mifare_desfire_create_value_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, int32_t lower_limit, int32_t upper_limit, int32_t value, uint8_t limited_credit_enable); -// int mifare_desfire_create_linear_record_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records); -// int mifare_desfire_create_linear_record_file_iso(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records, uint16_t iso_file_id); -// int mifare_desfire_create_cyclic_record_file(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records); -// int mifare_desfire_create_cyclic_record_file_iso(FreefareTag tag, uint8_t file_no, uint8_t communication_settings, uint16_t access_rights, uint32_t record_size, uint32_t max_number_of_records, uint16_t iso_file_id); -// int mifare_desfire_delete_file(FreefareTag tag, uint8_t file_no); -// -// ssize_t mifare_desfire_read_data(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data); -// ssize_t mifare_desfire_read_data_ex(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data, int cs); -// ssize_t mifare_desfire_write_data(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, const void *data); -// ssize_t mifare_desfire_write_data_ex(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, const void *data, int cs); -// int mifare_desfire_get_value(FreefareTag tag, uint8_t file_no, int32_t *value); -// int mifare_desfire_get_value_ex(FreefareTag tag, uint8_t file_no, int32_t *value, int cs); -// int mifare_desfire_credit(FreefareTag tag, uint8_t file_no, int32_t amount); -// int mifare_desfire_credit_ex(FreefareTag tag, uint8_t file_no, int32_t amount, int cs); -// int mifare_desfire_debit(FreefareTag tag, uint8_t file_no, int32_t amount); -// int mifare_desfire_debit_ex(FreefareTag tag, uint8_t file_no, int32_t amount, int cs); -// int mifare_desfire_limited_credit(FreefareTag tag, uint8_t file_no, int32_t amount); -// int mifare_desfire_limited_credit_ex(FreefareTag tag, uint8_t file_no, int32_t amount, int cs); -// ssize_t mifare_desfire_write_record(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data); -// ssize_t mifare_desfire_write_record_ex(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data, int cs); -// ssize_t mifare_desfire_read_records(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data); -// ssize_t mifare_desfire_read_records_ex(FreefareTag tag, uint8_t file_no, off_t offset, size_t length, void *data, int cs); -// int mifare_desfire_clear_record_file(FreefareTag tag, uint8_t file_no); -// int mifare_desfire_commit_transaction(FreefareTag tag); -// int mifare_desfire_abort_transaction(FreefareTag tag); -// -// MifareDESFireKey mifare_desfire_des_key_new(const uint8_t value[8]); -// MifareDESFireKey mifare_desfire_3des_key_new(const uint8_t value[16]); -// MifareDESFireKey mifare_desfire_des_key_new_with_version(const uint8_t value[8]); -// MifareDESFireKey mifare_desfire_3des_key_new_with_version(const uint8_t value[16]); -// MifareDESFireKey mifare_desfire_3k3des_key_new(const uint8_t value[24]); -// MifareDESFireKey mifare_desfire_3k3des_key_new_with_version(const uint8_t value[24]); -// MifareDESFireKey mifare_desfire_aes_key_new(const uint8_t value[16]); -// MifareDESFireKey mifare_desfire_aes_key_new_with_version(const uint8_t value[16], uint8_t version); -// uint8_t mifare_desfire_key_get_version(MifareDESFireKey key); -// void mifare_desfire_key_set_version(MifareDESFireKey key, uint8_t version); -// void mifare_desfire_key_free(MifareDESFireKey key); -// -// uint8_t *tlv_encode(const uint8_t type, const uint8_t *istream, uint16_t isize, size_t *osize); -// uint8_t *tlv_decode(const uint8_t *istream, uint8_t *type, uint16_t *size); -// size_t tlv_record_length(const uint8_t *istream, size_t *field_length_size, size_t *field_value_size); -// uint8_t *tlv_append(uint8_t *a, uint8_t *b); -// -// typedef enum mifare_key_type { -// MIFARE_KEY_DES, -// MIFARE_KEY_2K3DES, -// MIFARE_KEY_3K3DES, -// MIFARE_KEY_AES128, -// -// MIFARE_KEY_LAST = MIFARE_KEY_AES128 -// } MifareKeyType; -// -// struct mifare_key_deriver; -// typedef struct mifare_key_deriver *MifareKeyDeriver; -// -// MifareKeyDeriver mifare_key_deriver_new_an10922(MifareDESFireKey master_key, MifareKeyType output_key_type); -// int mifare_key_deriver_begin(MifareKeyDeriver deriver); -// int mifare_key_deriver_update_data(MifareKeyDeriver deriver, const uint8_t *data, size_t len); -// int mifare_key_deriver_update_uid(MifareKeyDeriver deriver, FreefareTag tag); -// int mifare_key_deriver_update_aid(MifareKeyDeriver deriver, MifareDESFireAID aid); -// int mifare_key_deriver_update_cstr(MifareKeyDeriver deriver, const char *cstr); -// MifareDESFireKey mifare_key_deriver_end(MifareKeyDeriver deriver); -// int mifare_key_deriver_end_raw(MifareKeyDeriver deriver, uint8_t* diversified_bytes, size_t data_max_len); -// void mifare_key_deriver_free(MifareKeyDeriver state); - -#ifdef __cplusplus -} -#endif // __cplusplus - -#endif /* !__FREEFARE_H__ */
--- a/service/rfid_pn532_py/pyfreefare/nfc.h Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,516 +0,0 @@ -/*- - * Free/Libre Near Field Communication (NFC) library - * - * Libnfc historical contributors: - * Copyright (C) 2009 Roel Verdult - * Copyright (C) 2009-2013 Romuald Conty - * Copyright (C) 2010-2012 Romain Tartière - * Copyright (C) 2010-2013 Philippe Teuwen - * Copyright (C) 2012-2013 Ludovic Rousseau - * See AUTHORS file for a more comprehensive list of contributors. - * Additional contributors of this file: - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/> - */ - - -/** - * @file nfc.h - * @brief libnfc interface - * - * Provide all usefull functions (API) to handle NFC devices. - */ - - -typedef unsigned char uint8_t; - -# include <sys/time.h> - -# include <stdint.h> -# include <stdbool.h> - -/*- - * Free/Libre Near Field Communication (NFC) library - * - * Libnfc historical contributors: - * Copyright (C) 2009 Roel Verdult - * Copyright (C) 2009-2013 Romuald Conty - * Copyright (C) 2010-2012 Romain Tartière - * Copyright (C) 2010-2013 Philippe Teuwen - * Copyright (C) 2012-2013 Ludovic Rousseau - * See AUTHORS file for a more comprehensive list of contributors. - * Additional contributors of this file: - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/> - */ -/** - * @file nfc-types.h - * @brief Define NFC types - */ - - -#include <stddef.h> -#include <stdint.h> -#include <stdbool.h> -#include <stdio.h> - - -#define NFC_BUFSIZE_CONNSTRING 1024 - - -/** - * NFC context - */ -struct nfc_context; -typedef struct nfc_context nfc_context; - -/** - * NFC device - */ -struct nfc_device; -typedef struct nfc_device nfc_device; - -/** - * NFC device driver - */ -struct nfc_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() - - -/* Library initialization/deinitialization */ -void nfc_init(nfc_context **context); -void nfc_exit(nfc_context *context); -int nfc_register_driver(const nfc_driver *driver); - -/* NFC Device/Hardware manipulation */ -nfc_device *nfc_open(nfc_context *context, const nfc_connstring connstring); -void nfc_close(nfc_device *pnd); -int nfc_abort_command(nfc_device *pnd); -size_t nfc_list_devices(nfc_context *context, nfc_connstring connstrings[], size_t connstrings_len); -int nfc_idle(nfc_device *pnd); - -/* NFC initiator: act as "reader" */ -int nfc_initiator_init(nfc_device *pnd); -int nfc_initiator_init_secure_element(nfc_device *pnd); -int nfc_initiator_select_passive_target(nfc_device *pnd, const nfc_modulation nm, const uint8_t *pbtInitData, const size_t szInitData, nfc_target *pnt); -int nfc_initiator_list_passive_targets(nfc_device *pnd, const nfc_modulation nm, nfc_target ant[], const size_t szTargets); -int nfc_initiator_poll_target(nfc_device *pnd, const nfc_modulation *pnmTargetTypes, const size_t szTargetTypes, const uint8_t uiPollNr, const uint8_t uiPeriod, nfc_target *pnt); -int nfc_initiator_select_dep_target(nfc_device *pnd, const nfc_dep_mode ndm, const nfc_baud_rate nbr, const nfc_dep_info *pndiInitiator, nfc_target *pnt, const int timeout); -int nfc_initiator_poll_dep_target(nfc_device *pnd, const nfc_dep_mode ndm, const nfc_baud_rate nbr, const nfc_dep_info *pndiInitiator, nfc_target *pnt, const int timeout); -int nfc_initiator_deselect_target(nfc_device *pnd); -int nfc_initiator_transceive_bytes(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRx, int timeout); -int nfc_initiator_transceive_bits(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar); -int nfc_initiator_transceive_bytes_timed(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, uint8_t *pbtRx, const size_t szRx, uint32_t *cycles); -int nfc_initiator_transceive_bits_timed(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar, uint32_t *cycles); -int nfc_initiator_target_is_present(nfc_device *pnd, const nfc_target *pnt); - -/* NFC target: act as tag (i.e. MIFARE Classic) or NFC target device. */ -int nfc_target_init(nfc_device *pnd, nfc_target *pnt, uint8_t *pbtRx, const size_t szRx, int timeout); -int nfc_target_send_bytes(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTx, int timeout); -int nfc_target_receive_bytes(nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, int timeout); -int nfc_target_send_bits(nfc_device *pnd, const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar); -int nfc_target_receive_bits(nfc_device *pnd, uint8_t *pbtRx, const size_t szRx, uint8_t *pbtRxPar); - -/* Error reporting */ -const char *nfc_strerror(const nfc_device *pnd); -int nfc_strerror_r(const nfc_device *pnd, char *buf, size_t buflen); -void nfc_perror(const nfc_device *pnd, const char *s); -int nfc_device_get_last_error(const nfc_device *pnd); - -/* Special data accessors */ -const char *nfc_device_get_name(nfc_device *pnd); -const char *nfc_device_get_connstring(nfc_device *pnd); -int nfc_device_get_supported_modulation(nfc_device *pnd, const nfc_mode mode, const nfc_modulation_type **const supported_mt); -int nfc_device_get_supported_baud_rate(nfc_device *pnd, const nfc_modulation_type nmt, const nfc_baud_rate **const supported_br); - -/* Properties accessors */ -int nfc_device_set_property_int(nfc_device *pnd, const nfc_property property, const int value); -int nfc_device_set_property_bool(nfc_device *pnd, const nfc_property property, const bool bEnable); - -/* Misc. functions */ -void iso14443a_crc(uint8_t *pbtData, size_t szLen, uint8_t *pbtCrc); -void iso14443a_crc_append(uint8_t *pbtData, size_t szLen); -void iso14443b_crc(uint8_t *pbtData, size_t szLen, uint8_t *pbtCrc); -void iso14443b_crc_append(uint8_t *pbtData, size_t szLen); -uint8_t *iso14443a_locate_historical_bytes(uint8_t *pbtAts, size_t szAts, size_t *pszTk); - -void nfc_free(void *p); -const char *nfc_version(void); -int nfc_device_get_information_about(nfc_device *pnd, char **buf); - -/* String converter functions */ -const char *str_nfc_modulation_type(const nfc_modulation_type nmt); -const char *str_nfc_baud_rate(const nfc_baud_rate nbr); -int str_nfc_target(char **buf, const nfc_target *pnt, bool verbose); - -/* Error codes */ -/** @ingroup error - * @hideinitializer - * Success (no error) - */ -#define NFC_SUCCESS 0 -/** @ingroup error - * @hideinitializer - * Input / output error, device may not be usable anymore without re-open it - */ -#define NFC_EIO -1 -/** @ingroup error - * @hideinitializer - * Invalid argument(s) - */ -#define NFC_EINVARG -2 -/** @ingroup error - * @hideinitializer - * Operation not supported by device - */ -#define NFC_EDEVNOTSUPP -3 -/** @ingroup error - * @hideinitializer - * No such device - */ -#define NFC_ENOTSUCHDEV -4 -/** @ingroup error - * @hideinitializer - * Buffer overflow - */ -#define NFC_EOVFLOW -5 -/** @ingroup error - * @hideinitializer - * Operation timed out - */ -#define NFC_ETIMEOUT -6 -/** @ingroup error - * @hideinitializer - * Operation aborted (by user) - */ -#define NFC_EOPABORTED -7 -/** @ingroup error - * @hideinitializer - * Not (yet) implemented - */ -#define NFC_ENOTIMPL -8 -/** @ingroup error - * @hideinitializer - * Target released - */ -#define NFC_ETGRELEASED -10 -/** @ingroup error - * @hideinitializer - * Error while RF transmission - */ -#define NFC_ERFTRANS -20 -/** @ingroup error - * @hideinitializer - * MIFARE Classic: authentication failed - */ -#define NFC_EMFCAUTHFAIL -30 -/** @ingroup error - * @hideinitializer - * Software error (allocation, file/pipe creation, etc.) - */ -#define NFC_ESOFT -80 -/** @ingroup error - * @hideinitializer - * Device's internal chip error - */ -#define NFC_ECHIP -90 -
--- a/service/rfid_pn532_py/requirements.txt Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,7 +0,0 @@ -docopt -rdflib-jsonld==0.4.0 -rdflib==4.2.2 -https://projects.bigasterisk.com/rdfdb/rdfdb-0.8.0.tar.gz -git+http://github.com/drewp/scales.git@448d59fb491b7631877528e7695a93553bfaaa93#egg=scales -influxdb==3.0.0 -https://github.com/drewp/cyclone/archive/python3.zip
--- a/service/rfid_pn532_py/rfid-console.html Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -<link rel="import" href="/lib/polymer/1.0.9/iron-ajax/iron-ajax.html"> -<link rel="import" href="/lib/polymer/1.0.9/polymer/polymer.html"> -<link rel="import" href="/rdf/rdf-oneshot.html"> -<link rel="import" href="/rdf/rdf-uri.html"> -<link rel="import" href="/rdf/streamed-graph.html"> - -<dom-module id="rfid-console"> - <style> - button { - min-width: 60px; - min-height: 40px; - } - table { - border-collapse: collapse; - } - - td, th { - border: 1px solid gray; - } - </style> - <template> - - <iron-ajax id="rewrite" url="rewrite" method="POST"></iron-ajax> - - Current RFID reads: - <table> - <tr><th>Card UID</th><th>Card text</th><th></th></tr> - <template is="dom-repeat" items="{{currentReads}}"> - <tr> - <td>{{item.uidDisplay}}</td> - <td>{{item.text}}</td> - <td> - <div id="form"> - <button on-click="rewrite">Rewrite</button> - </div> - </td> - </tr> - </template> - </table> - - <div> - <streamed-graph url="graph/events" graph="{{graph}}"></streamed-graph> - <!-- also get a graph of users so we can look up cards --> - </div> - </template> - <script> - Polymer({ - is: 'rfid-console', - properties: { - graph: { type: Object, notify: true, observer: "_onGraph" }, - currentReads: { type: Array, value: [] }, - }, - behaviors: [BigastUri], - _onGraph: function(graph) { - if (!graph.graph) return; - const env = graph.graph.store.rdf; - - this.splice('currentReads', 0, this.currentReads.length); - graph.graph.quadStore.quads( - {subject: env.createNamedNode('room:frontDoorWindowRfid'), - predicate: env.createNamedNode('room:reading'), - }, - (q) => { - graph.graph.quadStore.quads( - {subject: q.object, - predicate: env.createNamedNode('room:cardText'), - }, - (q2) => { - this.push( - 'currentReads', { - 'cardUid': q.object, - 'uidDisplay': q.object.toString().replace(/.*\//, ""), - 'text': q2.object.toString() - }); - }); - }); - }, - rewrite: function(ev) { - const cardUid = ev.model.item.cardUid; - - // ask for user first - - this.$.rewrite.contentType = "application/json"; - this.$.rewrite.body = {'cardUid': cardUid.toString(), - 'user': "some foaf"}; - this.$.rewrite.generateRequest(); - } - }); - </script> -</dom-module>
--- a/service/rfid_pn532_py/rfid.py Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,230 +0,0 @@ -import os -os.environ['LIBNFC_DEFAULT_DEVICE'] = "pn532_uart:/dev/ttyUSB0" - -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 cyclone -import logging, time, json, random, string, traceback -from logsetup import log, enableTwistedLog -from greplin import scales -from greplin.scales.cyclonehandler import StatsHandler -from export_to_influxdb import InfluxExporter -from tags import NfcDevice, FakeNfc, NfcError, AuthFailedError - -ROOM = Namespace('http://projects.bigasterisk.com/room/') - -ctx = ROOM['frontDoorWindowRfidCtx'] - -STATS = scales.collection('/root', - scales.PmfStat('cardReadPoll'), - scales.IntStat('newCardReads'), -) - -class OutputPage(cyclone.web.RequestHandler): - def put(self): - arg = self.request.arguments - if arg.get('s') and arg.get('p'): - self._onQueryStringStatement(arg['s'][-1], arg['p'][-1], self.request.body) - else: - self._onGraphBodyStatements(self.request.body, self.request.headers) - post = put - def _onQueryStringStatement(self, s, p, body): - subj = URIRef(s) - pred = URIRef(p) - turtleLiteral = self.request.body - try: - obj = Literal(float(turtleLiteral)) - except ValueError: - obj = Literal(turtleLiteral) - self._onStatements([(subj, pred, obj)]) - - def _onGraphBodyStatements(self, body, headers): - g = Graph() - g.parse(StringInputSource(body), format='nt') - if not g: - raise ValueError("expected graph body") - self._onStatements(list(g.triples((None, None, None)))) - post = put - - def _onStatements(self, stmts): - # write rfid to new key, etc. - if len(stmts) > 0 and stmts[0][1] == ROOM['keyContents']: - return - log.warn("ignoring %s", stmts) - -def uidUri(card_id): - return URIRef('http://bigasterisk.com/rfidCard/%s' % card_id) - -BODY_VERSION = "1" -def randomBody(): - return BODY_VERSION + '*' + ''.join(random.choice(string.ascii_uppercase) for n in range(16 - 2)) - -def looksLikeBigasterisk(text): - return text.startswith(BODY_VERSION + "*") - -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 = randomBody() - 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'] - -class ReadLoop(object): - def __init__(self, reader, masterGraph, overwrite_any_tag): - self.reader = reader - self.masterGraph = masterGraph - self.overwrite_any_tag = overwrite_any_tag - self.log = {} # cardIdUri : most recent seentime - - self.pollPeriodSecs = .1 - self.expireSecs = 5 - - # now=False avoids a serious bug where the first read error - # could happen before reactor.run() is called, and then the - # error fails to crash the reactor and get us restarted. - task.LoopingCall(self.poll).start(self.pollPeriodSecs, now=False) - - @STATS.cardReadPoll.time() - def poll(self): - now = time.time() - - self.flushOldReads(now) - - try: - for tag in self.reader.getTags(): # blocks for a bit - uid = tag.uid() - log.debug('detected tag uid=%r', uid) - cardIdUri = uidUri(uid) - - is_new = cardIdUri not in self.log - self.log[cardIdUri] = now - if is_new: - STATS.newCardReads += 1 - tag.connect() - try: - textLit = Literal(tag.readBlock(1).rstrip('\x00')) - if self.overwrite_any_tag and not looksLikeBigasterisk(textLit): - log.info("block 1 was %r; rewriting it", textLit) - tag.writeBlock(1, randomBody()) - textLit = Literal(tag.readBlock(1).rstrip('\x00')) - finally: - # This might not be appropriate to call after - # readBlock fails. I am getting double - # exceptions. - tag.disconnect() - self.startCardRead(cardIdUri, textLit) - except AuthFailedError as e: - log.error(e) - except (NfcError, OSError) as e: - traceback.print_exc() - log.error(e) - reactor.stop() - - def flushOldReads(self, now): - for uri in list(self.log): - if self.log[uri] < now - self.expireSecs: - self.endCardRead(uri) - del self.log[uri] - - def startCardRead(self, cardUri, text): - self.masterGraph.patch(Patch(addQuads=[ - (sensor, ROOM['reading'], cardUri, ctx), - (cardUri, ROOM['cardText'], text, ctx)], - delQuads=[])) - log.info('%s :cardText %s .', cardUri.n3(), text.n3()) - self._sendOneshot([(sensor, ROOM['startReading'], cardUri), - (cardUri, ROOM['cardText'], text)]) - - def endCardRead(self, cardUri): - log.debug(f'{cardUri} has been gone for {self.expireSecs} sec') - 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 = b'http://bang:9071/oneShot' - d = fetch(method=b'POST', - url=url, - headers={b'Content-Type': [b'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 - --overwrite_any_tag Rewrite any unknown tag with a new random body - -n Fake reader - """) - log.setLevel(logging.INFO) - if arg['-v']: - enableTwistedLog() - log.setLevel(logging.DEBUG) - log.info(f'cyclone {cyclone.__version__}') - defer.setDebugging(True) - - masterGraph = PatchableGraph() - reader = NfcDevice() if not arg['-n'] else FakeNfc() - - ie=InfluxExporter(Graph()) - ie.exportStats(STATS, ['root.cardReadPoll.count', - 'root.cardReadPoll.95percentile', - 'root.newCardReads', - ], - period_secs=10, - retain_days=7, - ) - - loop = ReadLoop(reader, masterGraph, overwrite_any_tag=arg['--overwrite_any_tag']) - - port = 10012 - reactor.listenTCP(port, cyclone.web.Application([ - (r"/(|.+\.html)", cyclone.web.StaticFileHandler, - {"path": ".", "default_filename": "index.html"}), - (r"/graph/rfid", CycloneGraphHandler, {'masterGraph': masterGraph}), - (r"/graph/rfid/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()
--- a/service/rfid_pn532_py/tags.py Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,115 +0,0 @@ -import time -from ctypes import pointer, byref, c_ubyte, cast, c_char_p -import nfc, freefare -import logging -log = logging.getLogger('tags') - -class FakeNfc(object): - def getTags(self): - return [] - - -class NfcDevice(object): - def __init__(self): - self.context = pointer(nfc.nfc_context()) - nfc.nfc_init(byref(self.context)) - self.dev = None - - conn_strings = (nfc.nfc_connstring * 10)() - t0, _, t2 = nfc.nfc_list_devices.argtypes - nfc.nfc_list_devices.argtypes = [t0, type(conn_strings), t2] - log.info("nfc_list_devices:") - devices_found = nfc.nfc_list_devices(self.context, conn_strings, 10) - log.info(f'{devices_found} connection strings') - for i in range(devices_found): - log.info(f' dev {i}: {cast(conn_strings[i], c_char_p).value}') - if devices_found < 1: - raise IOError("no devices") - - log.debug("open dev") - self.dev = nfc.nfc_open(self.context, conn_strings[0]) - if not self.dev or nfc.nfc_device_get_last_error(self.dev): - raise IOError(f'nfc.open failed on {cast(conn_strings[0], c_char_p).value}') - - def __del__(self): - if self.dev: - nfc.nfc_close(self.dev) - nfc.nfc_exit(self.context) - - def getTags(self): - log.debug("getting tags") - t0 = time.time() - # see https://github.com/nfc-tools/libfreefare/blob/master/libfreefare/freefare.c - # for how this might waste time on felica tags - ret = freefare.freefare_get_tags(self.dev) - if not ret: - raise IOError("freefare_get_tags returned null") - try: - log.debug(f"found tags in {time.time() - t0}") - for t in ret: - if not t: - break - yield NfcTag(t) - finally: - freefare.freefare_free_tags(ret) - -pubkey = b'\xff\xff\xff\xff\xff\xff' - -class NfcError(Exception): - def __init__(self, code, strerror): - Exception.__init__(self, "%s [%s]" % (strerror, code)) - self.code = code - -class AuthFailedError(NfcError): pass - -class NfcTag(object): - def __init__(self, tag): #FreefareTag - self.tag = tag - - def _check(self, ret: int): - if ret == 0: - return - - msg = cast(freefare.freefare_strerror(self.tag), c_char_p).value - if msg == b'Mifare Authentication Failed': - # return code is -1 (!). I was excpecting - # AUTHENTICATION_ERROR=0xAE or something. - raise AuthFailedError(ret, msg) - - raise NfcError(ret, msg) - - def tagType(self) -> str: - typeNum = freefare.freefare_get_tag_type(self.tag) - return freefare.freefare_tag_type__enumvalues[typeNum] - - def uid(self) -> str: - return cast(freefare.freefare_get_tag_uid(self.tag), - c_char_p).value.decode('ascii') - - def connect(self): - self._check(freefare.mifare_classic_connect(self.tag)) - - def disconnect(self): - self._check(freefare.mifare_classic_disconnect(self.tag)) - - def readBlock(self, blockNumber: int) -> bytes: - blockNum = freefare.MifareClassicBlockNumber(blockNumber) - self._check(freefare.mifare_classic_authenticate( - self.tag, blockNum, (c_ubyte*6)(*pubkey), freefare.MFC_KEY_A)) - - data = freefare.MifareClassicBlock() - self._check(freefare.mifare_classic_read(self.tag, blockNum, pointer(data))) - return ''.join(map(chr, data)) # with trailing nulls - - def writeBlock(self, blockNumber: int, data: str): - blocknum = freefare.MifareClassicBlockNumber(blockNumber) - self._check(freefare.mifare_classic_authenticate( - self.tag, blocknum, (c_ubyte*6)(*pubkey), freefare.MFC_KEY_A)) - - dataBytes = data.encode('utf8') - if len(dataBytes) > 16: - raise ValueError('too long') - dataBlock = (c_ubyte*16)(*dataBytes) - - self._check(freefare.mifare_classic_write(self.tag, blocknum, dataBlock)) - log.info(f" wrote block {blocknum}: {dataBlock}")
--- a/service/rfid_pn532_py/tags_test.py Wed Feb 05 16:39:08 2020 -0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -import unittest -import tags -import time -import os -os.environ['LIBNFC_DEFAULT_DEVICE'] = "pn532_i2c:/dev/i2c-1" -import logging -logging.basicConfig(level=logging.DEBUG) -log = logging.getLogger() - -class TestNfc(unittest.TestCase): - def test_open_close(self): - n = tags.NfcDevice() - del n - - def test_update_tag(self): # writes to the current tag! - n = tags.NfcDevice() - for t in n.getTags(): - print('tag', t) - print(' tagType', t.tagType()) - print(' uid %r' % t.uid()) - t.connect() - try: - print(' block 1', t.readBlock(1)) - print('write') - t.writeBlock(1, 'hello %s' % int(time.time())) - print(' block 1', t.readBlock(1)) - finally: - t.disconnect()