diff --git a/appliance_setup/device_types.py b/appliance_setup/device_types.py index 6a21e9870cde6372a2ad44f3e70ee430f6fafd80..ef7596c311c1c8c06f0485a31fbcb1ebf9791f3c 100755 --- a/appliance_setup/device_types.py +++ b/appliance_setup/device_types.py @@ -14,47 +14,65 @@ from configuration import * device_factories = []; class DeviceFactory: - def __init__ (self): - pass - def list_supported (self): - return []; - def detect (self, ui): - return []; + def __init__ (self): + pass + def list_supported (self): + return []; + def detect (self, ui): + return []; ## Base class class Device: - ui = None - capabilities = {} - def __init__ (self, ui): - self.ui = ui - self.capabilities = {'wifi': False, 'ad-hoc': False} + ui = None + capabilities = {} + def __init__ (self, ui): + self.ui = ui + self.capabilities = {'wifi': False, 'ad-hoc': False} - def device_string (self): - pass + def device_string (self): + pass - def detect_devices (self): - pass + def detect_devices (self): + pass - def device_open (self): - pass - def device_close (self): - pass - def config_send (self, config): - pass - def config_retrieve (self): - pass - def device_reset (self): - pass - def scan_for_aps (self): - pass - def print_supported_devices (self): - pass - def error (self, msg): - self.ui.error (msg) - def set_hostname (self, hostname): - config = Config (self.ui, cfg=[('0001', 'BOX_NAME', hostname)]); - self.ui.debug ("\tChanging hostname using config\n\t%s\n" % config.to_string ()) - return self.config_send (config) + def device_open (self): + pass + def device_close (self): + pass + def command_send (self, cmd): + cfg = "%s:\n" % cmd + res = self.bulk_data_write (cfg, len(cfg)) + return self.bulk_data_read (25600) + + def config_retrieve (self): + self.ui.debug ("Reading current configuration..."); + return self.command_send ("9100") + + def config_send (self, config): + self.ui.progress ("Sending new configuation to the device. Please wait") + cfgstring = config.to_string () + self.ui.debug ("\tNew device config: %s\n" % cfgstring) + self.bulk_data_write (cfgstring, len(cfgstring)) + self.ui.sleep_progress (10) + # Now reset the device: + return self.device_reset () + + def bulk_data_write (self, data, length, timeout=500): + pass + def bulk_data_read (self, length, timeout=500): + pass + def device_reset (self): + pass + def scan_for_aps (self): + pass + def print_supported_devices (self): + pass + def error (self, msg): + self.ui.error (msg) + def set_hostname (self, hostname): + config = Config (self.ui, cfg=[('0001', 'BOX_NAME', hostname)]); + self.ui.debug ("\tChanging hostname using config\n\t%s\n" % config.to_string ()) + return self.config_send (config) class USBDeviceFactory (DeviceFactory): @@ -129,25 +147,9 @@ class USBDevice (Device): self.handle.reset () self.handle = None - def config_retrieve (self): - self.ui.debug ("Reading current configuration..."); - cfg = "" - res = self.bulk_data_write ("9100:\n", 6) - return self.bulk_data_read (25600) - - def config_send (self, config): - self.ui.progress ("Sending new configuation to the device. Please wait") - cfgstring = config.to_string () - self.ui.debug ("\tNew device config: %s\n" % cfgstring) - - self.bulk_data_write (cfgstring, len(cfgstring)) - self.ui.sleep_progress (10) - # Now reset the device: - return self.device_reset () - def device_reset (self): self.ui.progress ("Resetting the device, please wait") - res = self.bulk_data_write ("9002:\n", 6) + res = self.command_send ("9002") self.ui.debug ("\tSent 9002 reset command: %d" % res) # Poll the device until it doesn't respond. Then sleep for ~15 seconds try: @@ -165,13 +167,13 @@ class USBDevice (Device): self.device_close () self.ui.wait_enter ("Device was reset. Please press Return.") - def bulk_data_write (self, data, length): + def bulk_data_write (self, data, length, timeout=500): # Add the header (12 bytes): '@\0', packet length, boxname (="XXXXXXXX") request = "@\0" + struct.pack("<H8s", length, self.thisboxname) + data self.ui.debug ("Request: " + request) res = None try: - res = self.handle.bulkWrite (1, request, 500) + res = self.handle.bulkWrite (1, request, timeout) except Exception, e: self.error ("writing bulk data; message: %s" % e.message) return res @@ -247,20 +249,12 @@ class Ether8888Packet: return True def encode (self, cmd, unknown, nrPackets, dataLen, data): - # TODO - self.dstAddr, self.srcAddr, self.proto = struct.pack(self.ethHeaderFmt,data[:14]) - if self.proto != 0x8888: - # FIXME: Error message about invalid packet - return False - self.ethData = data[14:] - self.cmd,self.unknown,self.zero,self.nrPackets,self.dataLen = \ - struct.unpack (self.headerFmt, self.ethData[:10]) - self.payload = self.ethData[10:self.dataLen+10] - - if (self.dataLen != len (self.payload)): - # FIXME: Error message about invalid packet - return False - return True + # Ethernet II header + d = struct.pack(self.ethHeaderFmt, self.dstAddr, self.srcAddr, self.proto) + d += struct.pack (self.headerFmt, self.cmd, self.unknown, self.zero, + self.nrPackets, self.dataLen) + d += data + return d class Ether8888DeviceFactory (DeviceFactory): supported_devices = ( @@ -336,7 +330,7 @@ class Ether8888Device (Device): self.srcAddr = None self.destAddr = None self.capabilities['wifi'] = True; - #self.capabilities['ad-hoc'] = False; + self.capabilities['ad-hoc'] = False; def device_string (self): return "%s (Ethernet interface %s, MAC %12s)" % ( @@ -360,6 +354,55 @@ class Ether8888Device (Device): self.socket.close () self.socket = None + def device_reset (self): + self.ui.progress ("Resetting the device, please wait") + res = self.command_send ("9002") + self.ui.debug ("\tSent 9002 reset command: %d" % res) + # Poll the device until it doesn't respond. Then sleep for ~15 seconds + self.ui.sleep_progress (20) + self.device_close () + self.ui.wait_enter ("Device was reset. Please press Return.") + + def bulk_data_write (self, data, length): + packet = Ether8888Packet (localAddr = self.localAddr, remoteAddr = self.remoteAddr) + request = packet.encode ("\x01\x01", "\0\0", "\0\0", 0, length, data) + self.ui.debug ("Request: " + request) + res = None + try: + res = self.socket.send (request) + except Exception, e: + self.error ("writing data; message: %s" % e.message) + return res + + # Read and return USB bulk data + def bulk_data_read (self, length, timeout=500): + # TODO: Get rid of the length argument, simply read all that is sent + try: + res = self.handle.bulkRead (2, length+13, timeout); + except Exception, e: + self.error ("reading bulk data; message: %s" % e.message) + return None + + # bulkRead returns a tuple, convert to a binary string + res = ''.join(chr(v) for v in res) + if (len (res) == 0): + self.ui.debug ("\tEmpty response received\n") + return '' + + self.ui.debug ("read %d bytes: \n" % len (res)) + self.ui.hex_print (res) + # Check and cut off the header after some sanity checks: + if (not res.startswith ("@\0\0")): + self.error ("reading data: Wrong header %s" % res[0:3]) + (datalen,) = struct.unpack ("H", res[3:5]); + realdatalen = len (res)-13 + if (datalen != realdatalen): + self.error ("reading data: Expected %d bytes of data, got %d\n" % (datalen, realdatalen)) + self.boxname = res[5:13] + ## FIXME: Check the name of the box... + ## cut off the header: + return res[13:] + ### FTP-based devices like ??? #class FTPDevice (Device):