Skip to content
Snippets Groups Projects
Commit 3237246b authored by Reinhold Kainhofer's avatar Reinhold Kainhofer
Browse files

appliance_setup: Implement wlan scan, ask for SSID, implement changing host...

appliance_setup: Implement wlan scan, ask for SSID, implement changing host name on 8888 devices, etc.
parent 0075ae54
Branches
No related tags found
No related merge requests found
......@@ -73,130 +73,20 @@ def ask_device (ui):
"""
###############################################################################
## WIRELESS NETWORK DETECTION
###############################################################################
sub parse_survey_data ($) {
my $survey = shift;
my $networks = {};
my @entries = split ("\x0b", $survey);
foreach (@entries) {
(my $ssid, my $settings) = split ("\x0c", $_);
my @settings = split (",", $settings);
$networks->{$ssid} = {
'mac' => $settings[0],
'channel' => $settings[1],
'wifi_ver' => $settings[2],
'secmode' => $settings[3],
'signal' => $settings[4],
'adhoc' => $settings[5]
};
}
debug Dumper ($networks);
return $networks;
}
sub scan_for_aps ($) {
my $dev = shift;
progress "Scanning for access points: ";
my $loop = 0;
my $found = 0;
my $survey;
while (!$found && $loop <= 4) {
++$loop;
debug ("loop=", $loop, "\n");
my $res = bulk_data_write ($dev, "9107:\n", 6);
$res = bulk_data_read ($dev, my $d="", 0);
sleep_progress (6);
my $cfg = "";
$res = bulk_data_write ($dev, "9100:\n", 6);
$res = bulk_data_read ($dev, $cfg, 25600);
my @config = config_parse ($cfg);
$survey = val(\@config, '7021');
$found = (defined ($survey) && length ($survey) > 0);
}
progress "\n";
if ($found) {
debug "Found wireless networks: \n", $survey;
} else {
print "ERROR: No wireless networks detected.\n";
}
return parse_survey_data ($survey);
}
sub print_wireless_networks ($) {
my $aps = shift;
print "Detected wireless networks:\n";
my $format = " %3s %-25s%-9s%-13s%-17s%-8s\n";
printf $format, " ", "SSID", "Signal", "Security", "Type", "channel";
print "\t------------------------------------------------------------------------\n";
my $i = 0;
foreach my $ssid (sort {lc $a cmp lc $b} keys (%$aps)) {
++$i;
my $network = $aps->{$ssid};
printf $format, $i.")", $ssid, $network->{'signal'},
security2string ($network->{'secmode'}),
$network->{'adhoc'}?"Ad-Hoc":"Infrastructure",
$network->{'channel'};
}
print "\n";
}
###############################################################################
## INFRASTRUCTURE WIRELESS SETUP (i.e. wlan through access point / router)
###############################################################################
sub wifi_ask_ssid ($) {
my $dev = shift;
my $aps = scan_for_aps ($dev);
print_wireless_networks ($aps);
my @ssids = (sort {lc $a cmp lc $b} keys (%$aps));
my $newssid;
print "Please enter the number or the SSID of the desired wireless network.\n";
print "\tEnter '0', 'hidden' or 'h' to connect to a hidden network.\n";
print "\tEnter 'r' or 'rescan' to rescan for wireless networks.\n";
do {
$newssid = input ("Desired wireless network: ");
return $newssid if (exists $aps->{$newssid});
if ($newssid =~ /^[1-9]\d*$/ && ($newssid <= scalar(@ssids))) {
return ($aps,$ssids[$newssid-1]);
}
if ($newssid eq "0" || $newssid eq "h" || $newssid eq "hidden") {
$newssid = "";
while (length($newssid) < 1) {
$newssid = input ("Please enter the SSID: ");
}
return ($aps,$newssid);
}
if ($newssid eq "r" || $newssid eq "rescan") {
return wifi_ask_ssid ($dev);
}
} while 1; # We'll jump out of the loop via return!
}
def wifi_ask_ssid (ui, dev):
while True:
aps = dev.scan_for_aps ()
res = ui.ask_wireless_ap (aps)
print "SSID is {}".format(res)
if res:
return (res, aps)
sub wifi_ask_address ($$) {
my $ap = shift;
my $aps = shift;
my $dhcp = ask_choice ("IP-address assignment:", ["DHCP", "Manual"], ["Enable", "Disable"], "Enable");
my %result = ("dhcp" => $dhcp);
if ($dhcp ne "Enable") {
$result{'ip_addr'} = ask_ip_address ("IP-address of the device:\t");
$result{'mask'} = ask_ip_address ("Netmask:\t");
$result{'gateway'} = ask_ip_address ("IP-address of the gateway:\t");
} else {
$result{'ip_addr'} = "0.0.0.0";
$result{'mask'} = "0.0.0.0";
$result{'gateway'} = "0.0.0.0";
}
return %result;
}
"""
sub wifi_ask_security ($$) {
my $ap = shift;
......@@ -268,40 +158,28 @@ sub wifi_config_create ($) {
return config_create ($config);
}
"""
###############################################################################
## AD-HOC WIRELESS SETUP (i.e. direct connection with print server and PC)
###############################################################################
sub adhoc_send_unknown_command ($) {
my $dev = shift;
bulk_data_write ($dev, "9971:\n", 6);
my $val = "";
bulk_data_read ($dev, $val, 1);
debug "\tResponse to 9971 Ad-hoc setting command (unknown purpose): %s\n", $val;
return $val;
}
sub adhoc_ask_ssid ($) {
my $dev = shift;
my $ssid = "";
print "\n";
do {
$ssid = input ("SSID of the ad-hoc wireless connection:");
if (length ($ssid) > 0) {
def adhoc_ask_ssid (ui, dev):
ssid = ""
ui.progress ("")
while True:
ssid = ui.input ("SSID of the ad-hoc wireless connection:")
if (len(ssid) > 0):
# scan for wireless networks to check for name clashes
my $aps = scan_for_aps ($dev);
if (defined ($aps->{$ssid})) {
print "\tERROR: wireless network '$ssid' already exists, please choose a different name.\n\n";
} else {
return $ssid;
}
}
} while 1; # We'll jump out of the loop via return!
}
aps = dev.scan_for_aps ()
if (aps.get(ssid)):
ui.error ("wireless network '%s' already exists, please choose a different name.\n" % ssid)
else:
return ssid
"""
def adhoc_ask_channel (ap):
channel = False
while (!channel):
......@@ -375,8 +253,8 @@ def ask_operation (ui, dev):
def main ():
reconfigured = False
operation = ""
UI = ConsoleInterface (debug=True)
UI = ConsoleInterface (debug=False)
dev = ask_device (UI)
if (not dev or not dev.device_open ()):
return
......@@ -391,21 +269,23 @@ def main ():
UI.debug ("\tSelected operation: %s\n" % operation)
if (operation == "wifi_infrastructure"):
## Infrastructure, scan for APs
# TODO
#my ($aps,$newap) = wifi_ask_ssid ($dev);
#my %newconfig = ('SSID' => $newap);
#debug ("\tSelected wireless network: %s\n", $newap);
#my %security = wifi_ask_security ($newap, $aps);
#my %ip = wifi_ask_address ($newap, $aps);
#%newconfig = (%newconfig, %security, %ip);
(newap, aps) = wifi_ask_ssid (UI, dev)
newconfig = {'SSID': newap)
UI.debug ("\tSelected wireless network: %s" % newap)
security = UI.wifi_ask_security ()#TODO: $newap, $aps);
newconfig.update (security)
if (dev.capabilities['ip-address']):
ip = UI.ask_IP_setting ()
newconfig.update (ip)
# TODO:
#my $newcfg = wifi_config_create (\%newconfig);
#device_config_send ($dev, $newcfg);
reconfigured = True
elif (operation == "wifi_adhoc"):
## Ad-hoc connection to print server
# TODO
#my $adhocssid = adhoc_ask_ssid ($dev);
#adhoc_send_unknown_command ($dev);
adhocssid = adhoc_ask_ssid (UI, dev)
dev.command_send ("9971:\n")
#my $channel = adhoc_ask_channel ($dev, $adhocssid);
#my %newconfig = ('SSID' => $adhocssid,
#'channel' => $channel,
......
......@@ -34,58 +34,57 @@ class Config:
self.cfgdata = cfg
def print_configuration (self, text):
#print self.cfgstring
##print self.cfgdata
#print self.val('0012')
res = text + "\tDevice name: %s\n" % self.val('0001')
if (self.val('0012') != "Enable"):
res += "\tTCP/IP not yet configured and/or enabled.\n\n"
return res
res = text + "\tDevice name:\t%s\n" % self.val('0001')
adhoc = (self.val('7024') == '1')
if adhoc:
# ad-hoc network:
sec = self.val('7103');
res += "\tWireless mode: Ad-hoc network\n"
res += "\tSSID: %s\n" % self.val('7100')
res += "\tChannel: %s\n" % self.val('7102')
res += "\tSecurity: %s\n" % security2string (sec)
res += "\tWireless mode:\tAd-hoc network\n"
res += "\tSSID:\t\t%s\n" % self.val('7100')
res += "\tChannel:\t%s\n" % self.val('7102')
res += "\tSecurity:\t%s\n" % security2string (sec)
if (sec == 0):
# None => nothing to display
pass
elif (sec == 1):
# WEP => Print passphrase
res += "\tWEP Key: %s\n" % self.val('7106')
res += "\tWEP Key:\t%s\n" % self.val('7106')
else:
# WPA 1/2 or mixed
res += "\tEncryption: %s\n" % encryption2string(self.val('7118'))
res += "\tPassphrase: %s\n" % self.val('7119')
res += "\tEncryption:\t%s\n" % encryption2string(self.val('7118'))
res += "\tPassphrase:\t%s\n" % self.val('7119')
else:
# infrastructure network
sec = self.val('7003');
res += "\tSSID: %s\n" % self.val('7000')
res += "\tChannel: %s\n" % self.val('7002')
res += "\tSecurity: %s\n" % security2string (sec)
res += "\tSSID:\t\t%s\n" % self.val('7000')
res += "\tChannel:\t%s\n" % self.val('7002')
res += "\tSecurity:\t%s\n" % security2string (sec)
if (sec == 0):
# None => nothing to display
pass
elif (sec == 1):
# WEP => Print passphrase
res += "\tAuthentication: %s\n" % authentication2string(self.val('7012'))
res += "\tWEP Key: %s\n" % self.val('7006')
res += "\tAuthentication:\t%s\n" % authentication2string(self.val('7012'))
res += "\tWEP Key:\t%s\n" % self.val('7006')
else:
# WPA 1/2 or mixed
res += "\tEncryption: %s\n" % encryption2string(self.val('7018'))
res += "\tPassphrase: %s\n" % self.val('7019')
res += "\tEncryption:\t%s\n" % encryption2string(self.val('7018'))
res += "\tPassphrase:\t%s\n" % self.val('7019')
dhcp = (self.val('4020') == "Enable")
res += "\tIPv4 method: %s\n" % ("DHCP" if dhcp else "manual")
associated = (self.val('7014').find ("STATE:Associated") >= 0)
if (associated or not dhcp):
res += "\tIP address: %s\n" % self.val('4000')
res += "\tGateway: %s\n" % self.val('4001')
res += "\tNetmask: %s\n" % self.val('4002')
associated = (self.val('7014').find ("STATE:Associated") >= 0) or \
(self.val('7014').find ("STATE:Connected") >= 0)
if (self.get ('4000')):
dhcp = (self.val('4020') == "Enable")
res += "\tIPv4 method:\t%s\n" % ("DHCP" if dhcp else "manual")
if (associated or not dhcp):
res += "\tIP address:\t%s\n" % self.val('4000')
res += "\tGateway:\t%s\n" % self.val('4001')
res += "\tNetmask:\t%s\n" % self.val('4002')
else:
res += "\tDevice does not receive an IP address\n"
if associated:
res += "\tLink state: %s\n" % self.val('7014')
res += "\tLink state:\t%s\n" % self.val('7014').replace ("\x0b", "\n\t\t\t").replace (";", "\n\t\t\t")
else:
# Not connected
res += "\tWireless not connected\n"
......@@ -141,175 +140,14 @@ class Config:
###############################################################################
## DEVICE CONFIGURATION HANDLING
###############################################################################
"""
###############################################################################
## WIRELESS NETWORK DETECTION
###############################################################################
sub parse_survey_data ($) {
my $survey = shift;
my $networks = {};
my @entries = split ("\x0b", $survey);
foreach (@entries) {
(my $ssid, my $settings) = split ("\x0c", $_);
my @settings = split (",", $settings);
$networks->{$ssid} = {
'mac' => $settings[0],
'channel' => $settings[1],
'wifi_ver' => $settings[2],
'secmode' => $settings[3],
'signal' => $settings[4],
'adhoc' => $settings[5]
};
}
debug Dumper ($networks);
return $networks;
}
sub scan_for_aps ($) {
my $dev = shift;
progress "Scanning for access points: ";
my $loop = 0;
my $found = 0;
my $survey;
while (!$found && $loop <= 4) {
++$loop;
debug ("loop=", $loop, "\n");
my $res = bulk_data_write ($dev, "9107:\n", 6);
$res = bulk_data_read ($dev, my $d="", 0);
sleep_progress (6);
my $cfg = "";
$res = bulk_data_write ($dev, "9100:\n", 6);
$res = bulk_data_read ($dev, $cfg, 25600);
my @config = config_parse ($cfg);
$survey = val(\@config, '7021');
$found = (defined ($survey) && length ($survey) > 0);
}
progress "\n";
if ($found) {
debug "Found wireless networks: \n", $survey;
} else {
print "ERROR: No wireless networks detected.\n";
}
return parse_survey_data ($survey);
}
sub print_wireless_networks ($) {
my $aps = shift;
print "Detected wireless networks:\n";
my $format = " %3s %-25s%-9s%-13s%-17s%-8s\n";
printf $format, " ", "SSID", "Signal", "Security", "Type", "channel";
print "\t------------------------------------------------------------------------\n";
my $i = 0;
foreach my $ssid (sort {lc $a cmp lc $b} keys (%$aps)) {
++$i;
my $network = $aps->{$ssid};
printf $format, $i.")", $ssid, $network->{'signal'},
security2string ($network->{'secmode'}),
$network->{'adhoc'}?"Ad-Hoc":"Infrastructure",
$network->{'channel'};
}
print "\n";
}
###############################################################################
## INFRASTRUCTURE WIRELESS SETUP (i.e. wlan through access point / router)
###############################################################################
sub wifi_ask_ssid ($) {
my $dev = shift;
my $aps = scan_for_aps ($dev);
print_wireless_networks ($aps);
my @ssids = (sort {lc $a cmp lc $b} keys (%$aps));
my $newssid;
print "Please enter the number or the SSID of the desired wireless network.\n";
print "\tEnter '0', 'hidden' or 'h' to connect to a hidden network.\n";
print "\tEnter 'r' or 'rescan' to rescan for wireless networks.\n";
do {
$newssid = input ("Desired wireless network: ");
return $newssid if (exists $aps->{$newssid});
if ($newssid =~ /^[1-9]\d*$/ && ($newssid <= scalar(@ssids))) {
return ($aps,$ssids[$newssid-1]);
}
if ($newssid eq "0" || $newssid eq "h" || $newssid eq "hidden") {
$newssid = "";
while (length($newssid) < 1) {
$newssid = input ("Please enter the SSID: ");
}
return ($aps,$newssid);
}
if ($newssid eq "r" || $newssid eq "rescan") {
return wifi_ask_ssid ($dev);
}
} while 1; # We'll jump out of the loop via return!
}
sub wifi_ask_address ($$) {
my $ap = shift;
my $aps = shift;
my $dhcp = ask_choice ("IP-address assignment:", ["DHCP", "Manual"], ["Enable", "Disable"], "Enable");
my %result = ("dhcp" => $dhcp);
if ($dhcp ne "Enable") {
$result{'ip_addr'} = ask_ip_address ("IP-address of the device:\t");
$result{'mask'} = ask_ip_address ("Netmask:\t");
$result{'gateway'} = ask_ip_address ("IP-address of the gateway:\t");
} else {
$result{'ip_addr'} = "0.0.0.0";
$result{'mask'} = "0.0.0.0";
$result{'gateway'} = "0.0.0.0";
}
return %result;
}
sub wifi_ask_security ($$) {
my $ap = shift;
my $aps = shift;
my %result = ();
my $sec = 0;
if (defined $aps->{$ap}) {
$sec = $aps->{$ap}->{'secmode'};
$result{'channel'} = $aps->{$ap}->{'channel'};
}
$sec = ask_choice ("Security: ", ["None", -1, "WEP", "WPA-PSK", "WPA2-PSK", "WPA/WPA2-PSK"], ['0', '1', '2', '4', '6'], $sec);
$result{'secmode'} = $sec;
if ($sec == 0) {
# No encryption, nothing to ask the user
} elsif ($sec == 1) {
# WEP
progress "Using WEP security\n";
$result{'authen'} = ask_choice ("Type of authentication:", ["Open System","Shared Key"], ['1','2'], '1');
$result{'key'} = ask_wep_key ($ap);
$result{'key_len'} = length ($result{'key'})/2;
} elsif ($sec == 2 || $sec == 4 || $sec == 6 || $sec == 7) {
# WPA1 / WPA2
progress "Using %s security\n", security2string($sec);
$result{'pskalset'} = ask_choice ("Type of encryption:", ["TKIP", "AES"], ['0','1'], '0');
$result{'pskkey'} = ask_input ("Please enter the WPA passphrase for network '$ap': ",
\&is_wpa_passphrase, "\tEnter a passprase with 1-63 characters!\n");
} else {
printf "ERROR: security type %s not supported\n", security2string($sec);
return wifi_ask_security ($ap, $aps);
}
return %result;
}
sub wifi_config_create ($) {
my $newconfig = shift;
my $config = [
......@@ -353,45 +191,6 @@ sub wifi_config_create ($) {
## AD-HOC WIRELESS SETUP (i.e. direct connection with print server and PC)
###############################################################################
sub adhoc_send_unknown_command ($) {
my $dev = shift;
bulk_data_write ($dev, "9971:\n", 6);
my $val = "";
bulk_data_read ($dev, $val, 1);
debug "\tResponse to 9971 Ad-hoc setting command (unknown purpose): %s\n", $val;
return $val;
}
sub adhoc_ask_ssid ($) {
my $dev = shift;
my $ssid = "";
print "\n";
do {
$ssid = input ("SSID of the ad-hoc wireless connection:");
if (length ($ssid) > 0) {
# scan for wireless networks to check for name clashes
my $aps = scan_for_aps ($dev);
if (defined ($aps->{$ssid})) {
print "\tERROR: wireless network '$ssid' already exists, please choose a different name.\n\n";
} else {
return $ssid;
}
}
} while 1; # We'll jump out of the loop via return!
}
def adhoc_ask_channel (ap):
channel = False
while (!channel):
c = input ("Wireless channel for network '%s' [auto or 0-13]: " % ap);
if (c == "auto"):
channel = "6" # FIXME
elif (re.match ('^([0-9]|1[0-3])$', c)):
channel = c
debug ("\tNew channel: %s\n" % channel)
return channel
sub adhoc_config_create ($) {
my $newconfig = shift;
my $config = [
......
......@@ -27,7 +27,7 @@ class Device:
capabilities = {}
def __init__ (self, ui):
self.ui = ui
self.capabilities = {'wifi': False, 'ad-hoc': False}
self.capabilities = {'wifi': False, 'ad-hoc': False, 'ip-address': False}
def device_string (self):
pass
......@@ -39,32 +39,51 @@ class Device:
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 command_send (self, cfg):
res = self.data_write (cfg, len(cfg))
return self.data_read (25600)
def config_retrieve (self):
self.ui.debug ("Reading current configuration...");
return self.command_send ("9100")
return self.command_send ("9100:\n")
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.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):
def data_write (self, data, length, timeout=500):
pass
def bulk_data_read (self, length, timeout=500):
def data_read (self, length, timeout=500):
pass
def device_reset (self):
pass
def scan_for_aps (self):
pass
self.ui.progress ("Scanning for access points", False)
loop = 0
found = False
survey = ''
while (not found and loop <= 4):
loop += 1
self.ui.debug ("loop=%d\n" % loop)
# trigger a WLAN scan
self.command_send ("9107:\n")
self.ui.sleep_progress (6)
cfg = self.config_retrieve ()
config = Config (self.ui, cfgstring=cfg)
survey = config.val('7021')
found = (survey and len(survey) > 0)
self.ui.progress ("")
if found:
self.ui.debug ("Found wireless networks: \n%s" % survey)
else:
self.ui.error ("No wireless networks detected.")
return parse_survey_data (survey)
def print_supported_devices (self):
pass
def error (self, msg):
......@@ -111,6 +130,7 @@ class USBDevice (Device):
Device.__init__ (self, ui)
self.capabilities['wifi'] = True
self.capabilities['ad-hoc'] = True
self.capabilities['ip-address'] = True
self.dev = dev
self.desc = desc
self.bus = bus
......@@ -149,8 +169,8 @@ class USBDevice (Device):
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)
res = self.command_send ("9002:\n")
self.ui.debug ("\tSent 9002 reset command: %s (len: %s)" % (res, len(res)))
# Poll the device until it doesn't respond. Then sleep for ~15 seconds
try:
i=0
......@@ -167,7 +187,7 @@ class USBDevice (Device):
self.device_close ()
self.ui.wait_enter ("Device was reset. Please press Return.")
def bulk_data_write (self, data, length, timeout=500):
def 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)
......@@ -179,7 +199,7 @@ class USBDevice (Device):
return res
# Read and return USB bulk data
def bulk_data_read (self, length, timeout=500):
def 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);
......@@ -225,17 +245,20 @@ import re
class Ether8888Packet:
ethHeaderFmt = "!6s6sH"
headerFmt = "<2s2s2sHH"
localAddr="\0\0\0\0\0\0"
remoteAddr="\xff\xff\xff\xff\xff\xff"
srcAddr="\0\0\0\0\0\0"
dstAddr="\xff\xff\xff\xff\xff\xff"
proto = 0x8888
zero = "\0\0"
def __init__ (self, localAddr="\x00\x00\x00\x00\x00\x00", remoteAddr="\xff\xff\xff\xff\xff\xff", proto=0x8888):
status = None
data = None
def __init__ (self, srcAddr="\x00\x00\x00\x00\x00\x00", dstAddr="\xff\xff\xff\xff\xff\xff", proto=0x8888):
self.proto = proto
self.localAddr = localAddr
self.remoteAddr = remoteAddr
self.srcAddr = srcAddr
self.dstAddr = dstAddr
def decode (self, data):
self.localAddr, self.remoteAddr, self.proto = struct.unpack(self.ethHeaderFmt,data[:14])
self.dstAddr, self.srcAddr, self.proto = struct.unpack(self.ethHeaderFmt,data[:14])
if self.proto != 0x8888:
# FIXME: Error message about invalid packet
return False
......@@ -244,16 +267,20 @@ class Ether8888Packet:
struct.unpack (self.headerFmt, self.ethData[:10])
self.payload = self.ethData[10:self.dataLen+10]
if (self.dataLen>2):
self.status = {"\0\0":True}.get( self.payload[:2])
if (self.dataLen != len (self.payload)):
# FIXME: Error message about invalid packet
return False
self.data = self.payload[2:]
return True
def encode (self, cmd, unknown, nrPackets, dataLen, data):
# Ethernet II header
(self.cmd, self.unknown, self.nrPackets, self.dataLen,self.payload) = (cmd, unknown, nrPackets, dataLen, data)
d = struct.pack(self.ethHeaderFmt, self.remoteAddr, self.localAddr, self.proto)
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
......@@ -261,7 +288,8 @@ class Ether8888Packet:
class Ether8888DeviceFactory (DeviceFactory):
supported_devices = (
{'desc':"Vonets VAP11G wireless bridge"},
{'id': '\x04\xE0\x54\x00', 'desc':"Vonets VAP11G wireless bridge"},
#{'id': '\x59\x4a\x34\x8c', 'desc':"HP2101nw Wireless USB print server (via WLAN)"},
);
proto=0x8888;
def __init__ (self):
......@@ -282,12 +310,12 @@ class Ether8888DeviceFactory (DeviceFactory):
# Create Ethernet II broadcast socket of ethertype 0x8888:
sockets = []
bcAddr = "\xFF\xFF\xFF\xFF\xFF\xFF";
bcAddr = "\xFF\xFF\xFF\xFF\xFF\xFF"
for i in interfaces:
s = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, self.proto)
s.bind((i,self.proto))
ifName,ifProto,pktType,hwType,hwAddr = s.getsockname()
packet = Ether8888Packet (localAddr = hwAddr, remoteAddr = bcAddr)
packet = Ether8888Packet (srcAddr = hwAddr, dstAddr = bcAddr)
request = packet.encode ("\0\0", "\0\0", 0, 0, "\0"*0x10)
# Send and wait for response
s.send (request)
......@@ -300,9 +328,31 @@ class Ether8888DeviceFactory (DeviceFactory):
for sock in sread:
rxFrame = sock.recv (1500)
pack = Ether8888Packet()
if pack.decode (rxFrame) and (not pack.remoteAddr == bcAddr):
ifName,ifProto,pktType,hwType,hwAddr = sock.getsockname()
devices.append (Ether8888Device (ui, ifName, ifProto, pack.localAddr, "Vonets VAP11G wireless bridge"));
# Decode frame and filter out all broadcasts (in case we have a
# loop, e.g. because the device is already connected to the WLAN
# and so all packages sent over eth0 will be received via the wlan
# bridge on the wireless interface!)
if (not pack.decode (rxFrame)):
ui.error ("decoding response packet of device detection")
continue
is_broadcast = (pack.srcAddr == bcAddr) and (pack.dstAddr == bcAddr)
if is_broadcast:
ui.debug ("Received broadcast package instead of response:")
ui.hex_print (rxFrame)
continue
ifName,ifProto,pktType,hwType,hwAddr = sock.getsockname()
devdesc = None
for d in self.supported_devices:
if d['id'] == pack.data[2:6]:
devdesc = d['desc']
break
else:
ui.hex_print (pack.srcAddr)
ui.progress ("Response received from unknown device (id {}, MAC {}, interface {})".format (formatHex2 (pack.data[2:6]), formatMAC (pack.srcAddr), ifName))
continue
ui.debug ("Received response packet:")
ui.hex_print (rxFrame)
devices.append (Ether8888Device (ui, ifName, ifProto, pack.srcAddr, devdesc, localAddr = pack.dstAddr));
for s in sockets:
s.close ();
......@@ -325,20 +375,29 @@ class Ether8888Device (Device):
proto = 0x8888;
desc = ""
socket = None
def __init__ (self, ui, iface, proto, mac, desc):
cmds = {'dev_info': "\x00\x00",
'dev_stat': "\x00\x01",
'send_data': "\x01\x01",
'recv_data': "\x02\x01"}
def __init__ (self, ui, iface, proto, mac, desc,localAddr = ""):
Device.__init__ (self, ui);
self.ifName = iface
self.mac = mac
self.proto = proto
self.desc = desc
self.srcAddr = None
self.destAddr = None
self.localAddr = localAddr
self.remoteAddr = mac
self.capabilities['wifi'] = True;
self.capabilities['ad-hoc'] = False;
self.ui.debug("localAddr: ")
self.ui.hex_print (self.localAddr)
self.ui.debug("remoteAddr: ")
self.ui.hex_print (self.remoteAddr)
def device_string (self):
return "%s (Ethernet interface %s, MAC %12s)" % (
self.desc, self.ifName, ':'.join('%02x' % ord(b) for b in self.mac));
self.desc, self.ifName, formatMAC (self.mac));
def device_open (self):
try:
......@@ -350,7 +409,7 @@ class Ether8888Device (Device):
self.error ("Error opening socket for device '%s' on interface '%s'; message: %s" % (self.desc, self.ifName, e.message))
s.close ()
return False
self.ui.progress ("Successfully opened socket for device '%s' on interface '%s'" % (self.desc, self.ifName))
self.ui.debug ("Successfully opened socket for device '%s' on interface '%s'" % (self.desc, self.ifName))
return True;
def device_close (self):
......@@ -360,69 +419,87 @@ class Ether8888Device (Device):
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)
res = self.command_send ("9002:\n")
self.ui.debug ("\tSent 9002 reset command; response: %s (len: %d)" % (res, len(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, cmd="\x01\x01", unknown="\0\0"):
packet = Ether8888Packet (localAddr = self.localAddr, remoteAddr = self.remoteAddr)
request = packet.encode (cmd, unknown, 0, length, data)
self.ui.debug ("Request: " + request)
def raw_write (self, data):
res = None
try:
res = self.socket.send (request)
res = self.socket.send (data)
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 ''
def raw_read (self, length=15000, timeout=500):
self.ui.debug ("raw_read")
toread = 1 # Nr of remaining packets to read
data = None
while (toread>0):
(sread, swrite, sx) = select.select([self.socket], [], [], timeout/1000)
for sock in sread:
rxFrame = sock.recv (length)
toread -= 1
pack = Ether8888Packet(self.remoteAddr, self.localAddr, self.proto)
if pack.decode (rxFrame):
#self.ui.debug ("Complete returned data frame:")
#self.ui.hex_print (rxFrame)
toread = pack.nrPackets
if (not data):
data = ""
data += pack.data
else:
self.error ("decoding returned data: %s" % rxFrame)
self.ui.debug ("Unable to decode the %d bytes returned: \n" % len (rxFrame))
self.ui.hex_print (rxFrame)
if (len (sread) == 0 ):
self.error ("reading data, no response received")
toread = 0
#self.ui.debug ("Complete returned data:")
#self.ui.hex_print (data)
return data
def data_write (self, data, length, cmd=None, unknown="\x01\x00"):
self.ui.debug("data_write %d, %s"%(length, data))
if not cmd:
cmd = self.cmds.get('send_data')
packet = Ether8888Packet (srcAddr = self.localAddr, dstAddr = self.remoteAddr)
request = packet.encode (cmd, unknown, 0, length, data)
self.ui.debug ("Request: " + request)
res = self.raw_write (request)
time.sleep(1)
return self.raw_read ()
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:]
# Read and return USB bulk data
def data_read (self, length, timeout=500):
self.ui.debug("data_read %d"%length)
# TODO: Request return data
packet = Ether8888Packet (srcAddr = self.localAddr, dstAddr = self.remoteAddr)
request = packet.encode (self.cmds.get('recv_data'), "\x02\x00", 0, 0, "")
res = self.raw_write (request)
time.sleep (1)
return self.raw_read (length, timeout)
TODO:
def command_send (self, cmd):
cfg = "%s:\n" % cmd
res = self.bulk_data_write (cfg, len(cfg), cmd="\x01\x01", unknown="\0\0")
return self.bulk_data_read (25600)
def command_send (self, cfg):
res = self.data_write (cfg, len(cfg), cmd=self.cmds.get('send_data'), unknown="\1\0")
return self.data_read (25600)
def config_retrieve (self):
self.ui.debug ("Reading current configuration...");
return self.command_send ("9100")
return self.command_send ("9100:\n")
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), cmd="\0x02)
self.command_send (cfgstring)
self.ui.sleep_progress (10)
# Now reset the device:
return self.device_reset ()
......
......@@ -47,4 +47,30 @@ def find(f, seq):
"""Return first item in sequence where f(item) == True."""
for item in seq:
if f(item):
return item
\ No newline at end of file
return item
def formatMAC(m):
return ':'.join('%02x' % ord(b) for b in m)
def formatHex2(d):
return "0x" + " ".join ('%02x' % ord(b) for b in d)
def parse_survey_data (survey):
networks = {}
entries = filter (None, survey.split ("\x0b"))
for e in entries:
(ssid, settings) = e.split ("\x0c")
settings = settings.split (",")
# If device doesn't support ad-hoc, settings has only 4 entries => add dummy
if len(settings)<6:
settings.append (None)
networks[ssid] = {
'mac': settings[0],
'channel': settings[1],
'wifi_ver':settings[2],
'secmode': settings[3],
'signal' : settings[4],
'adhoc': settings[5]
}
return networks
......@@ -43,8 +43,28 @@ class UserInterface:
pass
def display_device_settings (self):
pass
def print_wireless_networks (self):
pass
# Print a table of available wifi networks
def print_wireless_networks (self, aps):
pass
# Request a wifi network from the user. First, show the table of APs,
# then ask. It's also possible to let the user enter the SSID of a hidden
# network.
def ask_wireless_ap (self, aps):
pass
# Request IP Address settings (DHCP, IP, netmask, gateway); returns a dict
def ask_IP_setting (self):
dhcp = self.ask_choice ("IP-address assignment:", ["DHCP", "Manual"], ["Enable", "Disable"], "Enable");
result = {"dhcp": dhcp}
if (dhcp == "Enable");
result['ip_addr'] = self.ask_ip_address ("IP-address of the device:")
result['mask'] = self.ask_ip_address ("Netmask:")
result['gateway'] = self.ask_ip_address ("IP-address of the gateway:")
else:
result['ip_addr'] = "0.0.0.0"
result['mask'] = "0.0.0.0"
result['gateway'] = "0.0.0.0"
return result
def ask_operation (self):
pass
def ask_ip_address (self, string):
......@@ -85,12 +105,12 @@ class ConsoleInterface (UserInterface):
if (i % 8 == 0):
line += " "
if (i % 16 == 0):
print ("0x%04x %34s %16s" % (index, line, readable))
print ("{:#06x} {:<50} {:<16}".format (index, line, readable))
index += 0x10;
readable = ""
line = ""
if (len (line) > 0):
print ("0x%04x %34s %16s" % (index, line, readable))
print ("{:#06x} {:<50} {:<16}".format (index, line, readable))
sys.stdout.flush()
def input (self, str):
......@@ -150,8 +170,6 @@ class ConsoleInterface (UserInterface):
def display_device_settings (self):
pass
def print_wireless_networks (self):
pass
def ask_operation (self):
pass
......@@ -165,4 +183,60 @@ class ConsoleInterface (UserInterface):
"\tInvalid key %s. Length can only be 10 or 26, use only digits 0-9 and letters a-f.\n\n")
def wait_enter (self, text):
raw_input (text)
\ No newline at end of file
raw_input (text)
def print_wireless_networks (self, aps):
fmt = " %3s %-25s%-9s%-13s%-17s%-8s\n"
msg = "Detected wireless networks:\n"
msg += fmt % (" ", "SSID", "Signal", "Security", "Type", "channel")
msg += "\t------------------------------------------------------------------------\n"
i = 0
ssids = aps.keys()
ssids.sort (key=str.lower)
for ssid in ssids:
i += 1
network = aps.get (ssid, {})
msg += fmt % (str(i)+")", ssid, network.get ('signal', ''),
security2string (network.get ('secmode', '')),
"Ad-Hoc" if network.get ('adhoc', None) else "Infrastructure",
network.get ('channel', ''))
print msg
def ask_wireless_ap (self, aps):
self.print_wireless_networks (aps)
ssids = aps.keys()
ssids.sort (key=str.lower)
print "Please enter the number or the SSID of the desired wireless network."
print "\tEnter '0', 'hidden' or 'h' to connect to a hidden network."
print "\tEnter 'r' or 'rescan' to rescan for wireless networks."
newssid = None
while (not newssid):
newssid = self.input ("Desired wireless network: ")
print "Newssid=%s" % newssid
if aps.get (newssid):
print "Known SSID %s" % newssid
return newssid
if (newssid == 'h' or newssid == 'hidden' or newssid == '0'):
newssid = ''
while (not newssid):
newssid = self.input ("Please enter the hidden network name:")
return newssid
if (newssid == 'r' or newssid == 'rescan'):
print "Rescan (%s)" % newssid
return None
try:
i = int(newssid)
print "int %s = %d" % (newssid,i)
if (i>0 and i<len(ssids)):
print "In range"
return ssids[i-1]
else:
print "Not in range"
except Exception, e:
print e.message
return self.ask_wireless_ap (aps)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment