Files
VA-Control-for-linux/reference/decompiled/server.py
T
maikandClaude Opus 4.8 a7c93fa266 Erster Commit: nativer Linux-Port aus macOS-Bytecode
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>
2026-08-20 19:57:01 +02:00

1333 lines
55 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: server.pyc
# Compiled at: 2024-11-13 12:27:47
import mytime, d_protocol, socket, collections, threading, copy, struct, types, sys, os.path, traceback, wx, codecs, string, d_ethernet, d_usb, d_bootloader, d_keepalive, one_unit, main, protocol, data_model, future
from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EBADF, ECONNABORTED, EPIPE, errorcode
errorlist = (
EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET,
ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EBADF, ECONNABORTED, EPIPE)
mac_names = 'posix'
if os.name in mac_names:
newline = '\n'
else:
newline = '\r\n'
Key = collections.namedtuple('Key', 'struct_id, member_id, channel, num')
help_text = newline + 'Commands: ' + newline + 'telnet: Enter telnet mode.' + newline + 'list: List available units.' + newline + 'quit: Close the software.' + newline + 'get: Read variale value from unit.' + newline + 'set: Set variable value to unit.' + newline + newline + 'Syntax:' + newline + 'get [MAC]/[Structure ID]/[Member ID]/[Channel]/[index]' + newline + 'Example: get AB:CD:EF:12:34:56/0/0/0/0' + newline + 'set [MAC]/[Structure ID]/[Member ID]/[Channel]/[index]=[value]' + newline + 'Example: set AB:CD:EF:12:34:56/0/0/0/0=-13.47'
password_text = newline + 'Attention: You need to be logged in with the factory password to be able to read or set values. Log in by setting 13/29/0/0=[password].' + newline + newline
class RemoteUnits():
def __init__(self, parent):
self.units = {}
self.clients = {}
self.parent = parent
self.lock = threading.Lock()
self.ignore_list = []
self.onlineUnits = 0
return
def add(self, unit):
if not unit:
return
else:
if unit == None:
return
if unit.type not in one_unit.app.supported_unit_ids and unit.type not in one_unit.app.short_unit_ids and one_unit.app.testpc == False and one_unit.app.supportAnyUnit == False:
if unit.MAC not in self.ignore_list:
self.ignore_list.append(unit.MAC)
if unit.type.startswith('1_1') == True:
one_unit.app.ignoredUnits[unit.MAC] = unit
print mytime.displayTime() + ' s.a.Ignoring unit: ', unit.MAC, unit.type, unit.IP
return
if unit.MAC not in self.units:
self.units[unit.MAC] = unit
self.units[unit.MAC].discover_time = mytime.clock()
if unit.pkt != None:
self.onlineUnits += 1
else:
self.units[unit.MAC].IP = unit.IP
if self.units[unit.MAC].link_status != 'available':
self.units[unit.MAC].link_status = unit.link_status
self.units[unit.MAC].type = unit.type
self.units[unit.MAC].pkt = unit.pkt
self.units[unit.MAC].link_type = unit.link_type
self.units[unit.MAC].DSPState = unit.DSPState
self.units[unit.MAC].Serial = unit.Serial
self.units[unit.MAC].HWVersion = unit.HWVersion
self.units[unit.MAC].PICVersion = unit.PICVersion
self.units[unit.MAC].ProductionDate = unit.ProductionDate
self.units[unit.MAC].originalSwID = unit.originalSwID
return
def print_units(self):
if len(self.units) == 0:
print mytime.displayTime() + ' None'
for MAC in self.units:
print mytime.displayTime(), self.units[MAC].MAC, self.units[MAC].IP, self.units[MAC].type, self.units[MAC].name
return
def delete(self, MAC):
if MAC in self.units:
del self.units[MAC]
return
def set_unit_name(self, MAC, val):
self.units[MAC].name = val
return
def clear_preset_names(self, MAC):
self.units[MAC].preset_names = {}
return
def set_by_key(self, MAC, key, val):
try:
if key.struct_id >= 0 and self.units[MAC].values[key] == val:
return
except:
pass
try:
self.units[MAC].values[key] = val
for client in self.clients[MAC].values():
client.set_direct(key, val)
return
except:
pass
self.units[MAC].values[key] = val
self.parent.local_listener.priority_level[key] = mytime.clock() + 2
return
def get(self, key, MAC):
try:
return self.units[MAC].values[key]
except:
return
return
class UnitData():
def __init__(self):
self.vu = {}
self.gr = {}
return
unit_data = UnitData()
class Daemon():
def __init__(self):
self.thread = threading.Thread(name='AllDSP Client Monitor', target=self.process)
self.thread.daemon = True
self.last_loopback = None
self.start()
self.last_maclist = []
self.last_threads = []
self.last_processlist = []
return
def start(self):
self.thread.start()
return
def process(self):
self.peers = RemoteUnits(self)
self.local_listener = TCP_Listener(self)
while one_unit.app.init_finished == False:
mytime.sleep(0.01)
self.ethernet_listener = d_ethernet.Ethernet(self)
self.bootloader_listener = d_bootloader.Bootloader(self)
self.usb_listener = d_usb.USB_updater(self)
self.ethernet_listener.start()
self.bootloader_listener.start()
self.usb_listener.start()
last_displaylist = {}
while one_unit.app.application_stopping == False:
mytime.sleep(0.1)
active_threads = threading.enumerate()
MAClist = [_[1] for MAC in self.peers.units.keys()]
for MAC in MAClist:
if MAC.startswith('DEMO') == True:
continue
found = False
for thread in active_threads:
if thread.name.strip() == MAC.strip():
found = True
break
if found == False and self.peers.units[MAC].process != None:
self.peers.units[MAC].process = None
print mytime.displayTime() + ' s.Process reset'
if found == False and self.peers.units[MAC].IP[:3] != 'DEM' and (self.peers.units[MAC].link_status == 'available' or self.peers.units[MAC].link_status == 'ready'):
self.peers.units[MAC].process = d_protocol.Remote_Link(self, MAC)
print mytime.displayTime() + ' s.p.started thread ' + MAC, self.peers.units[MAC].link_status
mytime.sleep(0.1)
self.local_listener.Close()
mytime.sleep(0.1)
threadlist = threading.enumerate()
exit_counter = 0
while exit_counter < 1000:
threadlist = threading.enumerate()
exit_counter += 1
continue_loop = False
for thread in threadlist:
if thread.name in ('MAC', 'AllDSP Server USB Detection', 'AllDSP Server Ethernet Detection'):
mytime.sleep(0.1)
continue_loop = True
break
if continue_loop == False:
break
for thread in threadlist:
if thread.name in ('MAC', 'AllDSP Server USB Detection', 'AllDSP Server Ethernet Detection'):
print mytime.displayTime() + ' Not all server threads quit in time, exiting anyway.'
else:
print mytime.displayTime() + ' All server threads exited normally'
print mytime.displayTime() + ' Server terminated'
return
class TCP_Listener():
"""Listen to TCP connections from a user, e.g., a GUI."""
def __init__(self, parent):
self.priority_level = {}
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
self.sock.bind(('0.0.0.0', 50684))
self.sock.listen(1)
except:
traceback.print_exc(file=sys.stdout)
print mytime.displayTime() + ' Local Loopback Server Failed'
self.parent = parent
self.conn = {}
self.index = 0
self.group_membership_list = {}
self.groups = {}
self.thread = threading.Thread(name='AllDSP Local Loopback', target=self.process)
self.thread.daemon = True
self.start()
return
def start(self):
self.thread.start()
return
def process(self):
self.sock.settimeout(1)
while one_unit.app.application_stopping == False:
try:
(new_sock, addr) = self.sock.accept()
self.conn[self.index] = User_command(self, new_sock)
self.conn[self.index].start()
self.index += 1
except:
pass
print mytime.displayTime() + ' Closing Local Loopback'
try:
self.sock.close()
except:
pass
return
def start_direct_link(self, direct):
client = direct.parent
mac = client.MAC
self.conn[self.index] = User_command(self, None, mac, direct)
try:
if mac.startswith('GRP_'):
group = mac[4:]
unit_mac = one_unit.app.groups[group].keys()[0]
if unit_mac not in self.parent.peers.clients:
self.parent.peers.clients[unit_mac] = {}
self.parent.peers.clients[unit_mac][client.launchKey] = direct.parent.model
elif mac not in self.parent.peers.clients:
self.parent.peers.clients[mac] = {}
self.parent.peers.clients[mac][client.launchKey] = direct.parent.model
except:
traceback.print_exc(file=sys.stdout)
self.index += 1
return self.conn[self.index - 1]
def handle_close(self):
try:
self.sock.close()
except:
pass
return
def Close(self):
try:
self.conn[self.index].Close()
except:
pass
try:
self.sock.close()
except:
pass
return
class User_command():
def __init__(self, parent, new_sock, mac=None, direct=None):
if new_sock != None:
self.s = new_sock
self.s.settimeout(12)
self.link_mac = 'Unknown'
self.direct = None
else:
self.s = None
self.link_mac = mac
self.direct = direct
self.ibuffer = ''
self.echo = False
self.telnet = False
self.parent = parent
self.request_MAC_list = {}
self.last_requested = 0
self.group_list = {}
self.make_group_skip_list()
self.printed_conn = False
self.start_time = mytime.clock()
if self.s != None:
self.thread = threading.Thread(name='AllDSP Local Loopback conn ' + str(self.parent.index), target=self.process)
self.thread.daemon = True
return
def start(self):
if self.s != None:
self.thread.start()
return
def process(self):
self.ibuffer = ''
self.s.settimeout(1)
while one_unit.app.application_stopping == False:
try:
data = self.s.recv(1024)
if data != None and len(data) >= 1:
self.collect_incoming_data(data)
else:
print mytime.displayTime() + ' Server connection with ' + self.link_mac + ' disconnected'
break
except socket.timeout:
if self.direct != None:
continue
except:
print mytime.displayTime() + ' Server connection with ' + self.link_mac + ' failed!'
traceback.print_exc(file=sys.stdout)
break
self.s.close()
print mytime.displayTime() + ' Link process ' + self.link_mac + ' exit'
return
def Close(self):
self.close()
return
def push(self, data):
if self.direct == None:
self.s.send(data)
return
else:
self.direct.recv_direct(data)
return
def make_group_skip_list(self):
self.group_skip_list = []
self.group_skip_list.append(Key(protocol.STRUCT_ID_GLOBAL, protocol.MEMBER_ID_SHORT_NAME, 0, 0))
self.group_skip_list.append(Key(protocol.STRUCT_ID_GLOBAL, protocol.MEMBER_ID_IP, 0, 0))
self.group_skip_list.append(Key(protocol.STRUCT_ID_GLOBAL, protocol.MEMBER_ID_SUBNET_MASK, 0, 0))
self.group_skip_list.append(Key(protocol.STRUCT_ID_COMMAND, protocol.MEMBER_ID_COMMAND, 0, protocol.cmdLocate))
self.group_skip_list.append(Key(protocol.STRUCT_ID_GLOBAL, protocol.MEMBER_ID_HARDWARE_STATUS_FLAGS, 0, 0))
return
def collect_incoming_data(self, data):
self.ibuffer += data
if self.echo == True:
self.push(data)
if self.ibuffer.find('\r') < 0 and len(data) < 4:
return
else:
if self.echo == True:
self.push(newline)
if self.ibuffer.startswith('list'):
self.command_list()
elif self.ibuffer.startswith('echo'):
self.echo = True
elif self.ibuffer.startswith('DDL'):
self.command_DDL()
elif self.ibuffer.startswith('vudata'):
self.send_vu_data()
elif self.ibuffer.startswith('presets'):
self.command_presets()
elif self.ibuffer.startswith('update_groups'):
self.update_groups()
elif self.ibuffer.startswith('mute_single_unit'):
self.mute_single_unit()
elif self.ibuffer.startswith('mute_group'):
self.mute_group()
elif self.ibuffer.startswith('make_image'):
self.make_image()
elif self.ibuffer.startswith('update_display'):
self.update_display()
elif self.ibuffer.startswith('power_single_unit'):
self.power_single_unit()
elif self.ibuffer.startswith('power_group'):
self.power_group()
elif self.ibuffer.startswith('locate_unit'):
self.locate_unit()
elif self.ibuffer.startswith('clear_data_buffer'):
self.clear_data_buffer()
elif self.ibuffer.startswith('start_main_update'):
mac = self.ibuffer[18:]
one_unit.app.always_allow_update[mac] = True
one_unit.app.interfaceUpdate[mac] = False
one_unit.app.image_filesize[mac] = '0x1000000'
one_unit.app.image_filename[mac] = None
self.start_main_update()
elif self.ibuffer.startswith('quit'):
one_unit.app.application_stopping = True
one_unit.app.main_frame.Close()
elif self.ibuffer.startswith('enable_bootloader'):
one_unit.app.enable_bootloader = True
elif self.ibuffer.startswith('disable_bootloader'):
one_unit.app.enable_bootloader = False
elif self.ibuffer.startswith('update_progress'):
mac = self.ibuffer[16:]
print mytime.displayTime() + ' Progress for', mac, ':', one_unit.app.bootloader_progress[mac]
self.push(str(one_unit.app.bootloader_progress[mac]))
elif self.ibuffer.startswith('bl_update_progress'):
try:
self.push(str(one_unit.app.bootloader_progress['Bootloader']))
except:
self.push('None')
elif self.ibuffer.startswith('time'):
self.push(str(mytime.clock()))
elif self.ibuffer.startswith('telnet'):
self.telnet = True
elif self.ibuffer.strip() in ('?', 'help', 'HELP', 'Help'):
self.push(help_text)
self.push(password_text)
elif self.ibuffer.startswith('get_info'):
self.sendMyInfo()
elif self.ibuffer[:3] in ('GET', 'get', 'Get'):
self.command_get()
elif self.ibuffer[:3] in ('SET', 'set', 'Set'):
self.command_set()
elif self.ibuffer.strip() == 'testResult':
self.sendTestResult()
else:
self.push(newline + 'Unknown command: ' + self.ibuffer)
if self.telnet == True:
self.push(newline)
self.ibuffer = ''
return
def sendTestResult(self):
self.push('Test result:' + one_unit.app.testResult)
return
def sendMyInfo(self):
self.push(os.getcwd())
return
def mute_group(self):
self.ibuffer = self.ibuffer[10:]
if len(self.ibuffer) < 1:
print mytime.displayTime() + ' server.mute_group: Packet too short'
self.push('error')
return
tlen = ord(self.ibuffer[0])
if len(self.ibuffer) < tlen + 1:
print mytime.displayTime() + ' server.mute_group: Packet too short (2)'
self.push('error')
return
target = self.ibuffer[1:tlen + 1]
mute = ord(self.ibuffer[tlen + 1])
if target == 'all_units':
maclist = [_[1] for k in self.parent.parent.peers.units if self.parent.parent.peers.units[k].link_status == 'available']
else:
maclist = one_unit.getMacList(target)
if len(maclist) == 0:
print mytime.displayTime() + ' Unknown Group', target, maclist
return
if mute == 0:
print mytime.displayTime(), 's.mg.Unmuting', len(maclist), 'units'
else:
print mytime.displayTime(), 's.mg.Muting', len(maclist), 'units'
i = 0
for mac in maclist:
try:
self.parent.parent.peers.units[mac].process.TempMute(mute)
i += 1
except:
print mytime.displayTime(), i, 's.mg.Exception for unit', mac
return
def mute_single_unit(self):
self.ibuffer = self.ibuffer[16:]
if len(self.ibuffer) < 18:
print mytime.displayTime() + ' server.mute_single_unit: Packet too short'
self.push('error')
return
target = self.ibuffer[1:len(self.ibuffer) - 1]
mute = ord(self.ibuffer[len(self.ibuffer) - 1])
try:
self.parent.parent.peers.units[target].process.TempMute(mute)
except:
print mytime.displayTime() + ' Mute single unit failed for', target
return
def make_image(self):
self.ibuffer = self.ibuffer[10:]
if len(self.ibuffer) < 1:
print mytime.displayTime() + ' server.make_image: Packet too short'
self.push('error')
return
target = self.ibuffer[1:len(self.ibuffer)]
try:
self.parent.parent.peers.units[target].process.MakeImage()
except:
pass
return
def update_display(self):
self.ibuffer = self.ibuffer[14:]
if len(self.ibuffer) < 1:
print mytime.displayTime() + ' server.update_display: Packet too short'
self.push('error')
return
target = self.ibuffer[1:len(self.ibuffer)]
print mytime.displayTime(), 's.update_display'
try:
self.parent.parent.peers.units[target].process.startUpdateDisplay()
except:
pass
return
def power_group(self):
self.ibuffer = self.ibuffer[11:]
if len(self.ibuffer) < 1:
print mytime.displayTime() + ' server.power_group: Packet too short'
self.push('error')
return
tlen = ord(self.ibuffer[0])
if len(self.ibuffer) < tlen + 1:
print mytime.displayTime() + ' server.power_group: Packet too short (2)'
self.push('error')
return
target = self.ibuffer[1:tlen + 1]
state = ord(self.ibuffer[tlen + 1])
if target == 'all_units':
maclist = self.parent.parent.peers.units.keys()
else:
try:
maclist = one_unit.app.groups[target]
except:
print mytime.displayTime() + ' Unknown Group', target
return
threads = {}
for mac in maclist:
if mac not in one_unit.app.pin_verified or one_unit.app.pin_verified[mac] == False:
continue
if mac not in self.parent.parent.peers.units:
continue
try:
threads[mac] = threading.Thread('power_state_' + mac, target=self.parent.parent.peers.units[mac].process.SetPower(state))
except:
pass
return
def power_single_unit(self):
self.ibuffer = self.ibuffer[17:]
if len(self.ibuffer) < 18:
print mytime.displayTime() + ' server.power_single_unit: Packet too short'
self.push('error')
return
target = self.ibuffer[1:len(self.ibuffer) - 1]
state = ord(self.ibuffer[len(self.ibuffer) - 1])
try:
self.parent.parent.peers.units[target].process.SetPower(state)
except:
pass
return
def send_vu_data(self):
data = 'vu_list:'
try:
for mac in unit_data.vu.keys():
data += str(mac) + struct.pack('b', unit_data.vu[mac][0]) + struct.pack('b', unit_data.vu[mac][1])
except:
pass
self.push(data)
return
def update_groups(self):
group_membership_list = {}
for MAC in self.parent.parent.peers.units.keys():
group_membership_list[MAC] = []
for group_id in one_unit.app.groups:
if MAC in one_unit.app.groups[group_id].keys():
group_membership_list[MAC].append(group_id)
self.parent.group_membership_list[MAC] = group_membership_list[MAC]
self.parent.groups = one_unit.app.groups
return
def locate_unit(self):
self.ibuffer = self.ibuffer[11:]
if len(self.ibuffer) < 1:
print mytime.displayTime() + ' server.locate_unit: Packet too short'
self.push('error')
return
tlen = ord(self.ibuffer[0])
if len(self.ibuffer) < tlen + 1:
print mytime.displayTime() + ' server.locate_unit: Packet too short (2)'
self.push('error')
return
target = self.ibuffer[1:tlen + 1]
key = data_model.Key(protocol.STRUCT_ID_COMMAND, protocol.MEMBER_ID_COMMAND, 0, protocol.cmdLocate)
try:
if target in self.parent.parent.peers.units.keys():
self.parent.parent.peers.units[target].process.conn.set_by_key(key, 1)
try:
future.Future(3, self.parent.parent.peers.units[target].process.conn.set_by_key, key, 0)
except:
traceback.print_exc(file=sys.stdout)
else:
print mytime.displayTime() + ' Unknown Unit:', target
except:
print mytime.displayTime() + ' s.lu.Unit not connected:', target
return
def start_main_update(self):
print mytime.displayTime(), 's.smu.1'
self.ibuffer = self.ibuffer[17:]
if len(self.ibuffer) < 1:
print mytime.displayTime() + ' server.start_main_update: Packet too short'
self.push('error: packet too short')
return
tlen = ord(self.ibuffer[0])
if len(self.ibuffer) < tlen + 1 and self.telnet == False:
print mytime.displayTime() + ' server.start_main_update: Packet too short (2)'
self.push('error: packet too short')
return
if self.telnet == True:
target = self.ibuffer[1:].strip()
else:
target = self.ibuffer[1:tlen + 1]
if self.telnet == False:
ignore = self.ibuffer[tlen + 1]
else:
ignore = 'i'
print mytime.displayTime(), ' '
print mytime.displayTime() + ' s.smu.Updating', target, ignore
try:
if target in self.parent.parent.peers.units.keys():
self.parent.parent.peers.units[target].process.StartMainUpdate(ignore)
if self.telnet == True:
self.push('Updating ' + target)
else:
print mytime.displayTime() + ' Unknown Unit:', target
self.push('error: unknown target')
except:
print mytime.displayTime() + ' s.smu.Unit not connected:', target
self.push('error: unit not connected')
return
def clear_data_buffer(self):
if len(self.ibuffer) > 3:
MAC = self.ibuffer[17:]
if MAC.count(':') != 5:
print mytime.displayTime(), 's.cdb.No valid MAC found, aborting. MAC:', MAC
self.push('clear_data_buffer_failed')
return
try:
tmp = self.parent.parent.peers.units[MAC].process.conn.MK2
except:
self.push('clear_data_buffer_failed')
mytime.sleep(0.1)
return
else:
try:
name = self.parent.parent.peers.units[MAC].name
while 1:
for testkey in self.parent.parent.peers.units[MAC].process.conn.values.keys():
if testkey.struct_id != protocol.STRUCT_ID_COMMAND and testkey.member_id not in protocol.unit_global_items:
if testkey.struct_id == protocol.STRUCT_ID_PRESET_GLOBAL and testkey.member_id == protocol.MEMBER_ID_SHORT_NAME and testkey.channel > 0:
continue
del self.parent.parent.peers.units[MAC].process.conn.values[testkey]
break
stop_loop = True
for testkey in self.parent.parent.peers.units[MAC].process.conn.values.keys():
if testkey.struct_id != protocol.STRUCT_ID_COMMAND and testkey.member_id not in protocol.unit_global_items:
if testkey.struct_id == protocol.STRUCT_ID_PRESET_GLOBAL and testkey.member_id == protocol.MEMBER_ID_SHORT_NAME and testkey.channel > 0:
continue
stop_loop = False
break
if stop_loop == True:
break
self.parent.parent.peers.units[MAC].process.conn.ResetValues = True
self.parent.parent.peers.units[MAC].process.conn.correct_vars = 0
except:
traceback.print_exc(file=sys.stdout)
self.push('clear_data_buffer_ok')
print mytime.displayTime() + ' s.cdb.Cleared data buffer for', MAC
return
print mytime.displayTime() + ' s.cdb.Clear data buffer failed, invalid command'
return
def command_get(self):
try:
MAC = self.ibuffer[self.ibuffer.find(' ') + 1:self.ibuffer.find('/')]
self.ibuffer = self.ibuffer[self.ibuffer.find('/') + 1:]
struct_id = int(self.ibuffer[:self.ibuffer.find('/')])
self.ibuffer = self.ibuffer[self.ibuffer.find('/') + 1:]
member_id = int(self.ibuffer[:self.ibuffer.find('/')])
self.ibuffer = self.ibuffer[self.ibuffer.find('/') + 1:]
channel = int(self.ibuffer[:self.ibuffer.find('/')])
self.ibuffer = self.ibuffer[self.ibuffer.find('/') + 1:]
num = int(self.ibuffer)
if member_id in (protocol.MEMBER_ID_SET_PASSWORD, protocol.MEMBER_ID_CHECK_PASSWORD):
self.push(newline + 'Access Denied')
return
key = data_model.Key(protocol.STRUCT_ID_GLOBAL, protocol.MEMBER_ID_CURRENT_USER, 0, 0)
try:
user = int(self.parent.parent.peers.units[MAC].process.conn.values[key].read_val)
except:
user = protocol.uLocked
if user != protocol.uFactory and member_id != protocol.MEMBER_ID_CURRENT_USER and one_unit.app.testpc == False:
self.push(newline + 'Access Denied')
return
key = data_model.Key(struct_id, member_id, channel, num)
if key not in one_unit.app.member_scale:
one_unit.app.member_scale[key] = protocol.get_member_scale(key.member_id)
one_unit.app.member_offset[key] = 0.0
try:
if protocol.get_member_format(member_id)[-1:] == 's':
val = self.parent.parent.peers.units[MAC].process.conn.values[key].read_val
else:
val = self.parent.parent.peers.units[MAC].process.conn.values[key].read_val - one_unit.app.member_offset[key]
val = val / one_unit.app.member_scale[key]
self.push(newline + MAC + '/' + str(struct_id) + '/' + str(member_id) + '/' + str(channel) + '/' + str(num) + ': ' + str(val))
except:
self.push(newline + MAC + '/' + str(struct_id) + '/' + str(member_id) + '/' + str(channel) + '/' + str(num) + ': None')
except:
traceback.print_exc(file=sys.stdout)
self.push(newline + 'Syntax error')
return
def command_set(self):
try:
MAC = self.ibuffer[self.ibuffer.find(' ') + 1:self.ibuffer.find('/')]
self.ibuffer = self.ibuffer[self.ibuffer.find('/') + 1:]
struct_id = int(self.ibuffer[:self.ibuffer.find('/')])
self.ibuffer = self.ibuffer[self.ibuffer.find('/') + 1:]
member_id = int(self.ibuffer[:self.ibuffer.find('/')])
key = data_model.Key(protocol.STRUCT_ID_GLOBAL, protocol.MEMBER_ID_CURRENT_USER, 0, 0)
try:
user = int(self.parent.parent.peers.units[MAC].process.conn.values[key].read_val)
except:
user = protocol.uLocked
if user != protocol.uFactory and member_id != protocol.MEMBER_ID_CHECK_PASSWORD and one_unit.app.testpc == False:
self.push(newline + 'Access Denied')
return
if member_id in (protocol.MEMBER_ID_SET_PASSWORD, protocol.MEMBER_ID_CURRENT_USER):
self.push(newline + 'Access Denied')
return
self.ibuffer = self.ibuffer[self.ibuffer.find('/') + 1:]
channel = int(self.ibuffer[:self.ibuffer.find('/')])
self.ibuffer = self.ibuffer[self.ibuffer.find('/') + 1:]
num = int(self.ibuffer[:self.ibuffer.find('=')])
self.ibuffer = self.ibuffer[self.ibuffer.find('=') + 1:]
val = self.ibuffer.strip()
valstring = val
key = data_model.Key(struct_id, member_id, channel, num)
if key not in one_unit.app.member_scale:
one_unit.app.member_scale[key] = protocol.get_member_scale(key.member_id)
one_unit.app.member_offset[key] = 0.0
try:
if protocol.get_member_format(member_id)[-1:] != 's':
val = float(val) * one_unit.app.member_scale[key]
val = val + one_unit.app.member_offset[key]
try:
if member_id in (protocol.MEMBER_ID_CHECK_PASSWORD, protocol.MEMBER_ID_COMMAND):
self.parent.parent.peers.units[MAC].process.conn.set_by_key(key, val, False)
else:
self.parent.parent.peers.units[MAC].process.conn.set_by_key(key, val, True)
self.parent.parent.peers.set_by_key(MAC, key, val)
except:
traceback.print_exc(file=sys.stdout)
self.push(newline + 'Connection to target lost')
self.push(newline + 'Setting ' + MAC + '/' + str(struct_id) + '/' + str(member_id) + '/' + str(channel) + '/' + str(num) + ': ' + valstring)
except:
self.push(newline + 'Unknown error')
print mytime.displayTime(), 's.cs.Error in telnet process'
traceback.print_exc(file=sys.stdout)
except:
traceback.print_exc(file=sys.stdout)
self.push(newline + 'Syntax error')
return
def command_DDL(self):
if len(self.ibuffer) > 3:
cmd = self.process_data_pkt(parse_data_pkt(self.ibuffer), True)
if cmd == None:
return
self.push(cmd)
self.parent.parent.last_loopback = mytime.clock()
return
def command_list(self):
"""Process a 'list' command from the user."""
if len(self.parent.parent.peers.units) == 0:
self.push('unit_list:None' + newline)
elif self.telnet == True:
res = ''
try:
for MAC in self.parent.parent.peers.units.keys():
if MAC.startswith('DEMO') == True:
continue
res += 'unit:' + newline
res += 'MAC='
res += str(MAC) + newline
res += 'Name='
res += str(self.parent.parent.peers.units[MAC].name) + newline
res += 'Type='
res += str(self.parent.parent.peers.units[MAC].type) + newline
res += 'Link_type='
res += str(self.parent.parent.peers.units[MAC].link_type) + newline
res += 'Link_status='
res += str(self.parent.parent.peers.units[MAC].link_status) + newline
res += 'IP='
res += str(self.parent.parent.peers.units[MAC].IP) + newline
res += 'Serial_number='
res += str(self.parent.parent.peers.units[MAC].Serial) + newline
res += 'Hardware_version='
res += str(self.parent.parent.peers.units[MAC].HWVersion) + newline
res += 'Firmware_version='
res += str(self.parent.parent.peers.units[MAC].FWVersion) + newline
res += 'Interface_version='
res += str(self.parent.parent.peers.units[MAC].PICVersion) + newline
res += 'Type_String_2='
if self.parent.parent.peers.units[MAC].originalSwID == '':
self.parent.parent.peers.units[MAC].originalSwID = self.parent.parent.peers.units[MAC].type
res += str(self.parent.parent.peers.units[MAC].originalSwID) + newline
res += 'Production_date='
res += str(self.parent.parent.peers.units[MAC].ProductionDate) + newline
res += 'Mute_status='
res += str(self.parent.parent.peers.units[MAC].Muted) + newline
res += 'Build_Number='
res += str(self.parent.parent.peers.units[MAC].BuildNumber) + newline
except:
traceback.print_exc(file=sys.stdout)
self.push(res)
return
res = ''
res += 'unit_list:'
try:
for MAC in self.parent.parent.peers.units.keys():
if MAC.startswith('DEMO') == True:
continue
res += 'unit'
res += chr(len(MAC))
res += str(MAC)
res += chr(len(self.parent.parent.peers.units[MAC].name))
res += str(self.parent.parent.peers.units[MAC].name)
res += chr(len(self.parent.parent.peers.units[MAC].type))
res += str(self.parent.parent.peers.units[MAC].type)
res += chr(len(self.parent.parent.peers.units[MAC].link_type))
res += str(self.parent.parent.peers.units[MAC].link_type)
res += chr(len(self.parent.parent.peers.units[MAC].link_status))
res += str(self.parent.parent.peers.units[MAC].link_status)
res += chr(len(self.parent.parent.peers.units[MAC].IP))
res += str(self.parent.parent.peers.units[MAC].IP)
res += chr(len(unicode(self.parent.parent.peers.units[MAC].Serial)))
res += str(self.parent.parent.peers.units[MAC].Serial)
res += chr(len(self.parent.parent.peers.units[MAC].HWVersion))
res += str(self.parent.parent.peers.units[MAC].HWVersion)
res += chr(len(self.parent.parent.peers.units[MAC].FWVersion))
res += str(self.parent.parent.peers.units[MAC].FWVersion)
res += chr(len(self.parent.parent.peers.units[MAC].PICVersion))
res += str(self.parent.parent.peers.units[MAC].PICVersion)
if self.parent.parent.peers.units[MAC].originalSwID == '':
self.parent.parent.peers.units[MAC].originalSwID = self.parent.parent.peers.units[MAC].type
res += chr(len(self.parent.parent.peers.units[MAC].originalSwID))
res += str(self.parent.parent.peers.units[MAC].originalSwID)
res += chr(len(self.parent.parent.peers.units[MAC].ProductionDate))
res += str(self.parent.parent.peers.units[MAC].ProductionDate)
res += chr(len(self.parent.parent.peers.units[MAC].Muted))
res += str(self.parent.parent.peers.units[MAC].Muted)
res += chr(len(str(self.parent.parent.peers.units[MAC].BuildNumber)))
res += str(self.parent.parent.peers.units[MAC].BuildNumber)
except:
traceback.print_exc(file=sys.stdout)
res += 'end'
self.push(res)
return
def command_get_group(self):
my_group = 'None'
pos = ord(self.ibuffer[7]) + 6
MAC = self.ibuffer[6:pos]
res = 'group:'
for group in one_unit.app.groups.keys():
if group == 'all_units':
continue
if MAC in one_unit.app.groups[group].keys():
my_group = group
res += chr(len(my_group))
res += str(my_group)
self.push(res)
return
def command_presets(self):
"""Process a 'presets' command from the user."""
pos = ord(self.ibuffer[7]) + 8
MAC = self.ibuffer[8:pos]
if MAC == 'Main':
self.push('Not supported yet')
return
try:
length = len(self.parent.parent.peers.units[MAC].preset_names)
except:
print mytime.displayTime() + ' s.cp.unknown MAC address:', MAC
traceback.print_exc(file=sys.stdout)
self.push('Unknown')
return
else:
if length == 0:
print mytime.displayTime() + ' s.cp.len=0'
self.push('None')
return
res = 'preset_list:'
for number in self.parent.parent.peers.units[MAC].preset_names.keys():
res += chr(number)
res += chr(len(self.parent.parent.peers.units[MAC].preset_names[number]))
res += str(self.parent.parent.peers.units[MAC].preset_names[number])
self.push(res)
return
def build_vars_to_send(self, MAC, limit):
vars = {}
no_of_correct_vars = 0
if MAC in self.parent.parent.peers.units:
try:
keys = [_[1] for k in self.parent.parent.peers.units[MAC].values.keys() if k[0] < 0]
except:
print mytime.displayTime() + ' server.build_vars_to_send VU list error'
return
else:
nitems = len(keys)
no_added = 0
item = 0
if nitems > 0:
while item < nitems:
key = keys[item]
try:
result = self.parent.parent.peers.units[MAC].values[key]
except:
print mytime.displayTime() + ' server.build_vars_to_send VU key error'
break
var = result
vars[key] = var
item += 1
try:
keys = [_[2] for k in self.parent.parent.peers.units[MAC].values.keys() if k[0] >= 0]
except:
print mytime.displayTime() + ' server.build_vars_to_send data key list error'
return
else:
nitems = len(keys)
if self.last_requested > nitems:
self.last_requested = 0
starting_point = self.last_requested
priority = 1
loopcounter = 0
added_pri = 0
now = mytime.clock()
if nitems > 0:
while no_added < limit and loopcounter < 10000:
loopcounter += 1
if self.last_requested >= nitems:
self.last_requested = 0
self.next_requested = (self.last_requested + 1) % nitems
self.last_requested = self.next_requested
key = keys[self.next_requested]
if key in vars.keys():
continue
if priority == 1:
if self.next_requested == starting_point:
priority = 0
try:
if self.parent.priority_level[key] - now < 0:
continue
except:
self.parent.priority_level[key] = 0
continue
elif self.next_requested == starting_point:
break
try:
vars[key] = self.parent.parent.peers.units[MAC].values[key]
if priority == 1:
added_pri = 1
no_added += 1
except:
print mytime.displayTime() + ' server.build_vars_to_send data key error'
break
try:
if MAC[:4] not in ('DEMO', 'GRPdeactivated'):
no_of_correct_vars = self.parent.parent.peers.units[MAC].process.conn.correct_vars
synced = self.parent.parent.peers.units[MAC].process.conn.synced
else:
no_of_correct_vars = 10000
synced = True
except:
pass
try:
res = build_command(MAC, vars, no_of_correct_vars, synced)
except:
res = None
return res
def set_get_key(self, key, MAC):
if key.struct_id < 0:
return
if key.struct_id in (11, 255):
return
if key.member_id in (37, 50):
return
maclist = []
try:
for group_id in self.parent.group_membership_list[MAC]:
if one_unit.app.group_enabled[group_id] == False:
continue
if group_id == 'all_units':
continue
if one_unit.app.group_type[group_id] == 'Mute':
if key.struct_id == protocol.STRUCT_ID_MUTE and key.channel < 128:
for target_MAC in one_unit.app.groups[group_id]:
maclist.append(target_MAC)
elif one_unit.app.group_type[group_id] == 'Carbon Copy':
if key not in one_unit.app.group_exceptions[group_id]:
for target_MAC in one_unit.app.groups[group_id]:
maclist.append(target_MAC)
elif key in one_unit.app.group_links[group_id]:
for target_MAC in one_unit.app.groups[group_id]:
maclist.append(target_MAC)
if len(maclist) == 0:
maclist.append(MAC)
if key in self.group_skip_list:
maclist = [
MAC]
for SET_MAC in maclist:
try:
del self.parent.parent.peers.units[SET_MAC].process.conn.values[key]
except:
pass
try:
self.parent.parent.peers.units[SET_MAC].process.conn.get_list.insert(0, key)
self.parent.parent.peers.units[SET_MAC].process.conn.config_vars.insert(0, key)
except:
pass
except:
pass
return
def set_direct_value(self, key, val, MAC, factory, group=None):
maclist = []
relative_maclist = []
if MAC[:4] == 'GRP_':
print mytime.displayTime(), 's.sdv.GRP_:', MAC
group = MAC[4:]
if group != None:
if group not in one_unit.app.groups:
print mytime.displayTime(), 's.sdv.invalid group:', group, MAC
group = None
else:
if one_unit.app.group_enabled[group] == False:
return
group_type = one_unit.app.group_type[group]
if group_type == 'Mute':
if key.struct_id != protocol.STRUCT_ID_MUTE:
return
elif group_type == 'Carbon Copy':
if key in one_unit.app.group_exceptions[group]:
return
elif key not in one_unit.app.group_links[group]:
print key, 'not in group links', group, one_unit.app.group_links
return
if one_unit.app.group_type[group] in one_unit.app.group_relative and one_unit.app.group_relative[one_unit.app.group_type[group]] == True:
if key in one_unit.app.group_links[group]:
relative_maclist += one_unit.app.groups[group]
else:
maclist = one_unit.getMacList(group)
else:
for group_id in self.parent.group_membership_list[MAC]:
if group_id in ('all_units', None):
continue
if one_unit.app.group_enabled[group_id] == False:
continue
group_type = one_unit.app.group_type[group_id]
print mytime.displayTime(), 's.sdv.unit:', MAC, group_type
if group_type == 'Mute':
maclist = [
MAC]
elif one_unit.app.group_type[group_id] == 'Carbon Copy':
if key not in one_unit.app.group_exceptions[group_id]:
maclist += one_unit.app.groups[group_id]
elif one_unit.app.group_type[group_id] in one_unit.app.group_relative and one_unit.app.group_relative[one_unit.app.group_type[group_id]] == True:
maclist = [
MAC]
elif key in one_unit.app.group_links[group_id]:
maclist += one_unit.app.groups[group_id]
if len(maclist) == 0 and len(relative_maclist) == 0:
if group != None:
return
maclist.append(MAC)
if key in self.group_skip_list:
maclist = [MAC]
relative_maclist = []
if len(relative_maclist) > 0:
relative_maclist.remove(MAC)
maclist = [MAC]
try:
delta = val - self.parent.parent.peers.get(key, MAC)
print mytime.displayTime(), 's.Relative change, old:', self.parent.parent.peers.get(key, MAC), 'new:', val, 'delta:', delta, 'source MAC:', MAC
except:
print mytime.displayTime(), 's.Trying to get delta failed for key', key
traceback.print_exc(file=sys.stdout)
return
else:
repeatlist = relative_maclist[:]
for SET_MAC in repeatlist:
if SET_MAC not in one_unit.app.pin_verified or one_unit.app.pin_verified[SET_MAC] == False or SET_MAC[:4] in ('DEMO',
'GRP_',
'VN::'):
relative_maclist.remove(SET_MAC)
repeat = 50
while repeat > 0 and len(relative_maclist) > 0:
repeatlist = relative_maclist[:]
print mytime.displayTime(), 's.Applying relative change to', len(repeatlist), 'units', repeat
for SET_MAC in repeatlist:
try:
set_val = self.parent.parent.peers.units[SET_MAC].process.conn.add_by_key(key, delta, factory)
if set_val != None:
relative_maclist.remove(SET_MAC)
self.parent.parent.peers.set_by_key(SET_MAC, key, set_val)
except:
traceback.print_exc(file=sys.stdout)
repeat -= 1
mytime.sleep(0.1)
for SET_MAC in maclist:
if SET_MAC not in one_unit.app.pin_verified or one_unit.app.pin_verified[SET_MAC] == False or SET_MAC[:4] in ('DEMO',
'GRP_',
'VN::'):
continue
try:
self.parent.parent.peers.units[SET_MAC].process.conn.set_by_key(key, val, factory)
self.parent.parent.peers.set_by_key(SET_MAC, key, val)
except:
print mytime.displayTime() + ' s.sd: Connection to', SET_MAC, 'lost'
return
def process_data_pkt(self, pkt, reply):
if pkt == None:
return
else:
MAC = None
priority_time = mytime.clock() + 2
for (opcode, fragment, MAC) in pkt.fragments:
if opcode == 234:
factory = True
else:
factory = False
if self.printed_conn == False:
print mytime.displayTime() + ' Accepting Connection from', MAC
self.printed_conn = True
if self.s != None:
self.link_mac = MAC
if len(fragment) == 0:
continue
if len(fragment) < 5:
print mytime.displayTime() + ' server.process.too small fragment! len=', len(fragment), ', packet discarded'
break
if MAC not in self.parent.parent.peers.units:
return
struct_id = struct.unpack('B', fragment[0])[0]
member_id = struct.unpack('B', fragment[1])[0]
channel = struct.unpack('B', fragment[2])[0]
index = struct.unpack('B', fragment[3])[0]
key = Key(struct_id, member_id, channel, index)
val = ''
try:
val = struct.unpack(protocol.get_member_format(member_id), fragment[4:])[0]
except:
continue
self.set_direct_value(key, val, MAC, factory)
self.invalid_packet_counter = 0
if reply == True and MAC != None:
return self.build_vars_to_send(MAC, 10)
return
return
class Data_packet():
"""The announcement broadcast by hardware units over USB"""
def __init__(self):
"""Constructor"""
self.fragments = []
self.PC_PacketId = None
self.HW_PacketId = None
self.invalid_packet_counter = 0
return
def __str__(self):
return 'Data_packet(opcode=%s, id=%s)' % (self.opcode,
self.HW_PacketId)
def parse_data_pkt(data):
res = Data_packet()
if len(data) < 5:
print mytime.displayTime() + ' server.invalid data (1)! length: ', len(data), ', packet discarded'
res.fragments = []
return res
else:
DDL = data[:3]
if DDL != 'DDL' and DDL != 'DDG':
print mytime.displayTime() + ' server.invalid data (2)! code: ', DDL, ', packet discarded'
res.fragments = []
res.invalid_packet_counter = res.invalid_packet_counter + 1
return res
pos = ord(data[3]) + 4
if len(data) < pos - 1:
print mytime.displayTime() + ' server.invalid data (3)! length: ', len(data), ', packet discarded'
res.fragments = []
return res
MAC = data[4:pos]
no_of_fragments = 0
if len(data) <= pos:
res.fragments.append((0, '', MAC))
return res
while pos + 6 < len(data):
opcode = ord(data[pos])
if opcode != 187 and opcode != 234:
return None
pos += 1
size = ord(data[pos])
pos += 1
size -= 2
if size < 2:
print mytime.displayTime() + ' server.too small fragment! opcode: ', opcode, ' size:', size + 2, ', packet discarded'
return None
if pos + size > len(data):
print mytime.displayTime() + ' server.fragment exceeds packet boundary! opcode: ', opcode, ', packet discarded'
return None
res.fragments.append((opcode, data[pos:pos + size], MAC))
pos += size
no_of_fragments += 1
return res
def build_command(MAC, vars={}, correct_vars=0, synced=False):
no_of_fragments = 0
if synced == False:
synced = chr(0)
else:
synced = chr(1)
cmd = 'DDR' + chr(len(MAC)) + MAC + struct.pack('I', correct_vars) + synced
for (k, v) in vars.items():
opcode = 123
(struct_id, member_id, channel, index) = k
new_val = struct.pack(protocol.get_member_format(member_id), v)
struct_id = struct.pack('b', struct_id)
member_id = struct.pack('B', member_id)
channel = struct.pack('B', channel)
index = struct.pack('B', index)
cmd += chr(opcode) + chr(6 + len(new_val)) + struct_id + member_id + channel + index + new_val
no_of_fragments += 1
return cmd
if __name__ == '__main__':
print 'Server start'
daemon = Daemon()
# okay decompiling pycode/server.pyc