Files for vault door entry system
This commit is contained in:
parent
3ffb978a6b
commit
28e9ad4458
242
doorman/doorman.pl
Executable file
242
doorman/doorman.pl
Executable file
@ -0,0 +1,242 @@
|
||||
#!/usr/bin/perl -W
|
||||
###############################################################################
|
||||
#
|
||||
# doorman.pl - Use inexpensive USB RFID reader to allow access to a physical
|
||||
# portal controlled by an inexpensive USB relay, via a background
|
||||
# HTTP portal for authentication.
|
||||
#
|
||||
#################################################################[ AJC 2018 ]##
|
||||
use strict;
|
||||
use Linux::Input;
|
||||
use Data::Dumper;
|
||||
use WWW::Mechanize;
|
||||
use File::Basename qw{basename};
|
||||
use IO::Select;
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Configuration directoves
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# Direct /dev link to device. Use by-id when possible
|
||||
my $device = "/dev/input/by-id/usb-13ba_Barcode_Reader-event-kbd";
|
||||
|
||||
my $usbrelay = "/usr/bin/usbrelay";
|
||||
my $usbrelay_device = "3X9XI_1";
|
||||
|
||||
# The URL of the authentication server
|
||||
my $url = "http://doors.pfv.turnsys.net/";
|
||||
|
||||
# Location of syslog's userspace logger utility
|
||||
my $rsyslog = "/usr/bin/logger";
|
||||
|
||||
# Card IDs that bypass network auth
|
||||
my %backdoors = (
|
||||
|
||||
"0009399422" => 'Charles NW',
|
||||
"0009106067" => 'Josef C',
|
||||
|
||||
);
|
||||
|
||||
# For logging syslog messages to stdout as well as syslog.
|
||||
my $debug = "true";
|
||||
#my $debug = "false";
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Subroutines
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
#################################################
|
||||
# logger - Send logs to syslog, or stdout if
|
||||
# DEBUG is defined.
|
||||
#################################################
|
||||
sub logger {
|
||||
|
||||
my $logtext = shift;
|
||||
if ($debug eq "true") { print localtime() . " " . basename($0) . ": " . "$logtext\n" };
|
||||
system( $rsyslog . " \"" . basename($0) . ": " . "$logtext\"" );
|
||||
|
||||
}
|
||||
|
||||
#################################################
|
||||
# unlock_door - Handle the USB relay to unlock
|
||||
# actuator.
|
||||
#################################################
|
||||
sub unlock_door() {
|
||||
|
||||
system $usbrelay . " " . $usbrelay_device . "=1 >/dev/null 2>&1";
|
||||
sleep 10;
|
||||
system $usbrelay . " " . $usbrelay_device . "=0 >/dev/null 2>&1";
|
||||
logger "Locking door.";
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
#################################################
|
||||
# authenticate - check backdoors and legit HTTP
|
||||
# source to see if ID is valid.
|
||||
# Unlocks door if appropriate.
|
||||
#################################################
|
||||
sub authenticate {
|
||||
|
||||
my $id = shift;
|
||||
|
||||
if ( defined $backdoors{$id} ) {
|
||||
|
||||
logger $backdoors{$id} . " override key accepted. Unlocking door.";
|
||||
unlock_door;
|
||||
|
||||
} else {
|
||||
|
||||
# Open a connection to auth server.
|
||||
my $connection = WWW::Mechanize->new( autocheck => 0, quiet => 1);
|
||||
$connection->get ($url . $id);
|
||||
|
||||
# Touch a file named as the card ID number to make the card work.
|
||||
if ($connection->status == 200) {
|
||||
|
||||
logger "Card $id is valid. Unlocking door.";
|
||||
unlock_door;
|
||||
|
||||
} else {
|
||||
|
||||
# File is not cleanly returned, so it's invalid.
|
||||
logger "Card $id is invalid! (" . $connection->status() . ")";
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#################################################
|
||||
# keytranslate - Reduce the returned keypress
|
||||
# value, and translate into the
|
||||
# actual number pressed.
|
||||
#################################################
|
||||
sub keytranslate {
|
||||
|
||||
my $keypress = shift;
|
||||
|
||||
return 1 if ($keypress == 30);
|
||||
return 2 if ($keypress == 31);
|
||||
return 3 if ($keypress == 32);
|
||||
return 4 if ($keypress == 33);
|
||||
return 5 if ($keypress == 34);
|
||||
return 6 if ($keypress == 35);
|
||||
return 7 if ($keypress == 36);
|
||||
return 8 if ($keypress == 37);
|
||||
return 9 if ($keypress == 38);
|
||||
return 0 if ($keypress == 39);
|
||||
return $keypress;
|
||||
|
||||
}
|
||||
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# main - This is where the whole thing comes together.
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# scoped values for loop work
|
||||
my $oldvalue = 0;
|
||||
my $dupe_flag = 0;
|
||||
my $id = "";
|
||||
my $done_flag = 0;
|
||||
|
||||
# Open all USB input devices, and stash in a hash until needed.
|
||||
my @devicenames = map { "/dev/input/by-id/" . basename($_) } </dev/input/by-id/*>;
|
||||
my %devices;
|
||||
|
||||
my $selector = IO::Select->new();
|
||||
|
||||
foreach (@devicenames) {
|
||||
my $device = Linux::Input->new($_);
|
||||
$selector->add($device->fh);
|
||||
$devices{$device->fh} = $device;
|
||||
}
|
||||
|
||||
logger basename($0) . " started.";
|
||||
|
||||
system $usbrelay . " " . $usbrelay_device . "=0 >/dev/null 2>&1";
|
||||
|
||||
|
||||
# stay in an infinite loop.
|
||||
while ( 1 ) {
|
||||
|
||||
# Do this if we have a device with some input
|
||||
while (my @fh = $selector->can_read) {
|
||||
|
||||
# For each file handle that has stuff to read
|
||||
foreach my $fh (@fh) {
|
||||
|
||||
my $input = $devices{$fh};
|
||||
|
||||
# Read the input that's waiting
|
||||
while (my @events = $input->poll(0.01)) {
|
||||
|
||||
# Convert keystrokes to useful data
|
||||
foreach (@events) {
|
||||
# break up the input struct into useful scalars.
|
||||
my $code = %$_{code};
|
||||
my $value = %$_{value};
|
||||
my $type = %$_{type};
|
||||
my $number = keytranslate($value & 127);
|
||||
|
||||
# This seems to indicate a KEYP/KEYDOWN event
|
||||
if ( $code == 4 && $type == 4 ) {
|
||||
|
||||
|
||||
# If we just saw this, it's KEYUP now, so ignore
|
||||
if ($value == $oldvalue && $dupe_flag == 0) {
|
||||
$dupe_flag = 1;
|
||||
next
|
||||
} else {
|
||||
$dupe_flag = 0;
|
||||
}
|
||||
|
||||
# 0-9 for number, 40 for end of string.
|
||||
if ( $number > 9 && $number != 40) { logger "Problem reading ID\n"; next}
|
||||
|
||||
if ( $number == 40) {
|
||||
$done_flag = 1;
|
||||
} else {
|
||||
$id .= $number;
|
||||
}
|
||||
|
||||
$oldvalue = $value;
|
||||
|
||||
} # if ($code == 4 && $type == 4)
|
||||
|
||||
} # foreach (@events)
|
||||
|
||||
} # while (my @events = $input->poll(0.01))
|
||||
|
||||
} # foreach my $fh (@fh)
|
||||
|
||||
# Do something with the completed code.
|
||||
if ( $done_flag == 1) {
|
||||
|
||||
logger "ID $id scanned.";
|
||||
|
||||
authenticate($id);
|
||||
|
||||
$id = "";
|
||||
$done_flag = 0;
|
||||
|
||||
} else {
|
||||
|
||||
next
|
||||
|
||||
}
|
||||
|
||||
} # while (my @fh = $selector->can_read)
|
||||
|
||||
|
||||
} # while (1)
|
||||
|
63
doorman/test.pl
Executable file
63
doorman/test.pl
Executable file
@ -0,0 +1,63 @@
|
||||
#!/usr/bin/perl -W
|
||||
###############################################################################
|
||||
#
|
||||
# doorman.pl - Use inexpensive USB RFID reader to allow access to a physical
|
||||
# portal controlled by an inexpensive USB relay, via a background
|
||||
# HTTP portal for authentication.
|
||||
#
|
||||
#################################################################[ AJC 2018 ]##
|
||||
use warnings;
|
||||
use strict;
|
||||
use Linux::Input;
|
||||
use IO::Select;
|
||||
use File::Basename qw{basename};
|
||||
use Data::Dumper;
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# Configuration directoves
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
# Direct /dev link to device. Use by-id when possible
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# main - This is where the whole thing comes together.
|
||||
#
|
||||
###############################################################################
|
||||
sub main {
|
||||
|
||||
# Add all input devices
|
||||
my @devicenames = map { "/dev/input/by-id/" . basename($_) } </dev/input/by-id/*>;
|
||||
my %devices;
|
||||
|
||||
my $selector = IO::Select->new();
|
||||
|
||||
foreach (@devicenames) {
|
||||
my $device = Linux::Input->new($_);
|
||||
$selector->add($device->fh);
|
||||
$devices{$device->fh} = $device;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
|
||||
while (my @fh = $selector->can_read) {
|
||||
foreach my $fh (@fh) {
|
||||
my $input = $devices{$fh};
|
||||
while (my @events = $input->poll(0.01)) {
|
||||
foreach (@events) {
|
||||
print Dumper($_);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
main();
|
||||
|
Loading…
Reference in New Issue
Block a user