Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
H
HP_2101nw
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Kainhofer
HP_2101nw
Commits
82fa7d01
Commit
82fa7d01
authored
13 years ago
by
Reinhold Kainhofer
Browse files
Options
Downloads
Patches
Plain Diff
hp2101nw_connect.pl: Send/receive broadcasts, get MAC; basic communication functions
parent
94e3e276
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
hp2101nw_connect.pl
+208
-615
208 additions, 615 deletions
hp2101nw_connect.pl
with
208 additions
and
615 deletions
hp2101nw_connect.pl
+
208
−
615
View file @
82fa7d01
...
@@ -32,7 +32,10 @@ use strict;
...
@@ -32,7 +32,10 @@ use strict;
our
$debug
=
1
;
our
$debug
=
1
;
our
$VERSION
=
0.01
;
our
$VERSION
=
0.01
;
# Wait a maximum of 5 seconds for data:
our
$SOCK_TIMEOUT
=
5
;
print
"
hp2101nw_connect.pl - version
$VERSION
\n
";
print
"
hp2101nw_connect.pl - version
$VERSION
\n
";
print
"
Linux connection utility for the HP 2101nw wireless G USB print server.
\n\n
";
print
"
Linux connection utility for the HP 2101nw wireless G USB print server.
\n\n
";
print
"
(C) 2012 Reinhold Kainhofer <reinhold
\@
kainhofer.com>
\n
";
print
"
(C) 2012 Reinhold Kainhofer <reinhold
\@
kainhofer.com>
\n
";
...
@@ -157,6 +160,38 @@ sub ask_input ($$$) {
...
@@ -157,6 +160,38 @@ sub ask_input ($$$) {
return
$retval
;
return
$retval
;
}
}
###############################################################################
## DEVICE CONFIGURATION HANDLING
###############################################################################
sub
config_parse
($)
{
my
$cfg
=
shift
;
my
@entries
=
split
('
\n
',
$cfg
);
my
@config
=
();
foreach
(
@entries
)
{
my
$key
=
substr
(
$_
,
0
,
4
);
(
my
$name
,
my
$value
)
=
split
(
/:/
,
substr
(
$_
,
5
),
2
);
push
(
@config
,
[
$key
,
$name
,
$value
]);
}
return
@config
;
}
# Convert a list of the form [ ["OPTIONID", "OPTIONNAME", VALUE], ...]
# into a string to be sent to the device
sub
config_create
($)
{
my
$cfg
=
shift
;
my
$result
=
"";
foreach
my
$o
(
@$cfg
)
{
if
(
$o
->
[
0
]
&&
length
(
$o
->
[
0
])
>
0
)
{
$result
.=
sprintf
("
%s %s:%s
\n
",
$o
->
[
0
],
$o
->
[
1
],
$o
->
[
2
]);
}
else
{
$result
.=
sprintf
("
%s:%s
\n
",
$o
->
[
1
],
$o
->
[
2
]);
}
}
return
$result
;
}
########################
########################
# validation functions
# validation functions
...
@@ -180,601 +215,231 @@ sub is_hostname ($) {
...
@@ -180,601 +215,231 @@ sub is_hostname ($) {
###############################################################################
sub
config_parse
($)
{
## USB DEVICE MANAGEMENT / COMMUNICATION FUNCTIONS
my
$cfg
=
shift
;
###############################################################################
my
@entries
=
split
('
\n
',
$cfg
);
my
@config
=
();
sub
setup_ports
(
)
{
foreach
(
@entries
)
{
#
my $
io_information = IO::Socket::INET->new(LocalPort => $port_information,
my
$
key
=
substr
(
$_
,
0
,
4
);
#
Proto => "udp"
);
(
my
$name
,
my
$value
)
=
split
(
/:/
,
substr
(
$_
,
5
),
2
);
#
my $io_sbsu = IO::Socket::INET->new(LocalPort => $port_command,
push
(
@config
,
[
$key
,
$name
,
$value
]);
# Proto => "udp");
}
#
return
@config
;
}
}
sub
SBSU_create_buffer
($)
{
# Convert a list of the form [ ["OPTIONID", "OPTIONNAME", VALUE], ...]
my
$cmd
=
shift
;
# into a string to be sent to the device
return
sprintf
("
SBSU%s
",
pack
("
v
",
$cmd
));
sub
config_create
($)
{
my
$cfg
=
shift
;
my
$result
=
"";
foreach
my
$o
(
@$cfg
)
{
if
(
$o
->
[
0
]
&&
length
(
$o
->
[
0
])
>
0
)
{
$result
.=
sprintf
("
%s %s:%s
\n
",
$o
->
[
0
],
$o
->
[
1
],
$o
->
[
2
]);
}
else
{
$result
.=
sprintf
("
%s:%s
\n
",
$o
->
[
1
],
$o
->
[
2
]);
}
}
return
$result
;
}
}
# Read data into the second argument (output argument!), return
# size of data
sub
SBSU_receive_data
($$$)
{
my
$sock
=
shift
;
my
$cmd
=
shift
;
}
sub
SBSU_status_parse
($)
{
###############################################################################
## USB DEVICE MANAGEMENT / COMMUNICATION FUNCTIONS
###############################################################################
sub
net_send_data
($$)
{
my
$sock
=
shift
;
my
$data
=
shift
;
return
$sock
->
send
(
$data
,
0
)
or
print
"
Error sending data to socket
$sock
. Data was:
\n
$data
\n
";
}
}
sub
device_detect
()
{
sub
net_read_data
($)
{
my
$request
=
SBSU_create_buffer
(
$SBSU_STATUS
);
my
$sock
=
shift
;
my
@result
=
();
my
$sel
=
IO::
Select
->
new
(
$sock
);
my
$loop
=
0
;
my
$data
=
undef
;
debug
"
Sending device detection request (UDP broadcast on port 34447)
\n
";
my
$br_addr
=
sockaddr_in
(
$port_command
,
INADDR_BROADCAST
);
my
$broadcast
=
IO::Socket::
INET
->
new
(
PeerPort
=>
$port_command
,
# PeerAddr => inet_ntoa(INADDR_BROADCAST),
Proto
=>
'
udp
',
# Listen => 1,
Broadcast
=>
1
)
or
die
"
Can't bind broadcast socket: $@
\n
";
my
$sel
=
IO::
Select
->
new
(
$broadcast
);
while
(
++
$loop
<=
5
&&
scalar
(
@result
)
<
5
)
{
if
(
$sel
->
can_read
(
$SOCK_TIMEOUT
))
{
print
"
.
";
$sock
->
recv
(
$data
,
10240
);
$broadcast
->
send
(
$request
,
0
,
$br_addr
)
# # printf "net_read_data: %d bytes read\n", $len;
or
die
"
Error at sending: $!
\n
";
return
$data
;
while
(
$sel
->
can_read
(
1
))
{
}
else
{
my
$data
=
"";
debug
"
Unable to read data from socket
$sock
.
\n
";
$broadcast
->
recv
(
$data
,
8096
);
return
$data
;
push
@result
,
$data
;
}
}
}
print
"
\n
Result:
@result
\n
";
return
@result
;
}
}
sub
device_info
($)
{
sub
SBSU_create_buffer
($)
{
my
$
ip
=
shift
()
;
my
$
cmd
=
shift
;
return
sprintf
("
SBSU%s
",
pack
("
v
",
$cmd
));
}
}
sub
create_status_request
()
{
# Read data into the second argument (output argument!), return
}
# size of data
sub
SBSU_receive_data
($$$)
{
my
$sock
=
shift
;
my
$cmd
=
shift
;
sub
device_open
($)
{
my
$dev
=
shift
;
my
$res
=
$dev
->
open
;
if
(
$res
<
0
)
{
printf
"
ERROR opening device (%d): %s
\n
",
$res
,
$!
;
}
$res
=
$dev
->
detach_kernel_driver_np
(
0
);
# No error check, Linux always gives an error!
$res
=
$dev
->
set_configuration
(
1
);
if
(
$res
<
0
)
{
printf
"
ERROR setting configuration 1 (%d): %s
\n
",
$res
,
$!
;
}
$res
=
$dev
->
claim_interface
(
0
);
if
(
$res
<
0
)
{
printf
"
ERROR claiming interface 0 (%d): %s
\n
",
$res
,
$!
;
}
}
}
sub
device_clos
e
($)
{
sub
info_data_writ
e
($
$
)
{
my
$dev
=
shift
;
my
$dev
=
shift
;
$dev
->
release_interface
(
0
);
my
$cfg
=
shift
;
$dev
->
reset
;
}
sub
bulk_data_write
($$$)
{
my
$sock
=
$dev
->
{'
socket-info
'};
my
$dev
=
shift
;
my
$cfgstring
=
config_create
(
$cfg
);
my
$data
=
shift
;
my
$len
=
length
(
$cfgstring
);
my
$len
=
shift
;
# Add the header (12 bytes): '@\0', packet length, boxname
# Add the header (12 bytes): '@\0', packet length, boxname (="XXXXXXXX")
my
$request
=
sprintf
("
@
\
0%s%s%s
",
pack
("
v
",
$len
),
$dev
->
{'
device-name
'},
$cfgstring
);
my
$request
=
sprintf
("
@
\
0%s%s%s
",
pack
("
v
",
$len
),
$thisboxname
,
$data
);
return
net_send_data
(
$sock
,
$request
);
debug
"
Request:
$request
\n
";
my
$res
=
$dev
->
bulk_write
(
1
,
$request
,
length
(
$request
),
500
);
if
(
$res
<
0
)
{
printf
"
ERROR write bulk data (%d): %s
\n
",
$res
,
$!
;
}
return
$res
;
}
}
# Read USB bulk data into the second argument (output argument!), return
# Read USB bulk data into the second argument (output argument!), return
# size of data
# size of data
sub
bulk
_data_read
($
$$
)
{
sub
info
_data_read
($)
{
my
$dev
=
shift
;
my
$dev
=
shift
;
# TODO: Get rid of the length argument, simply read all that is sent
# FIXME: Read bulk data in loops until there is nothing left to read?
my
$len
=
$_
[
1
];
my
$readdata
=
"";
my
$res
=
$dev
->
bulk_read
(
2
,
$readdata
,
$len
+
13
,
500
);
if
(
$res
<
0
)
{
printf
"
ERROR reading bulk data (%d): %s
\n
",
$res
,
$!
;
return
;
}
if
(
$res
==
0
)
{
debug
"
\t
Empty response received
\n
";
return
0
;
}
debug
("
read %d bytes:
\n
%s
\n\n
",
$res
,
$readdata
);
# Check and cut off the header after some sanity checks:
if
(
substr
(
$readdata
,
0
,
3
)
ne
"
\@\
0
\
0
")
{
printf
"
ERROR reading data: Wrong header %s
\n
",
substr
(
$readdata
,
0
,
3
);
}
my
$datalen
=
unpack
("
v
",
substr
(
$readdata
,
3
,
2
));
$res
=
$res
-
13
;
if
(
$datalen
!=
$res
)
{
printf
"
ERROR reading data: Expected %d bytes of data, got %d
\n
",
$datalen
,
$res
;
}
my
$boxname
=
substr
(
$readdata
,
5
,
8
);
# FIXME: Check the name of the box...
# cut off the header:
$_
[
0
]
=
substr
(
$readdata
,
13
);
return
$res
;
}
sub
device_reset
($)
{
my
$dev
=
shift
;
progress
"
Resetting the device, please wait
";
my
$res
=
bulk_data_write
(
$dev
,
"
9002:
\n
",
6
);
debug
"
\t
Sent 9002 reset command: %d
\n
",
$res
;
my
$reset_done
=
0
;
# Poll the device until it doesn't respond. Then sleep for ~15 seconds
do
{
my
$readdata
=
"";
$res
=
$dev
->
bulk_read
(
2
,
$readdata
,
13
,
100
);
debug
"
\t
Data received:
$readdata
(len:
$res
)
\n
";
sleep
(
1
);
}
while
(
$res
>
0
);
sleep_progress
(
20
);
device_close
(
$dev
);
progress
"
Device was reset. Please press Return.
";
<
STDIN
>
;
}
###############################################################################
## DEVICE CONFIGURATION HANDLING
###############################################################################
my
$sock
=
$dev
->
{'
socket-info
'};
sub
print_current_configuration
($$)
{
my
$data
=
net_read_data
(
$sock
);
my
$config
=
shift
;
my
$datalen
=
length
(
$data
);
my
$text
=
shift
;
if
(
substr
(
$data
,
0
,
3
)
ne
"
@
\
0
\
0
")
{
sub
val
($$)
{
printf
"
ERROR reading data: Wrong header '%s', expected @
\\
0
\\
0
\n
",
substr
(
$data
,
0
,
3
);
my
$config
=
shift
;
my
$var
=
shift
;
foreach
my
$e
(
@$config
)
{
return
$e
->
[
2
]
if
(
$e
->
[
0
]
eq
$var
);
}
return
undef
;
return
undef
;
}
}
progress
$text
;
# data length as given in the header:
printf
"
\t
Device name: %s
\n
",
val
(
$config
,
'
0001
');
my
$header_datalen
=
unpack
("
v
",
substr
(
$data
,
3
,
2
));
if
(
val
(
$config
,'
0012
')
ne
"
Enable
")
{
$datalen
=
$datalen
-
13
;
# ignore 13 bytes header
printf
"
\t
TCP/IP not yet configured and/or enabled.
\n\n
";
if
(
$header_datalen
!=
$datalen
)
{
return
;
printf
"
ERROR reading data: %d data bytes read, headers says %d bytes
\n
",
$datalen
,
$header_datalen
;
}
return
undef
;
my
$adhoc
=
val
(
$config
,'
7024
')
==
'
1
';
if
(
$adhoc
)
{
# ad-hoc network:
my
$sec
=
val
(
$config
,'
7103
');
printf
"
\t
Wireless mode: Ad-hoc network
\n
";
printf
"
\t
SSID: %s
\n
",
val
(
$config
,'
7100
');
printf
"
\t
Channel: %s
\n
",
val
(
$config
,'
7102
');
printf
"
\t
Security: %s
\n
",
security2string
(
$sec
);
if
(
$sec
==
0
)
{
# None => nothing to display
}
elsif
(
$sec
==
1
)
{
# WEP => Print passphrase
printf
"
\t
WEP Key: %s
\n
",
val
(
$config
,'
7106
');
}
else
{
# WPA 1/2 or mixed
printf
"
\t
Encryption: %s
\n
",
encryption2string
(
val
(
$config
,'
7118
'));
printf
"
\t
Passphrase: %s
\n
",
val
(
$config
,'
7119
');
}
}
else
{
# infrastructure network
my
$sec
=
val
(
$config
,'
7003
');
printf
"
\t
SSID: %s
\n
",
val
(
$config
,'
7000
');
printf
"
\t
Channel: %s
\n
",
val
(
$config
,'
7002
');
printf
"
\t
Security: %s
\n
",
security2string
(
$sec
);
if
(
$sec
==
0
)
{
# None => nothing to display
}
elsif
(
$sec
==
1
)
{
# WEP => Print passphrase
printf
"
\t
Authentication: %s
\n
",
authentication2string
(
val
(
$config
,'
7012
'));
printf
"
\t
WEP Key: %s
\n
",
val
(
$config
,'
7006
');
}
else
{
# WPA 1/2 or mixed
printf
"
\t
Encryption: %s
\n
",
encryption2string
(
val
(
$config
,'
7018
'));
printf
"
\t
Passphrase: %s
\n
",
val
(
$config
,'
7019
');
}
}
my
$dhcp
=
(
val
(
$config
,'
4020
')
eq
"
Enable
");
printf
"
\t
IPv4 method: %s
\n
",
$dhcp
?"
DHCP
":"
manual
";
my
$associated
=
val
(
$config
,'
7014
')
=~
m/STATE:Associated/
;
if
(
$associated
||
!
$dhcp
)
{
printf
"
\t
IP address: %s
\n
",
val
(
$config
,'
4000
');
printf
"
\t
Gateway: %s
\n
",
val
(
$config
,'
4001
');
printf
"
\t
Netmask: %s
\n
",
val
(
$config
,'
4002
');
}
if
(
$associated
)
{
my
$assinfo
=
val
(
$config
,'
7014
');
printf
"
\t
Link state: %s
\n
",
$assinfo
;
}
else
{
# Not connected
printf
"
\t
Wireless not connected
\n
";
}
}
print
"
\n\n
";
my
$boxname
=
substr
(
$data
,
5
,
8
);
}
# FIXME: Check the name of the box...
sub
device_config_request
($)
{
my
$dev
=
shift
;
my
$cfg
=
"";
debug
"
Reading current configuration...
\n
";
my
$res
=
bulk_data_write
(
$dev
,
"
9100:
\n
",
6
);
$res
=
bulk_data_read
(
$dev
,
$cfg
,
25600
);
return
$cfg
;
}
sub
device_config_send
($$)
{
my
$dev
=
shift
;
my
$cfg
=
shift
;
my
$tmp
=
"";
progress
"
Sending new configuation to the device. Please wait
";
debug
"
\t
New device config: %s
\n
",
$cfg
;
my
$res
=
bulk_data_write
(
$dev
,
$cfg
,
length
(
$cfg
));
sleep_progress
(
10
);
# Now reset the device:
return
device_reset
(
$dev
);
}
sub
config_parse
($)
{
# cut off the header:
my
$cfg
=
shift
;
return
substr
(
$data
,
13
);
my
@entries
=
split
('
\n
',
$cfg
);
my
@config
=
();
foreach
(
@entries
)
{
my
$key
=
substr
(
$_
,
0
,
4
);
(
my
$name
,
my
$value
)
=
split
(
/:/
,
substr
(
$_
,
5
),
2
);
push
(
@config
,
[
$key
,
$name
,
$value
]);
}
return
@config
;
}
}
# Convert a list of the form [ ["OPTIONID", "OPTIONNAME", VALUE], ...]
# into a string to be sent to the device
sub
config_create
($)
{
my
$cfg
=
shift
;
my
$result
=
"";
foreach
my
$o
(
@$cfg
)
{
$result
.=
sprintf
("
%s %s:%s
\n
",
$o
->
[
0
],
$o
->
[
1
],
$o
->
[
2
]);
}
return
$result
;
}
sub
set_hostname
($)
{
my
$dev
=
shift
;
my
$hostname
=
ask_input
("
New hostname:
",
\
&is_hostname
,
"
\t
A hostname can only contain A-Z, a-z, 0-9 and -, and may have 1 to 64 characters
\n
");;
my
$config
=
config_create
([["
0001
",
"
BOX_NAME
",
$hostname
]]);
debug
"
\t
Changing hostname using config
\n\t
%s
\n
",
$config
;
return
device_config_send
(
$dev
,
$config
);
}
sub
device_config_save
($$)
{
sub
SBSU_status_parse
($)
{
my
$filename
=
shift
;
my
$data
=
shift
;
my
$config
=
shift
;
my
$status
=
open
FILE
,
"
>
$filename
";
if
(
!
$status
)
{
printf
"
ERROR: %s
\n
",
$!
;
return
;
}
print
FILE
$config
;
progress
"
Current print server configuration saved to file '%s'
\n
",
$filename
;
}
sub
device_config_restore
($$)
{
if
(
substr
(
$data
,
0
,
6
)
ne
"
SBSU
\
1
\
0
")
{
my
$dev
=
shift
;
printf
"
ERROR reading data: Wrong header '%s', expected SBSU
\\
0
\\
1
\n
",
substr
(
$data
,
0
,
6
);
my
$filename
=
shift
;
return
undef
;
my
$status
=
open
FILE
,
"
<
$filename
";
if
(
!
$status
)
{
printf
"
ERROR: %s
\n
",
$!
;
return
;
}
}
my
$config
=
do
{
local
$/
;
<
FILE
>
};
debug
"
Configuration file '%s' contains the data:
\n
",
$filename
,
$config
;
progress
"
Loaded configuration data from file '%s', sending it to the device.
\n
";
return
device_config_send
(
$dev
,
$config
);
}
my
$result
=
{};
$result
->
{'
data
'}
=
$data
;
# TODO: what does byte 6 mean?
my
$devicename
=
substr
(
$data
,
7
,
8
);
$result
->
{'
device-name
'}
=
$devicename
;
$result
->
{'
printer-name
'}
=
substr
(
$data
,
22
,
64
);
$result
->
{'
locked-ip
'}
=
substr
(
$data
,
86
,
16
);
# TODO: Shall we call inet_aton on the string here?
$result
->
{'
locked-host
'}
=
substr
(
$data
,
102
,
8
);
# TODO: 8 or 10 bytes
# TODO: Bytes 112-168
$result
->
{'
serial
'}
=
unpack
("
V
",
substr
(
$data
,
168
,
4
));
$result
->
{'
vendor-id
'}
=
unpack
("
v
",
substr
(
$data
,
172
,
2
));
$result
->
{'
device-id
'}
=
unpack
("
v
",
substr
(
$data
,
174
,
2
));
###############################################################################
$result
->
{'
usb-descriptors
'}
=
substr
(
$data
,
176
);
## 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
print_wireless_networks
($)
{
return
$result
;
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
";
}
}
sub
device_detect
()
{
my
$request
=
SBSU_create_buffer
(
$SBSU_STATUS
);
my
$result
=
{};
my
$loop
=
0
;
debug
"
Sending device detection request (UDP broadcast on port 34447)
\n
";
# I can't add the broadcast address to the IO::Socket::INET, because
# the response will not be from the broadcast address and thus it
# would not be detected. Rather, I'll have to add the PeerAddress
# directly in the send command, so that the recv command does
# not do any peer address matching. It will then correctly receive
# the responses from any responding device.
my
$br_addr
=
sockaddr_in
(
$port_command
,
INADDR_BROADCAST
);
my
$broadcast
=
IO::Socket::
INET
->
new
(
PeerPort
=>
$port_command
,
Proto
=>
'
udp
',
Broadcast
=>
1
)
or
die
"
Can't bind broadcast socket: $@
\n
";
my
$sel
=
IO::
Select
->
new
(
$broadcast
);
###############################################################################
while
(
++
$loop
<=
3
&&
scalar
(
%$result
)
<
5
)
{
## INFRASTRUCTURE WIRELESS SETUP (i.e. wlan through access point / router)
print
"
.
";
###############################################################################
$broadcast
->
send
(
$request
,
0
,
$br_addr
)
or
die
"
Error at sending: $!
\n
";
while
(
$sel
->
can_read
(
1
))
{
sub
wifi_ask_ssid
($)
{
my
$data
=
"";
my
$dev
=
shift
;
$broadcast
->
recv
(
$data
,
8096
);
my
$aps
=
scan_for_aps
(
$dev
);
my
$found
=
SBSU_status_parse
(
$data
);
print_wireless_networks
(
$aps
);
if
(
$found
)
{
my
@ssids
=
(
sort
{
lc
$a
cmp
lc
$b
}
keys
(
%$aps
));
$found
->
{'
ip
'}
=
$broadcast
->
peerhost
();
my
$newssid
;
# Setup the sockets
print
"
Please enter the number or the SSID of the desired wireless network.
\n
";
$result
->
{
$found
->
{'
device-name
'}}
=
$found
;
print
"
\t
Enter '0', 'hidden' or 'h' to connect to a hidden network.
\n
";
print
"
\t
Enter 'r' or 'rescan' to rescan for wireless networks.
\n
";
do
{
print
"
Desired wireless network:
";
$newssid
=
input
();
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
)
{
print
"
Please enter the SSID:
";
$newssid
=
input
();
}
}
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
;
foreach
(
keys
%$result
)
{
}
# Setup the udp sockets:
my
$peer
=
$result
->
{
$_
}
->
{'
ip
'};
$result
->
{
$_
}
->
{'
socket-info
'}
=
IO::Socket::
INET
->
new
(
PeerAddr
=>
$peer
,
PeerPort
=>
$port_information
,
Proto
=>
'
udp
'
);
$result
->
{
$_
}
->
{'
socket-config
'}
=
IO::Socket::
INET
->
new
(
PeerAddr
=>
$peer
,
PeerPort
=>
$port_command
,
Proto
=>
'
udp
'
);
sub
wifi_ask_security
($$)
{
info_data_write
(
$result
->
{
$_
},
[[
undef
,
"
9801
",
"
"]]);
my
$ap
=
shift
;
$result
->
{
$_
}
->
{'
mac
'}
=
info_data_read
(
$result
->
{
$_
});
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
,
"
\t
Enter 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
;
return
$result
;
}
sub
wifi_config_create
($)
{
my
$newconfig
=
shift
;
my
$config
=
[
["
4000
",
"
IP_ADDR
",
$newconfig
->
{'
ip_addr
'}],
# IP-address
["
4001
",
"
GATEWAY
",
$newconfig
->
{'
gateway
'}],
["
4002
",
"
MASK
",
$newconfig
->
{'
mask
'}],
["
4020
",
"
DHCP_MODE
",
$newconfig
->
{'
dhcp
'}],
["
4021
",
"",
$newconfig
->
{'
dhcp
'}],
# Unknown, == 4020
["
4022
",
"",
$newconfig
->
{'
dhcp
'}],
# Unknown, == 4020
["
5000
",
"",
""],
# Unknown, always empty
["
5003
",
"",
""],
# Unknown, always empty
["
5101
",
"",
""],
# Unknown, always empty
["
5102
",
"",
""],
# Unknown, always empty
["
5104
",
"",
""],
# Unknown, always empty
["
5103
",
"",
""],
# Unknown, always empty
["
7000
",
"
SSID
",
$newconfig
->
{'
SSID
'}],
["
7001
",
"
DOMAIN
",
""],
["
7002
",
"
CHANNEL
",
$newconfig
->
{'
channel
'}],
["
7003
",
"
SECMODE
",
$newconfig
->
{'
secmode
'}],
["
7004
",
"
KEY_LEN
",
$newconfig
->
{'
key_len
'}],
["
7005
",
"
DEFAULTKEY
","
0
"],
["
7006
",
"
KEY0
",
$newconfig
->
{'
key
'}],
["
7007
",
"
KEY1
",
""],
["
7008
",
"
KEY2
",
""],
["
7009
",
"
KEY3
",
""],
["
7012
",
"
AUTHEN
",
$newconfig
->
{'
authen
'}],
["
7013
",
"
MODE
",
"
0
"],
["
7018
",
"
PSKALSET
",
$newconfig
->
{'
pskalset
'}],
["
7019
",
"
PSKKEY
",
$newconfig
->
{'
pskkey
'}],
["
7024
",
"
STAMODE
",
"
0
"],
["
7025
",
"
APCHANNEL
",
"
5
"],
["
7026
",
"
CHMODE
",
"
1
"],
["
7030
",
"
WLMODE
",
"
0
"],
];
return
config_create
(
$config
);
}
}
sub
device_select
($)
{
my
$devs
=
shift
;
###############################################################################
my
@d
=
();
## AD-HOC WIRELESS SETUP (i.e. direct connection with print server and PC)
my
@dn
=
();
###############################################################################
my
$format
=
"
%-18s%-15s%-30s
";
foreach
my
$dd
(
keys
%$devs
)
{
my
$devinfo
=
$devs
->
{
$dd
};
push
@d
,
sprintf
(
$format
,
$devinfo
->
{'
device-name
'},
$devinfo
->
{'
ip
'},
$devinfo
->
{'
printer-name
'});
push
@dn
,
$dd
;
}
my
$text
=
"
The following devices were found:
\n\n\t
"
.
sprintf
(
$format
,
"
Device
",
"
IP
",
"
Detected printer
")
.
"
\n
"
.
"
\t
------------------------------------------------------------------------
";
if
(
scalar
(
@d
)
==
1
)
{
print
$text
;
print
@d
[
0
];
}
else
{
return
ask_choice
(
$text
,
sub
adhoc_send_unknown_command
($)
{
\
@d
,
my
$dev
=
shift
;
\
@dn
,
bulk_data_write
(
$dev
,
"
9971:
\n
",
6
);
@dn
[
0
]
my
$val
=
"";
);
bulk_data_read
(
$dev
,
$val
,
1
);
}
debug
"
\t
Response 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
{
print
"
SSID of the ad-hoc wireless connection:
";
$ssid
=
input
();
if
(
length
(
$ssid
)
>
0
)
{
# scan for wireless networks to check for name clashes
my
$aps
=
scan_for_aps
(
$dev
);
if
(
defined
(
$aps
->
{
$ssid
}))
{
print
"
\t
ERROR: 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!
}
sub
adhoc_ask_channel
($$)
{
my
$dev
=
shift
;
my
$ap
=
shift
;
my
$channel
;
do
{
printf
"
Wireless channel for network '%s' [auto or 0-13]:
",
$ap
;
my
$c
=
input
();
if
(
$c
eq
"
auto
")
{
$channel
=
"
6
";
# FIXME
}
elsif
(
$c
=~
m/^([0-9]|1[0-3])$/
)
{
$channel
=
$c
;
}
}
while
(
!
defined
(
$channel
));
debug
"
\t
New channel: %s
\n
",
$channel
;
return
$channel
;
}
sub
adhoc_ask_security
($)
{
my
$ssid
=
shift
;
my
%result
=
();
my
$sec
=
ask_choice
("
Security:
",
["
None
",
-
1
,
"
WEP
",
"
WPA-PSK
",
"
WPA2-PSK
",
"
WPA/WPA2-PSK
"],
['
0
',
'
1
',
'
2
',
'
4
',
'
6
'],
0
);
$result
{'
secmode
'}
=
$sec
;
if
(
$sec
==
0
)
{
# No encryption, nothing to ask the user
}
elsif
(
$sec
==
1
)
{
# WEP
progress
"
Using WEP security
\n
";
$result
{'
key
'}
=
ask_wep_key
(
$ssid
);
$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 '
$ssid
':
",
\
&is_wpa_passphrase
,
"
\t
Enter a passprase with 1-63 characters!
\n
");
}
else
{
printf
"
ERROR: security type %s not supported
\n
",
security2string
(
$sec
);
return
adhoc_ask_security
(
$ssid
);
}
return
%result
;
}
sub
adhoc_config_create
($)
{
my
$newconfig
=
shift
;
my
$config
=
[
["
7024
",
"
STAMODE
",
"
1
"],
["
7025
",
"
APCHANNEL
",
$newconfig
->
{'
channel
'}],
["
7026
",
"
CHMODE
",
"
1
"],
# FIXME: Shall we change this?
["
7030
",
"
WLMODE
",
"
1
"],
# FIXME: Shall we change this?
["
7100
",
"
APSSID
",
$newconfig
->
{'
SSID
'}],
["
7103
",
"
APSECMODE
",
$newconfig
->
{'
secmode
'}],
["
7104
",
"
APKEY_LEN
",
$newconfig
->
{'
key_len
'}],
["
7105
",
"
APDEFAULTKE
","
0
"],
["
7106
",
"
APKEY0
",
$newconfig
->
{'
key
'}],
["
7107
",
"
APKEY1
",
""],
["
7108
",
"
APKEY2
",
""],
["
7109
",
"
APKEY3
",
""],
["
7112
",
"
APAUTHEN
",
$newconfig
->
{'
authen
'}],
["
7118
",
"
APPSKALSET
",
$newconfig
->
{'
pskalset
'}],
["
7119
",
"
APPSKKEY
",
$newconfig
->
{'
pskkey
'}]
];
return
config_create
(
$config
);
}
...
@@ -783,91 +448,19 @@ sub adhoc_config_create ($) {
...
@@ -783,91 +448,19 @@ sub adhoc_config_create ($) {
###############################################################################
###############################################################################
sub
ask_operation
()
{
return
ask_choice
(
"
What do you want to do?
",
["
Setup a wireless connection through a wifi router or access point ('infrastructure')
",
"
Setup a direct wireless connection with the printer ('ad-hoc')
",
-
1
,
"
Change the name of the device
",
-
1
,
"
Save the device configuration to a file
",
"
Restore the device configuration from a file
",
-
1
,
"
Reload the configuration
",
"
Exit
"
],
["
wifi_infrastructure
",
"
wifi_adhoc
",
"
change_hostname
",
"
config_save
",
"
config_restore
",
"
reload
",
"
exit
"
],
"
exit
");
}
sub
main
()
{
sub
main
()
{
device_detect
();
my
$devs
=
device_detect
();
# my $reconfigured = 0;
if
(
scalar
(
$devs
)
==
0
)
{
# my $dev = device_detect () or exit;
print
"
No supported devices detected on the network. Supported devices are:
\n
";
# device_open ($dev);
foreach
(
@supported_devices
)
{
# my $cfg = device_config_request ($dev);
print
"
\t
-)
$_
\n
";
# my @config = config_parse ($cfg);
}
# print_current_configuration (\@config, "Current configuration of the device:\n");
print
"
\n
";
# # Ask what to do (set wifi AP, ad-hoc, save, restore)
exit
0
;
# my $operation = ask_operation ();
}
# debug ("\tSelected operation: %s\n", $operation);
my
$d
=
device_select
(
$devs
);
# if ($operation eq "wifi_infrastructure") {
# print Dumper (\@d);
# # 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);
# my $newcfg = wifi_config_create (\%newconfig);
# device_config_send ($dev, $newcfg);
# $reconfigured = 1;
# } elsif ($operation eq "wifi_adhoc") {
# # Ad-hoc connection to print server
# my $adhocssid = adhoc_ask_ssid ($dev);
# adhoc_send_unknown_command ($dev);
# my $channel = adhoc_ask_channel ($dev, $adhocssid);
# my %newconfig = ('SSID' => $adhocssid,
# 'channel' => $channel,
# adhoc_ask_security ($adhocssid)
# );
# my $newcfg = adhoc_config_create (\%newconfig);
# device_config_send ($dev, $newcfg);
# $reconfigured = 1;
# } elsif ($operation eq "change_hostname") {
# set_hostname ($dev);
# $reconfigured = 1;
# } elsif ($operation eq "config_save") {
# my $filename = ask_input ("Filename to save to: ", \&is_filename, "");
# device_config_save ($filename, $cfg);
# } elsif ($operation eq "config_restore") {
# my $filename = ask_input ("Filename to load from: ", \&is_filename, "");
# device_config_restore ($dev, $filename);
# } elsif ($operation eq "reload") {
# # do nothing, we'll call main below...
# } elsif ($operation eq "exit") {
# device_close ($dev);
# exit;
# } else {
# printf "ERROR: unknown operation %s\n", $operation;
# }
# device_close ($dev);
# # if the configuration was changed, print the new config after the device was reset
# $dev = device_detect () or exit;
# device_open ($dev);
# @config = config_parse (device_config_request ($dev));
# print_current_configuration (\@config, "New configuration of the device:\n");
#
# # Loop in main if "reload" is selected...
# main () if ($operation eq "reload");
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment