Läuft die Voice Acoustic VA-Remotecontrol (AllDSP AllControl) nativ unter Linux auf echtem wxGTK 3.0 — ohne Wine und ohne dekompilierten App-Code. Ausgeführt wird das unveränderte Python-2.7-Bytecode aus dem macOS-.app; C-Extensions (wxGTK/numpy/ scipy/PortAudio) kommen nativ aus Debian stretch. Enthält: va/ (Original-.pyc + pure-Python-Libs + Assets + launch.py mit den drei Linux-Fixes), Dockerfile/run.sh/entrypoint.sh, reference/ (dekompilierter Quellcode zum Debuggen) und README/STATUS. img.cache (378 MB, regenerierbar) ist per .gitignore ausgeschlossen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
742 lines
26 KiB
Python
742 lines
26 KiB
Python
# uncompyle6 version 3.9.3
|
|
# Python bytecode version base 2.6 (62161)
|
|
# Decompiled from: Python 3.9.25 (main, Oct 31 2025, 23:16:49)
|
|
# [GCC 14.2.0]
|
|
# Embedded file name: d_ethernet.pyc
|
|
# Compiled at: 2025-03-06 16:07:19
|
|
import sys
|
|
from socket import *
|
|
import asyncore, asynchat, collections, mytime, threading, copy, struct, types, d_protocol, os.path, traceback, main, one_unit
|
|
from definitions import *
|
|
import d_protocol
|
|
|
|
def getString(str):
|
|
return one_unit.getString(str)
|
|
|
|
|
|
mac_names = 'posix'
|
|
if os.name in mac_names:
|
|
newline = '\n'
|
|
else:
|
|
newline = '\r\n'
|
|
usePolling = True
|
|
|
|
class Ethernet():
|
|
|
|
def __init__(self, parent):
|
|
self.thread1 = threading.Thread(name='AllDSP Server Ethernet Detection Port 50674', target=self.process1)
|
|
self.thread1.daemon = True
|
|
self.thread2 = threading.Thread(name='AllDSP Server Ethernet Detection Port 50774', target=self.process2)
|
|
self.thread2.daemon = True
|
|
if usePolling:
|
|
self.thread3 = threading.Thread(name='AllDSP Server Ethernet Polling', target=self.process3)
|
|
self.thread3.daemon = True
|
|
self.parent = parent
|
|
self.channel = None
|
|
self.conn = UDP_announce_listener(self)
|
|
self.polling_ip = 0
|
|
self.ip_index = 0
|
|
self.printedError = False
|
|
self.myip = None
|
|
self.found = []
|
|
self.foundtime = {}
|
|
one_unit.app.subnet_mask_list = {}
|
|
self.poll_skip_list = {}
|
|
self.pollingTimeout = 0.05
|
|
self.lastIPListCheckTime = 0
|
|
return
|
|
|
|
def add_unit(self, myip, pkt):
|
|
unit = d_protocol.RemoteUnit()
|
|
unit.MAC = pkt.MAC
|
|
unit.IP = myip
|
|
unit.type = pkt.broadcasted_skin
|
|
unit.name = 'No Name'
|
|
unit.pkt = pkt
|
|
unit.link_type = 'Ethernet'
|
|
unit.link_status = 'ready'
|
|
unit.HWVersion = pkt.HWVersion
|
|
unit.PICVersion = pkt.PICVersion
|
|
unit.Serial = pkt.Serial
|
|
unit.DSPState = pkt.DSPState
|
|
unit.ProductionDate = pkt.ProductionDate
|
|
unit.originalSwID = pkt.originalSwID
|
|
self.parent.peers.add(unit)
|
|
return
|
|
|
|
def sendResetLoader(self, s, ip):
|
|
try:
|
|
s.close()
|
|
except:
|
|
pass
|
|
|
|
mytime.sleep(0.1)
|
|
s = socket(AF_INET, SOCK_STREAM)
|
|
s.settimeout(1)
|
|
s.connect((ip, 50675))
|
|
cmd = chr(0) + chr(7) + chr(0) + chr(0)
|
|
nul = '0' * 512
|
|
cmd += nul
|
|
try:
|
|
s.send(cmd)
|
|
print mytime.displayTime() + ' d_e.srl.Loader Reset 1 Sent to', ip
|
|
try:
|
|
pkt = s.recv(1024)
|
|
print mytime.displayTime() + ' d_e.srl.Got reply from', ip, pkt
|
|
except:
|
|
print mytime.displayTime() + ' d_e.srl.No reply from', ip
|
|
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
s.close()
|
|
mytime.sleep(0.1)
|
|
s = socket(AF_INET, SOCK_STREAM)
|
|
s.settimeout(1)
|
|
s.connect((ip, 50675))
|
|
cmd = chr(0) + 'Q'
|
|
nul = '0' * 512
|
|
cmd += nul
|
|
try:
|
|
s.send(cmd)
|
|
print mytime.displayTime() + ' d_e.srl.Loader Reset 2 Sent to', ip
|
|
try:
|
|
pkt = s.recv(1024)
|
|
print mytime.displayTime() + ' d_e.srl.Got reply from', ip, pkt
|
|
except:
|
|
print mytime.displayTime() + ' d_e.srl.No reply from', ip
|
|
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
s.close()
|
|
mytime.sleep(0.1)
|
|
s = socket(AF_INET, SOCK_STREAM)
|
|
s.settimeout(1)
|
|
s.connect((ip, 50675))
|
|
cmd = 'DDReset_Interface'
|
|
try:
|
|
s.send(cmd)
|
|
print mytime.displayTime() + ' d_e.srl.Loader Reset 3 Sent to', ip
|
|
try:
|
|
pkt = s.recv(1024)
|
|
print mytime.displayTime() + ' d_e.srl.Got reply from', ip, pkt
|
|
except:
|
|
print mytime.displayTime() + ' d_e.srl.No reply from', ip
|
|
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
s.close()
|
|
mytime.sleep(0.1)
|
|
s = socket(AF_INET, SOCK_STREAM)
|
|
s.settimeout(1)
|
|
s.connect((ip, 50675))
|
|
cmd = 'DDUPLOADFIRMWARE'
|
|
try:
|
|
s.send(cmd)
|
|
print mytime.displayTime() + ' d_e.srl.Loader Reset 4 Sent to', ip
|
|
try:
|
|
pkt = s.recv(1024)
|
|
print mytime.displayTime() + ' d_e.srl.Got reply from', ip, pkt
|
|
except:
|
|
print mytime.displayTime() + ' d_e.srl.No reply from', ip
|
|
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
s.close()
|
|
mytime.sleep(0.1)
|
|
s = socket(AF_INET, SOCK_STREAM)
|
|
s.settimeout(1)
|
|
s.connect((ip, 50675))
|
|
cmd = 'DCRESARTFIRMWARE'
|
|
try:
|
|
s.send(cmd)
|
|
print mytime.displayTime() + ' d_e.srl.Loader Reset 5 Sent to', ip
|
|
try:
|
|
pkt = s.recv(1024)
|
|
print mytime.displayTime() + ' d_e.srl.Got reply from', ip, pkt
|
|
except:
|
|
print mytime.displayTime() + ' d_e.srl.No reply from', ip
|
|
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
s.close()
|
|
return
|
|
|
|
def pollIP(self, ip_to_poll):
|
|
try:
|
|
s = socket(AF_INET, SOCK_STREAM)
|
|
s.settimeout(self.pollingTimeout)
|
|
s.connect((ip_to_poll, 50675))
|
|
s.settimeout(self.pollingTimeout)
|
|
try:
|
|
s.settimeout(1)
|
|
cmd = '4DPP' + chr(253) + chr(0) + chr(255) + chr(0)
|
|
cs = d_protocol.Checksum()
|
|
cs.add(cmd)
|
|
cmd += cs.get()
|
|
s.send(cmd)
|
|
try:
|
|
pkt = s.recv(1024)
|
|
except:
|
|
pkt = None
|
|
try:
|
|
self.sendResetLoader(s, ip_to_poll)
|
|
except:
|
|
pass
|
|
|
|
s.close()
|
|
return
|
|
else:
|
|
if pkt != None and len(pkt) > 3:
|
|
if pkt[:3] != 'DDB':
|
|
try:
|
|
pkt = s.recv(1024)
|
|
print mytime.displayTime(), 'd_e.pi.Got another packet'
|
|
mytime.sleep(0.01)
|
|
except:
|
|
pkt = None
|
|
|
|
s.close()
|
|
if pkt != None:
|
|
string = ''
|
|
for c in pkt:
|
|
string += ':' + hex(ord(c))
|
|
|
|
parsedPkt = parse_announce(pkt)
|
|
if isinstance(parsedPkt, Announcement):
|
|
if one_unit.app.runConnectionTest == True:
|
|
one_unit.app.connectionTestLog.write(mytime.displayTime() + ' Received solicited announcement, MAC: ' + parsedPkt.MAC + ', IP: ' + ip_to_poll + newline)
|
|
if parsedPkt.MAC not in one_unit.app.server.peers.ignore_list:
|
|
self.add_unit(ip_to_poll, parsedPkt)
|
|
self.found.append(ip_to_poll)
|
|
return True
|
|
self.foundtime[ip_to_poll] = mytime.clock()
|
|
else:
|
|
self.poll_skip_list[ip_to_poll] = mytime.clock()
|
|
s = socket(AF_INET, SOCK_STREAM)
|
|
s.settimeout(1)
|
|
s.connect((ip_to_poll, 50675))
|
|
s.settimeout(1)
|
|
tmpcounter = 20
|
|
while tmpcounter > 0:
|
|
tmpcounter -= 1
|
|
try:
|
|
cmd = 'DDCOPY__FIRMWARE'
|
|
s.send(cmd)
|
|
mytime.sleep(0.1)
|
|
cmd = 'DQ'
|
|
s.send(cmd)
|
|
mytime.sleep(0.1)
|
|
except:
|
|
break
|
|
|
|
s.close()
|
|
else:
|
|
s.close()
|
|
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
except:
|
|
s.close()
|
|
|
|
return False
|
|
|
|
def getMyIPList(self):
|
|
self.lastIPListCheckTime = mytime.clock()
|
|
hostName = 'Start'
|
|
hostByName = 'Start'
|
|
try:
|
|
snm_list = {}
|
|
hostName = gethostname()
|
|
hostByName = gethostbyname_ex(hostName)
|
|
ip_list = [_[1] for ip in hostByName][2]
|
|
try:
|
|
one_unit.check_interfaces()
|
|
for adapter in one_unit.app.LAN_adapters.values():
|
|
if adapter.IPv4 is not None and adapter.IPv4 not in ip_list:
|
|
ip_list.append(adapter.IPv4)
|
|
if adapter.subnet_mask is not None:
|
|
snm_list[adapter.IPv4] = adapter.subnet_mask
|
|
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
if len(ip_list) == 0:
|
|
return []
|
|
if one_unit.app.my_ip_list != ip_list:
|
|
print mytime.displayTime() + ' My IP list changed from', one_unit.app.my_ip_list, 'to', ip_list
|
|
self.pollingTimeout = 0.01
|
|
one_unit.app.my_ip_list = ip_list
|
|
one_unit.app.subnet_mask_list = snm_list
|
|
one_unit.app.my_ip_list = ip_list
|
|
return
|
|
except:
|
|
if self.printedError == False:
|
|
print mytime.displayTime(), 'hostName:', hostName
|
|
print mytime.displayTime(), 'de.Could not make IP list, hostName:', hostName, 'error:'
|
|
traceback.print_exc(file=sys.stdout)
|
|
self.printedError = True
|
|
return
|
|
|
|
return
|
|
|
|
def ipToInt(self, ip):
|
|
try:
|
|
if ip.startswith('0x'):
|
|
return int(ip.replace('0x', ''), 16)
|
|
ip = ip.split('.')
|
|
res = int(ip[0]) << 24
|
|
res += int(ip[1]) << 16
|
|
res += int(ip[2]) << 8
|
|
if ip[3].find('(') > 0:
|
|
res += int(ip[3][:ip[3].find('(')]) << 0
|
|
else:
|
|
res += int(ip[3]) << 0
|
|
except:
|
|
print 'de.could not convert', ip[3], 'to int'
|
|
traceback.print_exc(file=sys.stdout)
|
|
res = 0
|
|
|
|
return res
|
|
|
|
def poll(self):
|
|
if self.myip == None:
|
|
self.getMyIPList()
|
|
if self.ip_index >= len(one_unit.app.my_ip_list):
|
|
self.ip_index = 0
|
|
if len(one_unit.app.my_ip_list) == 0:
|
|
mytime.sleep(0.1)
|
|
self.myip = None
|
|
else:
|
|
self.myip = one_unit.app.my_ip_list[self.ip_index].split('.')
|
|
return
|
|
else:
|
|
found = True
|
|
while found == True and one_unit.app.application_stopping == False:
|
|
found = False
|
|
if self.polling_ip > 255:
|
|
self.ip_index += 1
|
|
try:
|
|
if one_unit.app.my_ip_list[self.ip_index].find('169.254') >= 0 and len(one_unit.app.my_ip_list) > 1:
|
|
self.ip_index += 1
|
|
except:
|
|
pass
|
|
|
|
self.polling_ip = 0
|
|
self.getMyIPList()
|
|
if self.ip_index >= len(one_unit.app.my_ip_list):
|
|
self.ip_index = 0
|
|
if self.pollingTimeout >= 0.4 and len(one_unit.app.my_ip_list) > 0:
|
|
self.pollingTimeout = 0.05
|
|
if self.pollingTimeout < 0.5 and len(one_unit.app.my_ip_list) > 0:
|
|
self.pollingTimeout *= 2
|
|
if self.pollingTimeout > 0.4:
|
|
self.pollingTimeout = 0.4
|
|
if len(one_unit.app.my_ip_list) == 0:
|
|
mytime.sleep(0.1)
|
|
self.myip = None
|
|
else:
|
|
self.myip = one_unit.app.my_ip_list[self.ip_index].split('.')
|
|
if mytime.clock() - self.lastIPListCheckTime > 10:
|
|
self.getMyIPList()
|
|
if self.ip_index >= len(one_unit.app.my_ip_list):
|
|
self.ip_index = 0
|
|
if len(one_unit.app.my_ip_list) == 0:
|
|
mytime.sleep(0.1)
|
|
self.myip = None
|
|
else:
|
|
self.myip = one_unit.app.my_ip_list[self.ip_index].split('.')
|
|
if self.myip == None:
|
|
return
|
|
ip_to_poll = self.myip[0] + '.' + self.myip[1] + '.' + self.myip[2] + '.' + str(self.polling_ip)
|
|
self.polling_ip += 1
|
|
if ip_to_poll in self.poll_skip_list.keys():
|
|
if self.poll_skip_list[ip_to_poll] - mytime.clock() > 60:
|
|
found = True
|
|
continue
|
|
if ip_to_poll in self.foundtime.keys():
|
|
if mytime.clock() - self.foundtime[ip_to_poll] < 120:
|
|
found = True
|
|
continue
|
|
for testunit in self.parent.peers.units.values():
|
|
if testunit.IP == ip_to_poll and testunit.link_status != 'disconnected':
|
|
found = True
|
|
break
|
|
|
|
self.pollIP(ip_to_poll)
|
|
return
|
|
|
|
def process1(self):
|
|
try:
|
|
s_50674 = socket(AF_INET, SOCK_DGRAM)
|
|
s_50674.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
|
|
s_50674.bind(('0.0.0.0', 50674))
|
|
s_50674.settimeout(0.1)
|
|
self.Connected = False
|
|
self.socket_ok = True
|
|
except:
|
|
print mytime.displayTime() + ' de.Ethernet Server Failed'
|
|
traceback.print_exc(file=sys.stdout)
|
|
self.socket_ok = False
|
|
|
|
mytime.sleep(1)
|
|
if self.socket_ok == True:
|
|
print mytime.displayTime(), 'de.Ethernet Server Listening for incoming connections on port 50674'
|
|
while one_unit.app.application_stopping == False:
|
|
pkt = None
|
|
try:
|
|
(pkt, addr) = s_50674.recvfrom(1024)
|
|
if one_unit.app.runConnectionTest == True:
|
|
print mytime.displayTime(), 'Ethernet Server: got packet from 50674', addr, len(pkt)
|
|
except timeout:
|
|
pass
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
if pkt == None:
|
|
continue
|
|
subnetMatch = False
|
|
for ip in one_unit.app.my_ip_list:
|
|
if ip in one_unit.app.subnet_mask_list:
|
|
if self.ipToInt(ip) & self.ipToInt(one_unit.app.subnet_mask_list[ip]) == self.ipToInt(addr[0]) & self.ipToInt(one_unit.app.subnet_mask_list[ip]):
|
|
subnetMatch = True
|
|
elif addr[0][:addr[0].find('.')] == ip[:ip.find('.')]:
|
|
subnetMatch = True
|
|
|
|
if subnetMatch == False:
|
|
self.getMyIPList()
|
|
self.conn.handle_read(pkt, addr)
|
|
|
|
s_50674.close()
|
|
mytime.sleep(0.1)
|
|
print mytime.displayTime() + ' UDP Announce socket closed'
|
|
else:
|
|
print mytime.displayTime() + ' Ethernet Server Failed (Socket OK = False)'
|
|
return
|
|
|
|
def process2(self):
|
|
try:
|
|
s_50774 = socket(AF_INET, SOCK_DGRAM)
|
|
s_50774.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
|
|
s_50774.bind(('0.0.0.0', 50774))
|
|
s_50774.settimeout(0.1)
|
|
self.Connected = False
|
|
self.socket_ok = True
|
|
except:
|
|
print mytime.displayTime() + ' de.Ethernet Server Failed'
|
|
traceback.print_exc(file=sys.stdout)
|
|
self.socket_ok = False
|
|
|
|
mytime.sleep(1)
|
|
if self.socket_ok == True:
|
|
print mytime.displayTime(), 'de.Ethernet Server Listening for incoming connections on port 50774'
|
|
while one_unit.app.application_stopping == False:
|
|
pkt = None
|
|
try:
|
|
(pkt, addr) = s_50774.recvfrom(1024)
|
|
if one_unit.app.runConnectionTest == True:
|
|
print mytime.displayTime(), 'Ethernet Server: got packet from 50774 #######################################', addr, len(pkt)
|
|
except timeout:
|
|
pass
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
if pkt == None:
|
|
continue
|
|
subnetMatch = False
|
|
for ip in one_unit.app.my_ip_list:
|
|
if ip in one_unit.app.subnet_mask_list:
|
|
if self.ipToInt(ip) & self.ipToInt(one_unit.app.subnet_mask_list[ip]) == self.ipToInt(addr[0]) & self.ipToInt(one_unit.app.subnet_mask_list[ip]):
|
|
subnetMatch = True
|
|
elif addr[0][:addr[0].find('.')] == ip[:ip.find('.')]:
|
|
subnetMatch = True
|
|
|
|
if subnetMatch == False:
|
|
self.getMyIPList()
|
|
self.conn.handle_read(pkt, addr)
|
|
|
|
s_50774.close()
|
|
mytime.sleep(0.1)
|
|
print mytime.displayTime() + ' UDP Announce socket closed'
|
|
else:
|
|
print mytime.displayTime() + ' Ethernet Server Failed (Socket OK = False)'
|
|
return
|
|
|
|
def process3(self):
|
|
one_unit.lowPriority()
|
|
self.pollingTimeout = 0.5
|
|
loop = 30
|
|
while loop > 0 and one_unit.app.application_stopping == False:
|
|
try:
|
|
for mac in one_unit.app.knownIP:
|
|
if one_unit.app.application_stopping == True:
|
|
break
|
|
ip = one_unit.app.knownIP[mac]['IP']
|
|
if ip.lower().find('offline') >= 0:
|
|
continue
|
|
self.pollIP(ip)
|
|
|
|
break
|
|
except:
|
|
if loop < 5:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
mytime.sleep(0.1)
|
|
loop -= 1
|
|
|
|
self.pollingTimeout = 0.05
|
|
while one_unit.app.application_stopping == False:
|
|
try:
|
|
self.poll()
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
|
|
print mytime.displayTime() + ' TCP Polling Server closed'
|
|
return
|
|
|
|
def start(self):
|
|
"""Start the updating thread"""
|
|
self.stopping = False
|
|
self.thread1.start()
|
|
self.thread2.start()
|
|
if usePolling:
|
|
self.thread3.start()
|
|
return
|
|
|
|
|
|
class UDP_announce_listener():
|
|
"""Handle announcements from hardware units that they broadcast
|
|
over UDP. Can be used to discover new hardware units in the local
|
|
network.
|
|
"""
|
|
|
|
def __init__(self, parent):
|
|
self.Connected = False
|
|
self.ResetValues = False
|
|
self.last_peq_key = None
|
|
self.last_xover_key = None
|
|
self.values = {}
|
|
self.last_requested = -1
|
|
self.parent = parent
|
|
self.lock = threading.Lock()
|
|
self.stopping = False
|
|
self.broadcasted_skin = ''
|
|
self.last_hw_packet_id = 0
|
|
self.invalid_packet_counter = 0
|
|
self.DisconnectTime = mytime.clock()
|
|
self.ignoreList = []
|
|
return
|
|
|
|
def verifyIP(self, IP):
|
|
try:
|
|
s = socket(AF_INET, SOCK_STREAM)
|
|
s.settimeout(3)
|
|
s.connect((IP, 50675))
|
|
s.close()
|
|
return True
|
|
except:
|
|
s.close()
|
|
return False
|
|
|
|
return
|
|
|
|
def handle_read(self, pkt, addr):
|
|
pkt = parse_packet(pkt)
|
|
if isinstance(pkt, Announcement):
|
|
if one_unit.app.runConnectionTest == True:
|
|
txt = mytime.displayTime() + ' Received unsolicited announcement, MAC: ' + pkt.MAC + ', IP: ' + addr[0] + newline
|
|
one_unit.app.connectionTestLog.write(txt)
|
|
print txt
|
|
if pkt.MAC in self.parent.parent.peers.units and self.parent.parent.peers.units[pkt.MAC].IP == addr[0] and self.parent.parent.peers.units[pkt.MAC].link_status in ('available',
|
|
'ready'):
|
|
if one_unit.app.runConnectionTest == True:
|
|
print mytime.displayTime() + ' d_e.hr.Ignoring connected unit', pkt.MAC, addr[0], self.parent.parent.peers.units[pkt.MAC].link_status
|
|
return
|
|
if pkt.MAC in one_unit.app.server.peers.ignore_list:
|
|
if one_unit.app.runConnectionTest == True:
|
|
print mytime.displayTime() + ' d_e.hr.Ignoring known ignored unit', pkt.MAC, addr[0]
|
|
return
|
|
unit = d_protocol.RemoteUnit()
|
|
unit.MK2 = pkt.MK2
|
|
unit.MAC = pkt.MAC
|
|
unit.IP = addr[0]
|
|
unit.type = pkt.broadcasted_skin
|
|
unit.name = 'No Name'
|
|
unit.pkt = pkt
|
|
unit.link_type = 'Ethernet'
|
|
try:
|
|
if True:
|
|
if one_unit.app.runConnectionTest == True:
|
|
print 'd_e.hr.2'
|
|
unit.link_status = 'ready'
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
else:
|
|
unit.HWVersion = pkt.HWVersion
|
|
unit.PICVersion = pkt.PICVersion
|
|
unit.Serial = pkt.Serial
|
|
unit.DSPState = pkt.DSPState
|
|
unit.ProductionDate = pkt.ProductionDate
|
|
unit.originalSwID = pkt.originalSwID
|
|
self.parent.parent.peers.add(unit)
|
|
return
|
|
|
|
|
|
class Announcement():
|
|
"""The announcement broadcast by hardware units over USB"""
|
|
|
|
def __init__(self):
|
|
"""Constructor"""
|
|
self.UnitType2 = None
|
|
self.UnitType1 = None
|
|
self.MAC = None
|
|
self.PC_PacketId = None
|
|
self.HW_PacketId = None
|
|
self.skin_high = None
|
|
self.skin_mid = None
|
|
self.originalSwID = ''
|
|
self.skin_low = None
|
|
self.broadcasted_skin = None
|
|
self.HWVersion = None
|
|
self.PICVersion = None
|
|
self.Serial = None
|
|
self.ProductionDate = None
|
|
self.DSPState = None
|
|
self.MK2 = False
|
|
return
|
|
|
|
def __str__(self):
|
|
return 'Announcement(%s, Type1=%s, Type2=%s)' % (self.MAC, self.UnitType1, self.UnitType2)
|
|
|
|
|
|
def parse_announce(data):
|
|
"""Parse the data sent by MakeConfigData(void) in DDEthernet.c,
|
|
line 537. This data can be found in UDP broadcasts and in TCP
|
|
responces to the 'J' command from the user.
|
|
"""
|
|
if len(data) < 42 or data[41] != 'Q':
|
|
return None
|
|
else:
|
|
if data[:3] != 'DDB':
|
|
return None
|
|
res = Announcement()
|
|
if data[36:42] == '67890Q':
|
|
res.MK2 = True
|
|
else:
|
|
res.MK2 = False
|
|
res.UnitType2 = ord(data[4])
|
|
res.UnitType1 = ord(data[5])
|
|
res.MAC = data[5:22]
|
|
res.PC_PacketID = ord(data[39])
|
|
res.HW_PacketID = ord(data[40])
|
|
res.skin_high = unicode(ord(data[33]))
|
|
res.skin_mid = unicode(ord(data[34]))
|
|
res.skin_low = unicode(ord(data[35]))
|
|
res.broadcasted_skin = res.skin_high + '_' + res.skin_mid + '_' + res.skin_low
|
|
skinBeforeReplacement = ':' + res.skin_high + '.' + res.skin_mid + '.' + res.skin_low
|
|
try:
|
|
res.broadcasted_skin = one_unit.app.type_replacements[res.broadcasted_skin]
|
|
except:
|
|
pass
|
|
|
|
try:
|
|
high = unicode(ord(data[22]))
|
|
mid = unicode(ord(data[23]))
|
|
low = unicode(ord(data[24]))
|
|
res.HWVersion = high + '.' + mid + '.' + low
|
|
high = unicode(ord(data[25]))
|
|
mid = unicode(ord(data[26]))
|
|
low = unicode(ord(data[27]))
|
|
res.PICVersion = high + '.' + mid + '.' + low
|
|
high = int(ord(data[28]))
|
|
mid = int(ord(data[29]))
|
|
low = int(ord(data[30]))
|
|
res.Serial = high * 65536 + mid * 256 + low
|
|
high = unicode(ord(data[36]))
|
|
mid = unicode(ord(data[37]))
|
|
low = unicode(ord(data[38]))
|
|
res.originalSwID = high + '.' + mid + '.' + low + skinBeforeReplacement
|
|
res.ProductionDate = '01-01-71'
|
|
except:
|
|
pass
|
|
|
|
res.DSPState = ord(data[37])
|
|
return res
|
|
|
|
|
|
def parse_packet(pkt):
|
|
buf = ''
|
|
while True:
|
|
chunk = pkt
|
|
if len(chunk) == 0:
|
|
return
|
|
buf += chunk
|
|
pos = buf.find('DD')
|
|
if pos < 0:
|
|
buf = ''
|
|
return
|
|
buf = buf[pos:]
|
|
if buf[41] != 'Q':
|
|
print mytime.displayTime() + ' Q not found'
|
|
buf = ''
|
|
return
|
|
while len(buf) < 42:
|
|
chunk = ser.read(42 - len(buf))
|
|
buf += chunk
|
|
|
|
pkt = None
|
|
if buf[:3] == 'DDB':
|
|
pkt = parse_announce(buf)
|
|
else:
|
|
print mytime.displayTime() + " Unknown pkt '%s'" % buf[:3]
|
|
return
|
|
buf = buf[42:]
|
|
return pkt
|
|
|
|
return
|
|
|
|
|
|
def makeMask(n):
|
|
"""return a mask of n bits as a long integer"""
|
|
return (2L << n - 1) - 1
|
|
|
|
|
|
def dottedQuadToNum(ip):
|
|
"""convert decimal dotted quad string to long integer"""
|
|
try:
|
|
inetaton = inet_aton(ip)
|
|
return struct.unpack('<L', inetaton)[0]
|
|
except:
|
|
traceback.print_exc(file=sys.stdout)
|
|
return 0
|
|
|
|
return
|
|
|
|
|
|
def networkMask(ip, bits):
|
|
"""Convert a network address to a long integer"""
|
|
return dottedQuadToNum(ip) & makeMask(bits)
|
|
|
|
|
|
def addressInNetwork(ip1, ip2, net):
|
|
if ip1.startswith('USB') or ip1.startswith('Startup'):
|
|
return True
|
|
try:
|
|
net = networkMask(net, 32)
|
|
ip1 = struct.unpack('<L', inet_aton(ip1))[0]
|
|
ip2 = struct.unpack('<L', inet_aton(ip2))[0]
|
|
return ip1 & net == ip2 & net
|
|
except:
|
|
print mytime.displayTime(), 'd_e.addressInNetwork failed', ip1, ip2, net
|
|
|
|
return
|
|
|
|
|
|
|
|
# okay decompiling pycode/d_ethernet.pyc
|