Machine Shop RFID:rfid access.pl
#!/usr/bin/perl # # RFID access control program v1.0 # # Copyright (c) 2016, Zach Metzinger # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # $Id: rfid_access.pl,v 1.1 2016/01/02 23:15:31 zmetzing Exp $
use warnings;use strict;use DB_File;use Device::SerialPort qw( :PARAM :STAT 0.07 );
# Configuration parametersmy $db_fn = "nfc_auth_tags.db";my $serial_port_device = "/dev/ttyO2";my $relay_on_time = 10; # Seconds# Note: See http://www.armhf.com/using-beaglebone-black-gpios/ for details on the followingmy $sys_class_path = "/sys/class/gpio";my $sys_class_export = "$sys_class_path/export";my $sys_class_gpio = "$sys_class_path/gpio";my $red_led_gpio = 32+12;my $yel_led_gpio = 32+13;my $grn_led_gpio = 32+15;my $off_btn_gpio = 32+14; # Not currently usedmy $on_relay_gpio = 48;
# Local varsmy %auth_tags;my $tag_id;my $nbytes;my $nfc;my $sysfh;
# Debugging hexdump subrsub hexdump($){ my $offset = 0;
foreach my $chunk (unpack "(a16)*", $_[0]) { my $hex = unpack "H*", $chunk; # hexadecimal magic $chunk =~ tr/ -~/./c; # replace unprintables $hex =~ s/(.{1,8})/$1 /gs; # insert spaces printf "0x%08x (%05u) %-*s %s\n", $offset, $offset, 36, $hex, $chunk; $offset += 16; }}
# Bannerprintf "DMS HAAS RFID access control program v1.0\n";
# Verify existance of database before startingif (! -e $db_fn) { die "Unable to find database nfc_auth_tags.db\n";}
# Enable LEDsif (! -e $sys_class_export) { die "sysfs path $sys_class_export does not exist, are we on BBB?\n";}system("sudo chmod 222 $sys_class_export");system("echo $red_led_gpio > $sys_class_export");system("echo $yel_led_gpio > $sys_class_export");system("echo $grn_led_gpio > $sys_class_export");system("echo $on_relay_gpio > $sys_class_export");system("sudo chmod -R go=rwX $sys_class_gpio$red_led_gpio/*");system("sudo chmod -R go=rwX $sys_class_gpio$yel_led_gpio/*");system("sudo chmod -R go=rwX $sys_class_gpio$grn_led_gpio/*");system("sudo chmod -R go=rwX $sys_class_gpio$on_relay_gpio/*");system("echo high > $sys_class_gpio$red_led_gpio/direction");system("echo high > $sys_class_gpio$yel_led_gpio/direction");system("echo high > $sys_class_gpio$grn_led_gpio/direction");system("echo low > $sys_class_gpio$on_relay_gpio/direction");
# Initialize serial port$nfc = new Device::SerialPort ($serial_port_device) || die "Can't open $serial_port_device: $!\n";
$nfc->user_msg(1);$nfc->databits(8);$nfc->baudrate(9600);$nfc->parity("none");$nfc->stopbits(1);$nfc->handshake("none");$nfc->read_char_time(0);$nfc->read_const_time(250);$nfc->write_settings || undef $nfc;
if (!defined($nfc)) { die "Unable to open serial port: $!\n";}
system("stty -F $serial_port_device raw");
printf "Ready to read tags\n";
while (1) {# Light red LED, others off system("echo 0 > $sys_class_gpio$red_led_gpio/value"); system("echo 1 > $sys_class_gpio$grn_led_gpio/value");
# Wait for serial port data to come in ($nbytes, $tag_id) = $nfc->read(255); if ($nbytes == -1) { die "EOF on serial port read\n"; }
# Only process if we got after the 1 second read timeout if ($nbytes > 0) { # FIXME: Dump for debug #hexdump($tag_id); if (($nbytes != 16) || (ord(substr($tag_id, 0, 1)) != 0x02)) { printf "Got data on serial port, but does not fit tag format. Ignoring.\n"; } else { # Extract tag id from framing $tag_id = substr($tag_id, 1, 12); # FIXME: Dump for debug #hexdump($tag_id); # Look up NFC tag ID in database # Note: Only opening database long enough to look this up. That way, we don't have to # manage a multi-access database right now. Could be solved with DB v2-v6 or mysql ..later if (!defined(tie %auth_tags, "DB_File", $db_fn, O_RDONLY | O_EXCL, 0600, $DB_HASH)) { printf "Cannot open database: $!\n"; } else { if ($auth_tags{$tag_id}) { printf "Tag $tag_id is authorized\n"; # If matched, close relay and light green LED system("echo 1 > $sys_class_gpio$on_relay_gpio/value"); system("echo 1 > $sys_class_gpio$red_led_gpio/value"); system("echo 0 > $sys_class_gpio$grn_led_gpio/value"); sleep($relay_on_time); } else { printf "Tag $tag_id is NOT authorized\n"; } untie %auth_tags; } # Release relay and light red RED system("echo 0 > $sys_class_gpio$on_relay_gpio/value"); system("echo 0 > $sys_class_gpio$red_led_gpio/value"); system("echo 1 > $sys_class_gpio$grn_led_gpio/value"); } }}Migrated from the legacy DMS wiki: original page