diff --git a/Utils/CamManager.py b/Utils/CamManager.py index 170465462..23097444b 100644 --- a/Utils/CamManager.py +++ b/Utils/CamManager.py @@ -16,8 +16,6 @@ # based on https://github.com/OpenIPC/python-dvr/blob/master/DeviceManager.py """ -from __future__ import print_function, unicode_literals, division, absolute_import - import os, sys, struct, fcntl, json from locale import getlocale from subprocess import check_output @@ -25,13 +23,7 @@ import platform from datetime import * import hashlib, base64 - -try: - from dvrip import DVRIPCam - -except ImportError: - print("Exiting: dvrip module not found. This script cannot run on Python 2.") - sys.exit(1) +from dvrip import DVRIPCam try: try: @@ -47,7 +39,7 @@ GUI_TK = False # list of preffered interfaces - camera is supposed to be connected to a wired interface -intfs = ['eth0', 'eno1'] +intfs = ['eth', 'eno', 'wlx', 'enx'] devices = {} log = "search.log" icon = "R0lGODlhIAAgAPcAAAAAAAkFAgwKBwQBABQNBRAQDQQFERAOFA4QFBcWFSAaFCYgGAoUMhwiMSUlJCsrKyooJy8wLjUxLjkzKTY1Mzw7OzY3OEpFPwsaSRsuTRUsWD4+QCo8XQAOch0nYB05biItaj9ARjdHYiRMfEREQ0hIR0xMTEdKSVNOQ0xQT0NEUVFNUkhRXlVVVFdYWFxdXFtZVV9wXGZjXUtbb19fYFRda19gYFZhbF5wfWRkZGVna2xsa2hmaHFtamV0Ynp2aHNzc3x8fHh3coF9dYJ+eH2Fe3K1YoGBfgIgigwrmypajDtXhw9FpxFFpSdVpzlqvFNzj0FvnV9zkENnpUh8sgdcxh1Q2jt3zThi0SJy0Dl81Rhu/g50/xp9/x90/zB35TJv8DJ+/EZqzj2DvlGDrlqEuHqLpHeQp26SuhqN+yiC6imH/zSM/yqa/zeV/zik/1aIwlmP0mmayWSY122h3VWb6kyL/1yP8UGU/UiW/VWd/miW+Eqp/12k/1Co/1yq/2Gs/2qr/WKh/nGv/3er9mK3/3K0/3e4+4ODg4uLi4mHiY+Qj5WTjo+PkJSUlJycnKGem6ShnY2ZrKOjo6urrKqqpLi0prS0tLu8vMO+tb+/wJrE+bzf/sTExMfIx8zMzMjIxtrWyM/Q0NXU1NfY193d3djY1uDf4Mnj+931/OTk5Ozs7O/v8PLy8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAgACAAAAj+AAEIHEiwoMGDCBMqXMiwocOHECNKnEixosWLGDNq3Mgx4iVMnTyJInVKlclSpD550nRpUqKGmD59EjWqlMlVOFWdIgWq0iNNoBIhSujokidPn0aNKrmqVStWqjxRumTqyI5KOxI5OpiIkiakNG2yelqK5alKLSAJgbBBB6RIjArmCKLIkV1HjyZNpTTJFKgSQoI4cGBiBxBIR6QM6TGQxooWL3LwMBwkSJEcLUq8YATDAZAdMkKh+GGpAo0cL1wInJuokSNIeqdeCgLBAoVMR2CEMkHDzAcnTCzsCAKERwsXK3wYKYLIdd6pjh4guCGJw5IpT7R8CeNlCwsikx7+JTJ+PAZlRHXxOgqBAQMTLXj0AAKkJw+eJw6CXGqJyAWNyT8QgZ5rsD2igwYEOOEGH38EEoghgcQhQgJAxISJI/8ZNoQUijiX1yM7NIBAFm3wUcghh9yBhQcCFEBDJ6V8MskKhgERxBGMMILXI7AhsoAAGSgRBRlliLHHHlZgMAAJmLByCiUnfGajFEcgotVzjkhggAYjjBHFFISgkoodSDAwAyStqDIJAELs4CYQQxChVSRTQcJCFWmUyAcghmzCCRgdXCEHEU69VJiNdDmnV0s4rNHFGmzgkUcfhgiShAd0nNHDVAc9YIEFFWxAQgkVpKAGF1yw4UYdc6AhhQohJFiwQAIRPQCHFlRAccMJFCRAgAAVJXDBBAsQEEBHDwUEADs=" @@ -79,66 +71,66 @@ # return locale[lang][msg] # return msg -""" + CODES = { - 100: _("Success"), - 101: _("Unknown error"), - 102: _("Version not supported"), - 103: _("Illegal request"), - 104: _("User has already logged in"), - 105: _("User is not logged in"), - 106: _("Username or Password is incorrect"), - 107: _("Insufficient permission"), - 108: _("Timeout"), - 109: _("Find failed, file not found"), - 110: _("Find success, returned all files"), - 111: _("Find success, returned part of files"), - 112: _("User already exists"), - 113: _("User does not exist"), - 114: _("User group already exists"), - 115: _("User group does not exist"), - 116: _("Reserved"), - 117: _("Message is malformed"), - 118: _("No PTZ protocol is set"), - 119: _("No query to file"), - 120: _("Configured to be enabled"), - 121: _("Digital channel is not enabled"), - 150: _("Success, camera restart required"), - 202: _("User is not logged in"), - 203: _("Incorrect password"), - 204: _("User is illegal"), - 205: _("User is locked"), - 206: _("User is in the blacklist"), - 207: _("User already logged in"), - 208: _("Invalid input"), - 209: _("User already exists"), - 210: _("Object not found"), - 211: _("Object does not exist"), - 212: _("Account in use"), - 213: _("Permission table error"), - 214: _("Illegal password"), - 215: _("Password does not match"), - 216: _("Keep account number"), - 502: _("Illegal command"), - 503: _("Talk channel has ben opened"), - 504: _("Talk channel is not open"), - 511: _("Update started"), - 512: _("Update did not start"), - 513: _("Update data error"), - 514: _("Update failed"), - 515: _("Update succeeded"), - 521: _("Failed to restore default config"), - 522: _("Camera restart required"), - 523: _("Default config is illegal"), - 602: _("Application restart required"), - 603: _("System restart required"), - 604: _("Write file error"), - 605: _("Features are not supported"), - 606: _("Verification failed"), - 607: _("Configuration does not exist"), - 608: _("Configuration parsing error"), + 100: "Success", + 101: "Unknown error", + 102: "Version not supported", + 103: "Illegal request", + 104: "User has already logged in", + 105: "User is not logged in", + 106: "Username or Password is incorrect", + 107: "Insufficient permission", + 108: "Timeout", + 109: "Find failed, file not found", + 110: "Find success, returned all files", + 111: "Find success, returned part of files", + 112: "User already exists", + 113: "User does not exist", + 114: "User group already exists", + 115: "User group does not exist", + 116: "Reserved", + 117: "Message is malformed", + 118: "No PTZ protocol is set", + 119: "No query to file", + 120: "Configured to be enabled", + 121: "Digital channel is not enabled", + 150: "Success, camera restart required", + 202: "User is not logged in", + 203: "Incorrect password", + 204: "User is illegal", + 205: "User is locked", + 206: "User is in the blacklist", + 207: "User already logged in", + 208: "Invalid input", + 209: "User already exists", + 210: "Object not found", + 211: "Object does not exist", + 212: "Account in use", + 213: "Permission table error", + 214: "Illegal password", + 215: "Password does not match", + 216: "Keep account number", + 502: "Illegal command", + 503: "Talk channel has ben opened", + 504: "Talk channel is not open", + 511: "Update started", + 512: "Update did not start", + 513: "Update data error", + 514: "Update failed", + 515: "Update succeeded", + 521: "Failed to restore default config", + 522: "Camera restart required", + 523: "Default config is illegal", + 602: "Application restart required", + 603: "System restart required", + 604: "Write file error", + 605: "Features are not supported", + 606: "Verification failed", + 607: "Configuration does not exist", + 608: "Configuration parsing error", } -""" + def tolog(s): print(s) @@ -211,30 +203,40 @@ def GetAllAddr(): if "inet " in x and "127.0." not in x ] - -def SearchXM(devices): - # pick the first wired interface +def GetInterfaces(): + # pick the first wired interface det_intfs = list(zip(*if_nameindex()))[1] + det_intfs = list(det_intfs) + det_intfs.remove('lo') print("detected network interfaces:", det_intfs) - intfsf = list(filter(lambda i: i in intfs, det_intfs)) + return det_intfs + + +def SearchXM(devices): + + #intfsf = list(filter(lambda i: i[:3] in intfs, det_intfs)) #print("prefferd interfaces:", intfsf) - intf = intfsf[0] + #intf = intfs[0] server = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) - + intf = app.intf.get() # hack to use eth0 interface instantly print("Interface:", intf) - print("IP:", get_ip_address(intf)) + try: + ip = get_ip_address(intf) + except: + ip = '' + print("Error during IP estimation, interface up?") + print("IP:", ip) server.bind(('', 34569)) - print("binded") + print("socket bound") server.settimeout(3) server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) server.setsockopt(SOL_SOCKET, SO_BROADCAST, 1) - server.setsockopt(SOL_SOCKET, 25, intf.encode('utf-8') + '\0'.encode('utf-8')) + #server.setsockopt(SOL_SOCKET, 25, intf.encode('utf-8') + '\0'.encode('utf-8')) server.setsockopt(IPPROTO_IP, IP_MULTICAST_TTL, 1) server.sendto( struct.pack("BBHIIHHI", 255, 0, 0, 0, 0, 0, 1530, 0), ("255.255.255.255", 34569) ) - print("sent") while True: data = server.recvfrom(1024) head, ver, typ, session, packet, info, msg, leng = struct.unpack( @@ -327,8 +329,17 @@ def ConfigXM(data): return answer +def FlashXM(cmd): + cam = DVRIPCam(GetIP(devices[cmd[1]]["HostIP"]), "admin", cmd[2]) + if cam.login(): + cmd[4]("Auth success") + cam.upgrade(cmd[3], 0x4000, cmd[4]) + else: + cmd[4]("Auth failed") + + def ProcessCMD(cmd): - global log, logLevel, devices, searchers, configure, flashers + global log, logLevel, devices, searchers, configure if logLevel == 20: tolog(datetime.now().strftime("[%Y-%m-%d %H:%M:%S] >") + " ".join(cmd)) if cmd[0].lower() == "q" or cmd[0].lower() == "quit": @@ -382,17 +393,17 @@ def ProcessCMD(cmd): return logs if cmd[0].lower() == "csv": logs = ( - _("Vendor") + "Vendor" + ";" - + _("MAC Address") + + "MAC Address" + ";" - + _("Name") + + "Name" + ";" - + _("IP Address") + + "IP Address" + ";" - + _("Port") + + "Port" + ";" - + _("SN") + + "SN" + "\n" ) for dev in devices: @@ -411,17 +422,17 @@ def ProcessCMD(cmd): if cmd[0].lower() == "html": logs = ( "\r\n" ) for dev in devices: @@ -463,17 +474,6 @@ def ProcessCMD(cmd): else: return "config [MAC] [IP] [MASK] [GATE] [Pasword]" - if cmd[0].lower() == "flash": - if ( - len(cmd) > 3 - and cmd[1] in devices.key(s) - and devices[cmd[1]]["Brand"] in flashers.keys() - ): - if len(cmd) == 4: - cmd[4] = tolog - return flashers[devices[cmd[1]]["Brand"]](cmd) - else: - return "flash [MAC] [password] [file]" if cmd[0].lower() == "loglevel": if len(cmd) > 1: logLevel = int(cmd[1]) @@ -512,7 +512,7 @@ def __init__(self, root): self.fr.rowconfigure(0, weight=1) self.table = Treeview(self.fr, show="headings", selectmode="browse", height=8) - self.table.grid(column=0, row=0, sticky="nsew") + self.table.grid(column=0, row=0, padx=5, sticky="nsew") self.table["columns"] = ("ID", "vendor", "addr", "port", "name", "mac", "sn") self.table["displaycolumns"] = ("addr", "name", "mac", "sn") @@ -607,6 +607,11 @@ def __init__(self, root): #self.ven.grid(row=0, column=1, padx=5, sticky="w") self.ven["values"] = ["XM",] self.ven.current(0) + self.l8 = Label(self.fr_tools, text="Interface", width=10) + self.intf = Combobox(self.fr_tools, width=10) + self.intf.grid(column=1, padx=5) + self.intf['values'] = GetInterfaces() + self.intf.current(newindex=0) self.search = Button(self.fr_tools, text="Search", command=self.search) self.search.grid(row=0, column=2, pady=5, padx=5, sticky=W + N) self.reset = Button(self.fr_tools, text="Reset", command=self.clear) @@ -710,15 +715,15 @@ def setconfig(self): ), ) else: - showerror("Error"), CODES[result["Ret"]] + showerror("Error", CODES[result["Ret"]]) def export(self): filename = asksaveasfilename( filetypes=( - ("JSON files"), "*.json", - ("HTML files"), "*.html;*.htm", - ("Text files"), "*.csv;*.txt", - ("All files"), "*.*", + ("JSON files", "*.json"), + ("HTML files", "*.html;*.htm"), + ("Text files", "*.csv;*.txt"), + ("All files", "*.*"), ) ) if filename == "": @@ -735,27 +740,6 @@ def export(self): ProcessCMD(["table"]) ProcessCMD(["loglevel", str(10)]) - def flash(self): - self.fl_state.set("Processing...") - filename = askopenfilename( - filetypes=("Flash", "*.bin", "All files", "*.*") - ) - if filename == "": - return - if len(self.table.selection()) == 0: - _mac = "all" - else: - _mac = self.table.item(self.table.selection()[0], option="values")[4] - result = ProcessCMD( - ["flash", _mac, self.passw.get(), filename, self.fl_state.set] - ) - if ( - hasattr(result, "keys") - and "Ret" in result.keys() - and result["Ret"] in CODES.keys() - ): - showerror("Error", CODES[result["Ret"]]) - searchers = { #"wans": SearchWans, @@ -782,6 +766,8 @@ def flash(self): if GUI_TK and "-n" not in sys.argv: root = Tk() app = GUITk(root) + #app.interface.values = GetInterfaces() + #app.interface if ( "--theme" in sys.argv ): # ('winnative', 'clam', 'alt', 'default', 'classic', 'vista', 'xpnative')
" - + _("Vendor") + + "Vendor" + "" - + _("MAC Address") + + "MAC Address" + "" - + _("Name") + + "Name" + "" - + _("IP Address") + + "IP Address" + "" - + _("Port") + + "Port" + "" - + _("SN") + + "SN" + "