From ae292f1d847c8575945e75144ee065c1cf408c27 Mon Sep 17 00:00:00 2001 From: Arturo Hernandez Date: Wed, 2 May 2018 17:09:33 -0400 Subject: [PATCH] added verbose mode (and fixed print statements for python3) better tcp and python3 support (still todo test --- zk/base.py | 205 ++++++++++++++++++++++++++++++++------------------- zk/finger.py | 4 +- 2 files changed, 131 insertions(+), 78 deletions(-) diff --git a/zk/base.py b/zk/base.py index f7badf0..89a54e2 100644 --- a/zk/base.py +++ b/zk/base.py @@ -86,7 +86,7 @@ class ZK_helper(object): class ZK(object): """ Clase ZK """ - def __init__(self, ip, port=4370, timeout=60, password=0, force_udp=False, ommit_ping=False): + def __init__(self, ip, port=4370, timeout=60, password=0, force_udp=False, ommit_ping=False, verbose=False): """ initialize instance """ self.is_connect = False self.is_enabled = True #let's asume @@ -99,6 +99,7 @@ class ZK(object): #self.firmware = int(firmware) #dummy self.force_udp = force_udp self.ommit_ping = ommit_ping + self.verbose = verbose self.tcp = False self.users = 0 self.fingers = 0 @@ -248,7 +249,7 @@ class ZK(object): """ t = t.encode('hex') t = int(self.__reverse_hex(t), 16) - #print ("decode from %s "% format(t, '04x')) + if self.verbose: print ("decode from %s "% format(t, '04x')) """ t = unpack("= (bytes + 32): #complete + if response == const.CMD_DATA: + resp = data_recv[16:bytes+16] # no ack? + if self.verbose: print ("resp len", len(resp)) + return Finger(uid, temp_id, 1, resp) + else: + if self.verbose: print("broken packet!!!") + return None #broken + else: # incomplete + data.append(data_recv[16:]) # w/o tcp and header + bytes -= recieved-16 + while bytes>0: #jic + data_recv = self.__sock.recv(bytes) #ideal limit? + recieved = len(data_recv) + data.append(data_recv) # w/o tcp and header + bytes -= recieved + data_recv = self.__sock.recv(16) + response = unpack('HHHH', data_recv[8:16])[0] + if response == const.CMD_ACK_OK: + resp = b''.join(data) + return Finger(uid, temp_id, 1, resp) + #data_recv[bytes+16:].encode('hex') #included CMD_ACK_OK + if self.verbose: print("bad response %s" % data_recv) + if self.verbose: print(data) + return None + #else udp size = bytes while True: #limitado por respuesta no por tamaño - data_recv = self.__sock.recv(1032) + data_recv = self.__sock.recv(response_size) response = unpack('HHHH', data_recv[:8])[0] - #print("# %s packet response is: %s" % (pac, response)) + if self.verbose: print("# %s packet response is: %s" % (pac, response)) if response == const.CMD_DATA: data.append(data_recv[8:]) #header turncated bytes -= 1024 @@ -882,19 +932,20 @@ class ZK(object): break #without problem. else: #truncado! continuar? - #print("broken!") + if self.verbose: print("broken!") break - #print("still needs %s" % bytes) + if self.verbose: print("still needs %s" % bytes) data = b''.join(data) + self.free_data() #uid 32 fing 03, starts with 4d-9b-53-53-32-31 - return Finger(size, uid, temp_id, 1, data) + return Finger(uid, temp_id, 1, data) def get_templates(self): """ return array of all fingers """ templates = [] templatedata, size = self.read_with_buffer(const.CMD_DB_RRQ, const.FCT_FINGERTMP) if size < 4: - print("WRN: no user data") # debug + if self.verbose: print("WRN: no user data") # debug return [] total_size = unpack('i', templatedata[0:4])[0] templatedata = templatedata[4:] #total size not used @@ -902,8 +953,8 @@ class ZK(object): while total_size: size, uid, fid, valid = unpack('HHbb',templatedata[:6]) template = unpack("%is" % (size-6), templatedata[6:size])[0] - finger = Finger(size, uid, fid, valid, template) - #print(finger) # test + finger = Finger(uid, fid, valid, template) + if self.verbose: print(finger) # test templates.append(finger) templatedata = templatedata[size:] total_size -= size @@ -916,14 +967,14 @@ class ZK(object): return [] users = [] userdata, size = self.read_with_buffer(const.CMD_USERTEMP_RRQ, const.FCT_USER) - #print("user size %i" % size) + if self.verbose: print("user size %i" % size) if size <= 4: - print("WRN: no user data")# debug + if self.verbose: print("WRN: no user data")# debug return [] total_size = unpack("I",userdata[:4])[0] self.user_packet_size = total_size / self.users if not self.user_packet_size in [28, 72]: - print("WRN packet size would be %i" % self.user_packet_size) + if self.verbose: print("WRN packet size would be %i" % self.user_packet_size) userdata = userdata[4:] if self.user_packet_size == 28: while len(userdata) >= 28: @@ -938,7 +989,7 @@ class ZK(object): name = "NN-%s" % user_id user = User(uid, name, privilege, password, group_id, user_id, card) users.append(user) - #print("[6]user:",uid, privilege, password, name, card, group_id, timezone, user_id) + if self.verbose: print("[6]user:",uid, privilege, password, name, card, group_id, timezone, user_id) userdata = userdata[28:] else: while len(userdata) >= 72: @@ -1006,13 +1057,13 @@ class ZK(object): if not user_id: #we need user_id (uid2) users = self.get_users() - users = filter(lambda x: x.uid==uid, users) + users = list(filter(lambda x: x.uid==uid, users)) if len(users) >= 1: user_id = users[0].user_id else: #double? posibly empty return False #can't enroll if self.tcp: - command_string = pack('<24sbb',str(user_id), temp_id, 1) # el 1 es misterio + command_string = pack('<24sbb',str(user_id).encode(), temp_id, 1) # el 1 es misterio else: command_string = pack(' 16: #not empty res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0] - print("res %i" % res) + if self.verbose: print("res %i" % res) if res == 0 or res == 6 or res == 4: # 6 timeout, 4 mismatch error, 0 can't start(why?) - print ("posible timeout o reg Fallido") + if self.verbose: print ("posible timeout o reg Fallido") break else: if len(data_recv) > 8: #not empty res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0] - print("res %i" % res) + if self.verbose: print("res %i" % res) if res == 6 or res == 4: - print ("posible timeout o reg Fallido") + if self.verbose: print ("posible timeout o reg Fallido") break - print ("A:%i esperando 2do regevent" % attempts) + if self.verbose: print ("A:%i esperando 2do regevent" % attempts) data_recv = self.__sock.recv(1032) # timeout? tarda bastante... self.__ack_ok() - #print ((data_recv).encode('hex')) + if self.verbose: print ((data_recv).encode('hex')) if self.tcp: if len(data_recv) > 8: #not empty res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0] - print("res %i" % res) + if self.verbose: print("res %i" % res) if res == 6 or res == 4: - print ("posible timeout o reg Fallido") + if self.verbose: print ("posible timeout o reg Fallido") break elif res == 0x64: - print ("ok, continue?") + if self.verbose: print ("ok, continue?") attempts -= 1 else: if len(data_recv) > 8: #not empty res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0] - print("res %i" % res) + if self.verbose: print("res %i" % res) if res == 6 or res == 4: - print ("posible timeout o reg Fallido") + if self.verbose: print ("posible timeout o reg Fallido") break elif res == 0x64: - print ("ok, continue?") + if self.verbose: print ("ok, continue?") attempts -= 1 if attempts == 0: - print ("esperando 3er regevent") + if self.verbose: print ("esperando 3er regevent") data_recv = self.__sock.recv(1032) # timeout? tarda bastante... self.__ack_ok() - #print ((data_recv).encode('hex')) + if self.verbose: print ((data_recv).encode('hex')) if self.tcp: res = unpack("H", data_recv.ljust(24,b"\x00")[16:18])[0] else: res = unpack("H", data_recv.ljust(16,b"\x00")[8:10])[0] - print("res %i" % res) + if self.verbose: print("res %i" % res) if res == 5: - print ("huella duplicada") + if self.verbose: print ("huella duplicada") if res == 6 or res == 4: - print ("posible timeout o reg Fallido") + if self.verbose: print ("posible timeout o reg Fallido") if res == 0: size = unpack("H", data_recv.ljust(16,b"\x00")[10:12])[0] pos = unpack("H", data_recv.ljust(16,b"\x00")[12:14])[0] - print("enroll ok", size, pos) + if self.verbose: print("enroll ok", size, pos) done = True self.__sock.settimeout(self.__timeout) + self.reg_event(0) # TODO: test self.cancel_capture() self.verify_user() return done @@ -1103,7 +1155,7 @@ class ZK(object): self.end_live_capture = False while not self.end_live_capture: try: - print ("esperando event") + if self.verbose: print ("esperando event") data_recv = self.__sock.recv(1032) self.__ack_ok() if self.tcp: @@ -1115,10 +1167,10 @@ class ZK(object): header = unpack('HHHH', data_recv[:8]) data = data_recv[8:] if not header[0] == const.CMD_REG_EVENT: - print("not event!") + if self.verbose: print("not event!") continue # or raise error? if not len(data): - print ("empty") + if self.verbose: print ("empty") continue """if len (data) == 5: @@ -1126,7 +1178,7 @@ class ZK(object): if len(data) == 12: #class 1 attendance user_id, status, match, timehex = unpack('= (bytes + 32): #complete if response == const.CMD_DATA: resp = data_recv[16:bytes+16] # no ack? - #print ("resp len", len(resp)) + if self.verbose: print ("resp len", len(resp)) return resp else: - print("broken packet!!!") + if self.verbose: print("broken packet!!!") return '' #broken else: # incomplete data.append(data_recv[16:]) # w/o tcp and header @@ -1215,14 +1268,14 @@ class ZK(object): if response == const.CMD_ACK_OK: return b''.join(data) #data_recv[bytes+16:].encode('hex') #included CMD_ACK_OK - print("bad response %s" % data_recv) - #print data + if self.verbose: print("bad response %s" % data_recv) + if self.verbose: print (data) return '' #else udp while True: #limitado por respuesta no por tamaño data_recv = self.__sock.recv(response_size) response = unpack('HHHH', data_recv[:8])[0] - #print ("# %s packet response is: %s" % (pac, response)) + if self.verbose: print ("# %s packet response is: %s" % (pac, response)) if response == const.CMD_DATA: data.append(data_recv[8:]) #header turncated bytes -= 1024 #UDP @@ -1230,9 +1283,9 @@ class ZK(object): break #without problem. else: #truncado! continuar? - print ("broken!") + if self.verbose: print ("broken!") break - #print ("still needs %s" % bytes) + if self.verbose: print ("still needs %s" % bytes) return b''.join(data) def read_with_buffer(self, command, fct=0 ,ext=0): @@ -1242,7 +1295,7 @@ class ZK(object): else: MAX_CHUNK = 16 * 1024 command_string = pack('= 8: uid, status, timestamp = unpack('HH4s', attendance_data.ljust(8, b'\x00')[:8]) - #print attendance_data[:8].encode('hex') + if self.verbose: print (codecs.encode(attendance_data[:8], 'hex')) attendance_data = attendance_data[8:] - tuser = filter(lambda x: x.uid == uid, users) + tuser = list(filter(lambda x: x.uid == uid, users)) if not tuser: user_id = str(uid) #TODO revisar pq else: @@ -1299,13 +1352,13 @@ class ZK(object): elif record_size == 16: # extended while len(attendance_data) >= 16: user_id, timestamp, status, verified, reserved, workcode = unpack('= 40: uid, user_id, sparator, timestamp, status, space = unpack('