changeset 401:a30ae57209b9

tags module and pynfc build steps Ignore-this: 11baf8329ae6e942eba2330a15abe675
author drewp@bigasterisk.com
date Wed, 27 Feb 2019 10:28:44 -0800
parents 1b303e7542a3
children 2e684f93ec25
files service/rfid_pn532_py/Dockerfile.pyfreefare service/rfid_pn532_py/makefile service/rfid_pn532_py/tags.py service/rfid_pn532_py/tags_test.py
diffstat 4 files changed, 145 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532_py/Dockerfile.pyfreefare	Wed Feb 27 10:28:44 2019 -0800
@@ -0,0 +1,9 @@
+FROM bang6:5000/base_x86
+
+WORKDIR /opt
+
+
+RUN apt-get install -y python-clang-6.0 libclang-6.0-dev
+RUN pip install ctypeslib2
+
+RUN apt-get install -y libnfc5 libfreefare0 libnfc-dev libfreefare-dev 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532_py/makefile	Wed Feb 27 10:28:44 2019 -0800
@@ -0,0 +1,21 @@
+
+pyfreefare_build_image: Dockerfile.pyfreefare
+	docker build --file Dockerfile.pyfreefare -t pyfreefare_build:latest .
+
+pyfreefare/nfc.py: pyfreefare_build_image pyfreefare/nfc.h
+	docker run --rm --net=host -v /my/proj/homeauto/service/rfid_pn532_py/pyfreefare:/opt/pyfreefare --name pyfreefare_build pyfreefare_build:latest \
+          clang2py -o /opt/pyfreefare/nfc.py \
+              --target x86_64-Linux \
+              --clang-args="-I=/usr/include/x86_64-linux-gnu  -I/usr/lib/llvm-6.0/lib/clang/6.0.0/include -I/usr/lib/llvm-6.0/lib/ -v -xc" \
+              /opt/pyfreefare/nfc.h
+
+pyfreefare/freefare.py: pyfreefare_build_image pyfreefare/freefare.py
+	docker run --rm --net=host -v /my/proj/homeauto/service/rfid_pn532_py/pyfreefare:/opt/pyfreefare --name pyfreefare_build pyfreefare_build:latest \
+          clang2py -o /opt/pyfreefare/freefare.py \
+              --target x86_64-Linux \
+              --clang-args="-I=/usr/include/x86_64-linux-gnu  -I/usr/lib/llvm-6.0/lib/clang/6.0.0/include -I/usr/lib/llvm-6.0/lib/ -v -xc"  \
+              /opt/pyfreefare/freefare.h
+
+#pyfreefare/nfc.py pyfreefare/freefare.py
+test_tags: tags.py tags_test.py 
+	PYTHONPATH=pyfreefare nose2-3 tags_test
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532_py/tags.py	Wed Feb 27 10:28:44 2019 -0800
@@ -0,0 +1,113 @@
+import nfc, freefare
+import logging
+log = logging.getLogger('tags')
+
+class NfcDevice(object):
+    def __init__(self):
+        context = ptr nfc.nfc_context
+        nfc.nfc_init(context)
+
+        '''
+          var connstrings: array[10, nfc.connstring]
+          var n = nfc.list_devices(result.context,
+                                   cast[ptr nfc.connstring](addr connstrings),
+                                   len(connstrings))
+          info(&"{n} connection strings")
+          for i in 0 ..< n:
+            info(&"  dev {i}: {join(connstrings[i])}")
+
+          info("open dev")
+          result.dev = nfc.open(result.context, connstrings[0])
+          let dev = result.dev
+          check(device_get_last_error(dev),
+                &"nfc.open failed on {join(connstrings[0])}")
+        '''
+
+    def __del__(self):
+        nfc.close(self.dev)
+        nfc.exit(self.context)
+
+    def getTags(self):
+        log.info("getting tags")
+        t0 = time.time()
+        ret = freefare.freefare_get_tags(self.dev)
+        if not ret: raise IOError("freefare_get_tags returned null")
+        log.info(f"found tags in {time.time() - t0}")
+        return ret
+
+    # freefare lib wants to free all the tag memory, so process them in a
+    # callback and don't keep them outside that.
+    def forAllTags(self, onTag: (NfcTag) -> None):
+        ret = self.getTags()
+        for tagp in ret:
+          if isNil(tagp):
+            break
+          if cast[int](tagp) < 10:
+            # pointer value looks wrong
+            break
+  
+          let tag: FreefareTag = tagp[]
+          if isNil(tag):
+            break
+          onTag(NfcTag(tag: tag))
+        freefare.freefare_free_tags(ret)
+
+def blockFromString(s: str):
+    result = MifareClassicBlock()
+    for i in 0..result.high:
+      if i < s.len:
+        result[i] = s[i]
+      else:
+        result[i] = '\x00'
+    return result
+  
+proc stringFromBlock(b: MifareClassicBlock) -> string
+  return ''.join(b)#cast[array[16,char]](b).join
+  
+type TagArray {.unchecked.} = array[999, ptr FreefareTag]
+
+pubkey = ['\xff', '\xff', '\xff', '\xff', '\xff', '\xff']
+
+def check(ret, msg):
+    if ret != 0:
+        raise IOError(msg)
+
+class NfcTag(object):
+    def __init__(self, tag): #FreefareTag
+        self.tag = tag
+
+    def tagType(self): freefare.freefare_tag_type =
+        return freefare.freefare_get_tag_type(self.tag)
+
+    def uid(self):
+        return freefare.freefare_get_tag_uid(self.tag)
+
+    def connect(self):
+        check(freefare.mifare_classic_connect(self.tag), "connect")
+
+    def disconnect(self):
+        check(freefare.mifare_classic_disconnect(self.tag), "disconnect")
+
+    def readBlock(self, blockNumber: int) -> string:
+      blockNum = cast[freefare.MifareClassicBlockNumber](blockNumber)
+      check(freefare.mifare_classic_authenticate(
+        self.tag, blockNum, pubkey, freefare.MFC_KEY_A),
+            &"mifare_classic_authenticate() failed")
+
+      var data: freefare.MifareClassicBlock
+
+      check(mifare_classic_read(self.tag, blockNum, addr data),
+            "classic_read() failed")
+      return toString(data)
+
+    def writeBlock(self,
+                    blockNumber: int,
+                    data: freefare.MifareClassicBlock) =
+      var blocknum = cast[freefare.MifareClassicBlockNumber](blockNumber)
+      check(freefare.mifare_classic_authenticate(
+        self.tag, blocknum, pubkey, freefare.MFC_KEY_A),
+            &"mifare_classic_authenticate() failed")
+
+      check(mifare_classic_write(self.tag, blocknum, data),
+            "classic_write() failed")
+      log.info(&"  wrote block {blocknum}: {data}")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/service/rfid_pn532_py/tags_test.py	Wed Feb 27 10:28:44 2019 -0800
@@ -0,0 +1,2 @@
+import unittest
+import tags