From 12aa0d08e0f8e4924f80917c65965c5bea143afa Mon Sep 17 00:00:00 2001 From: Sebastian Lohff Date: Mon, 2 Jan 2012 23:11:37 +0100 Subject: [PATCH] added draft of rfc1149 printer support --- tunnel/rfc1149/.gitignore | 1 + tunnel/rfc1149/README | 8 ++ tunnel/rfc1149/conf.py | 34 +++++++++ tunnel/rfc1149/rfc1149.py | 145 ++++++++++++++++++++++++++++++++++++ tunnel/rfc1149/tessconf/hex | 1 + 5 files changed, 189 insertions(+) create mode 100644 tunnel/rfc1149/.gitignore create mode 100644 tunnel/rfc1149/README create mode 100644 tunnel/rfc1149/conf.py create mode 100755 tunnel/rfc1149/rfc1149.py create mode 100644 tunnel/rfc1149/tessconf/hex diff --git a/tunnel/rfc1149/.gitignore b/tunnel/rfc1149/.gitignore new file mode 100644 index 0000000..d8de77f --- /dev/null +++ b/tunnel/rfc1149/.gitignore @@ -0,0 +1 @@ +conf_auth.py diff --git a/tunnel/rfc1149/README b/tunnel/rfc1149/README new file mode 100644 index 0000000..0e38b1d --- /dev/null +++ b/tunnel/rfc1149/README @@ -0,0 +1,8 @@ +This is a helper for RFC1149 based networks. It will ask for every +packet if it should be sent or not. + +THIS IS NOT COMPLETE! Until now it is disfunctional (no printer support). + +You need + * tesseract for ocr + * imagemagick diff --git a/tunnel/rfc1149/conf.py b/tunnel/rfc1149/conf.py new file mode 100644 index 0000000..55d10d4 --- /dev/null +++ b/tunnel/rfc1149/conf.py @@ -0,0 +1,34 @@ +# ___________________________________________________ +# | | +# | rfc1149 - ip over avian carrier (quadrocopter) | +# |___________________________________________________| + +import os + +Conf = { + # ======== network settings ======== + # ipsettings for the device + 'devname': '', + 'network': + { + 'address': '10.10.10.10', + 'netmask': '255.255.255.0', + #gateway: '', + 'mtu': 1400, + }, + + # ======== printer settings ======== + 'printerName': None, + 'serial': '/dev/ttyUSB0', + + # ======== printer settings ======== + 'mountpoint': '/mnt/', + 'udevAttrs': + { + 'ID_SERIAL': 'NIKON_D50-0:0', + 'UDISKS_PARTITION_NUMBER': '1', + }, + # ======== misc settings ======== + 'ackPackets': True, +} + diff --git a/tunnel/rfc1149/rfc1149.py b/tunnel/rfc1149/rfc1149.py new file mode 100755 index 0000000..8d36e78 --- /dev/null +++ b/tunnel/rfc1149/rfc1149.py @@ -0,0 +1,145 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import pyudev +import subprocess +import scapy +from scapy.all import IP +import sys +import tempfile +import threading +from zlib import crc32 + +from conf import Conf + +sys.path.append("../../../") + +from ether2any import Ether2Any + +class UdevReader(threading.Thread): + def __init__(self, dev): + threading.Thread.__init__(self) + self.daemon = True + self.context = pyudev.Context() + + self.dev = dev + + self.mountpoint = Conf.get("mountpoint") + self.attrs = Conf.get("udevAttrs") + + def isUsableDevice(self, device): + for k, v in self.attrs.items(): + try: + if not device[k] == v: + print device[k] + return False + except KeyError: + return False + return True + + def readPacket(self): + print " ** Decoding packet" + p = subprocess.Popen("find %s -iname '*jpg' -printf '%%C@ %%p\n'|sort -n|tail -n 1|awk {'print $2'}" % (self.mountpoint,), shell=True, stdout=subprocess.PIPE) + if p.wait() != 0: + return False + imgName = p.stdout.read().strip() + if imgName == "": + print " !! Error: No suitable image found" + return False + print " ++ Using image %s" % imgName + print " ++ Attempting convert + tesseract decoding" + imgFile, txtFile = tempfile.mktemp(suffix=".tif"), tempfile.mktemp() + p = subprocess.Popen("convert %(input)s -colorspace Gray -white-threshold 45%% %(tmpImg)s ; tesseract %(tmpImg)s %(output)s nobatch tessconf/hex" % {'input': imgName, 'tmpImg': imgFile, 'output': txtFile}, shell=True) + if p.wait() != 0: + print " !! Error executing convert/tesseract command" + return False + output = None + try: + outFile = open(txtFile + ".txt", "r") + output = outFile.read() + outFile.close() + except IOError: + print " !! Could not open tesseract output file" + return False + output = output.replace("\n", "").replace(" ", "") + if len(output) % 2 != 0: + print " !! Output of tesseract is not byte aligned" + return False + if len(output) < 10: + print " !! Output of tesseract is not long enough" + return False + + packet = "".join(map(lambda x: chr(int(output[x:x+2], 16)), xrange(0, len(output[0:-8]), 2))) + checksum = int(output[-8:], 16) + calcedChecksum = crc32(packet) & 0xffffffff + if checksum != calcedChecksum: + print " !! Checksum failed (was 0x%08x, should be 0x%08x)" % (checksum, calcedChecksum) + return Falsea + self.dev.write("\x00\x00\x08\x00" + packet) + return True + + def run(self): + monitor = pyudev.Monitor.from_netlink(self.context) + monitor.filter_by(subsystem='block') + for action, device in monitor: + if self.isUsableDevice(device): + self.devname = device['DEVNAME'] + if action == 'add': + print ["/bin/mount", self.devname, self.mountpoint] + p = subprocess.Popen(["/bin/mount", self.devname, self.mountpoint]) + ret = p.wait() + if ret == 0: + print " ++ Mounted camera/card (%s) at %s" % (self.devname, self.mountpoint) + if self.readPacket(): + print " >> Successfully read packet" + else: + print " !! Error reading packet" + print " ** Releasing camera/card (%s)..." % (self.devname,) + subprocess.Popen(["/bin/umount", "-f", self.devname]) + subprocess.Popen("/bin/sync") + print " ** Unmounted" + else: + print " !! Error mounting stick (%s) at %s: Error id %d" % (self.devname, self.mountpoint, ret) + elif action == 'remove': + print " -- Camera/card (%s) removed." % self.devname + + +class RFC1149(Ether2Any): + + def __init__(self): + Ether2Any.__init__(self, tap=False) + + network = Conf.get("network", {'mtu': 1500}) + + self.dev.ifconfig(**network) + self.dev.up() + + self.reader = UdevReader(self.dev) + self.reader.start() + + def toPrinter(self, packet): + packet = packet.upper() + print packet + + def sendToNet(self, packet): + print "packet", repr(packet[4:]) + scp = IP(packet[4:]) + checksum = crc32(packet[4:]) & 0xffffffff + checksumStr = "%08x" % checksum + hexRepr = " ".join(map(lambda x: "%02x" % ord(x), packet[4:])) + " " + " ".join(map(lambda x: checksumStr[x:x+2], range(0, len(checksumStr), 2))) + print " ?>", scp.summary(), " -- hex len", len(hexRepr), "checksum 0x%08x" % checksum + i = "" + while i.lower() not in ("a", "d"): + i = raw_input(" ?? (A)ccept/(D)rop? ") + if i == "a": + # accept the packet! + print " >> Moved one packet to printer" + self.toPrinter(hexRepr) + self.reader.output(hexRepr.replace(" ", "")) + else: + print " -- Dropped" + +if __name__ == '__main__': + rfc1149 = RFC1149() + rfc1149.run() + diff --git a/tunnel/rfc1149/tessconf/hex b/tunnel/rfc1149/tessconf/hex new file mode 100644 index 0000000..e1e4a69 --- /dev/null +++ b/tunnel/rfc1149/tessconf/hex @@ -0,0 +1 @@ +tessedit_char_whitelist 0123456789ABCDEFabcdef