--- /dev/null
+#!/usr/bin/python
+
+import sys
+import socket
+import logging
+import traceback
+from threading import Thread
+from time import sleep
+from protocoll import *
+
+logger = logging.getLogger(__name__)
+
+class NetServer(Thread):
+ def __init__(self, handler=None, handler_connect=None, handler_disconnect=None):
+ Thread.__init__(self)
+ self.setDaemon(True)
+ self.sck = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.sck.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ self.sck.bind(("", 10001))
+ self.sck.listen(1)
+ self.sck.setblocking(0)
+ self.bRun = False
+ self.handler = handler
+ self.handler_connect = handler_connect
+ self.handler_disconnect = handler_disconnect
+ self.start()
+
+ def run(self):
+ self.bRun = True
+ while(self.bRun):
+ sleep(0.01)
+ try:
+ conn, addr = self.sck.accept()
+ #conn.settimeout(0.01)
+ except:
+ continue
+ logger.debug("New Connection")
+ proto = Protocoll(NetWrapper(conn))
+ if self.handler_connect:
+ self.handler_connect(proto)
+ while True:
+ try:
+ addr, msg = proto.receive()
+ except socket.error, e:
+ if e.errno == 11:
+ logger.debug("Connection lost")
+ elif e.errno:
+ logger.debug("Socket Error %d", e.errno)
+ traceback.print_exc(file=sys.stdout)
+ break
+ except TimeoutException:
+ continue
+ except ByteError:
+ continue
+ except NAKReceived:
+ continue
+ except:
+ traceback.print_exc(file=sys.stdout)
+ break
+
+ if self.handler:
+ try:
+ self.handler(addr, msg)
+ except:
+ traceback.print_exc(file=sys.stdout)
+ logger.debug("Connection Ended")
+ if self.handler_disconnect:
+ self.handler_disconnect(proto)
+ conn.close()
+
+ def stop(self):
+ self.bRun = False
+
+
+class NetWrapper:
+ def __init__(self, sck):
+ self.sck = sck
+
+ def write(self, s):
+ return self.sck.send(s)
+
+ def read(self, i):
+ return self.sck.recv(i)
+
+ def close(self):
+ return self.sck.close()
+
+class NetClient(Protocoll, Thread):
+ def __init__(self, kTarget, handler=None):
+ Thread.__init__(self)
+ self.setDaemon(True)
+ self.comm = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.comm.connect(kTarget)
+ self.comm.setblocking(0)
+ self.comm.settimeout(0.01)
+ Protocoll.__init__(self, NetWrapper(self.comm))
+ self.handler = handler
+ self.bRun = False
+
+ def run(self):
+ self.bRun = True
+ while(self.bRun):
+ sleep(0.01)
+ try:
+ addr, msg = self.receive()
+ if self.handler:
+ self.handler(addr, msg)
+ except socket.error, e:
+ if hasattr(e, "errno") and e.errno == 9:
+ #print "Connection lost"
+ break
+ elif e.message == "timed out":
+ pass
+ else:
+ traceback.print_exc(file=sys.stdout)
+ except TimeoutException:
+ pass
+ except:
+ traceback.print_exc(file=sys.stdout)
+ self.comm.close()
+
+ def receive(self):
+ i = 0
+ while True:
+ i+=1
+ try:
+ return Protocoll.receive(self)
+ except:
+ if i > 300:
+ raise
+ sleep(0.01)
+
+ def stop(self):
+ self.bRun = False
+
+
+if __name__ == "__main__":
+ def handler(addr, s):
+ print addr, s
+
+ if sys.argv[1] == "server":
+ pNet = NetServer(handler)
+ while(1):
+ sleep(1)
+ elif sys.argv[1] == "client":
+ pNet = NetClient(("192.168.36.14", 10001))
+ pNet.send(0, "lights")
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: iso-8859-15 -*-
+
+import struct
+import threading
+import math
+from pycrc.crc_algorithms import Crc
+
+class ByteError(Exception):
+ def __init__(self, value):
+ Exception.__init__(self)
+ self.value = value
+ def __str__(self):
+ return "Byte Error, got 0x%x" % self.value
+
+class CRCError(Exception):
+ def __str__(self):
+ return "CRC Error"
+
+class TimeoutException(Exception):
+ def __str__(self):
+ return "Timeout"
+
+class NAKReceived(Exception):
+ def __str__(self):
+ return "NAK received"
+
+class PackageTooBigException(Exception):
+ def __str__(self):
+ return "Package too long"
+
+
+class Protocoll:
+ ENQ = 0x5
+ ACK = 0x6
+ DC1 = 0x11
+ NAK = 0x21
+ MAX_LEN = 128
+ STATE_DEFAULT = 0
+ STATE_LEN = 1
+ STATE_READ = 2
+
+ def __init__(self, conn):
+ self.conn = conn
+ self.lock = threading.Lock()
+ self.crc = Crc(width = 8, poly = 0x07, reflect_in = False, xor_in = 0x0, reflect_out = False, xor_out = 0x00)
+
+ def __get_ack(self):
+ c = ""
+ for i in range(60):
+ try:
+ c = self.conn.read(1)
+ except:
+ continue
+ if c:
+ break
+ if not c:
+ self.conn.close()
+ raise TimeoutException()
+ c = ord(c)
+ if c not in (self.ACK, self.NAK):
+ raise ByteError(c)
+ return c == self.ACK
+
+ def send(self, addr, msg, bSlitMsg=False):
+ msg_len = 3 + len(msg) + 1
+ if bSlitMsg and msg_len > self.MAX_LEN:
+ num_per_packet = self.MAX_LEN - 3 - 1
+ num_packets = math.ceil(len(msg)/float(num_per_packet))
+ self.send(addr, "%cSplit %d" % (self.DC1, num_packets))
+ for i in range(0, len(msg), num_per_packet):
+ msg_part = msg[i:i+num_per_packet]
+ self.send(addr, msg_part)
+ return
+ self.lock.acquire()
+ try:
+ if msg_len > self.MAX_LEN:
+ raise PackageTooBigException()
+ packet = struct.pack("<BBB%ds" % len(msg), self.ENQ, msg_len, addr, msg)
+ packet+=chr(self.crc.bit_by_bit_fast(packet))
+ self.conn.write(packet)
+ if not self.__get_ack():
+ raise NAKReceived()
+ except:
+ raise
+ finally:
+ self.lock.release()
+
+ def write(self, addr, msg):
+ return self.send(addr, msg)
+
+ def __reply_ack(self):
+ self.conn.write(chr(self.ACK))
+
+ def __reply_nak(self):
+ self.conn.write(chr(self.NAK))
+
+ def receive(self):
+ packet = ""
+ num = 0
+ state = self.STATE_DEFAULT
+ self.lock.acquire()
+ try:
+ while(True):
+ c = self.conn.read(1)
+ if not c:
+ raise
+ if state == self.STATE_DEFAULT:
+ if ord(c) != self.ENQ:
+ self.__reply_nak()
+ raise ByteError(ord(c))
+ state = self.STATE_LEN
+ packet = c
+ elif state == self.STATE_LEN:
+ if ord(c) > self.MAX_LEN:
+ self.__reply_nak()
+ raise PackageTooBigException()
+ state = self.STATE_READ
+ packet += c
+ num = ord(c)-2
+ elif state == self.STATE_READ:
+ packet += c
+ num-=1
+ if num == 0:
+ if self.crc.bit_by_bit_fast(packet) == 0:
+ self.__reply_ack()
+ msgtype, msglen, addr, msg, crc = struct.unpack("<BBB%dsB" % (len(packet)-3-1), packet)
+ return addr, msg
+ else:
+ self.__reply_nak()
+ raise CRCError()
+ except:
+ raise
+ finally:
+ self.lock.release()
+
+ def read(self):
+ addr, msg = self.receive()
+ if msg[0] == chr(self.DC1) and len(msg) > 1:
+ lCmd = msg[1:].split()
+ if len(lCmd) == 2 and lCmd[0] == "Split":
+ num = int(lCmd[1])
+ msg = ""
+ for i in range(num):
+ addr_part, msg_part = self.receive()
+ if addr_part == addr:
+ msg+=msg_part
+ return addr, msg