diff --git a/brmdoor-rpi/README b/brmdoor-rpi/README new file mode 100644 index 0000000..a2b2f36 --- /dev/null +++ b/brmdoor-rpi/README @@ -0,0 +1,10 @@ +This is quick and dirty version of brmdoor that does not require Arduino, and runs only on Raspberry Pi. + +This version of brmdoor requires: + irssi configured according to ./irssi/config with loaded scripts from ./irssi/scripts + libnfc-compatible smartcard reader + installed libnfc + nfc-getcard.c compiled against libnfc (with -lnfc) and saved as "./nfc-getcard" + to be running on RaspberryPi (or simillar with GPIO pins exported through /proc) + variables in brmdoor-rpi.sh modified according to reality + list of allowed cards in allowed.list in the correct format diff --git a/brmdoor-rpi/allowed.list b/brmdoor-rpi/allowed.list new file mode 100644 index 0000000..2cb6f9e --- /dev/null +++ b/brmdoor-rpi/allowed.list @@ -0,0 +1,2 @@ +mrkva 060606660 +mrqa 061600666 diff --git a/brmdoor-rpi/brmdoor-rpi.sh b/brmdoor-rpi/brmdoor-rpi.sh new file mode 100755 index 0000000..a3f766e --- /dev/null +++ b/brmdoor-rpi/brmdoor-rpi.sh @@ -0,0 +1,192 @@ +#!/bin/bash + +GPIO_LOCK=24 +GPIO_LED=22 +GPIO_BEEP=23 + +GPIO_SWITCH=18 +GPIO_MAGSWITCH=17 + + +NFC_BINARY=/root/brmdoor/nfc-getcard +ALLOWED_LIST=/root/brmdoor/allowed.list + +IRSSIFIFO=/home/brmdoor/.irssi/remote-control +IRCCHANS=("#brmlab" "#brmbiolab" "#brmstatus") +IRSSITOPICS=/home/brmdoor/.irssi/topics/ + + +# WARNING - OPEN/DOOR are stored as GPIO values. Since we have pullups and switches that grounds these pins, values are inverted (ie. 1 means "CLOSED") +OPEN=1 +DOOR=1 +UNLOCKED=0 + +LOCK_TIMEOUT=3s + +IGNORE_ALARM_SET=10 + +IGNORE_ALARM=0 + + +export LD_LIBRARY_PATH=/usr/local/lib + + +clean_gpio() { + for i in $GPIO_LOCK $GPIO_LED $GPIO_BEEP $GPIO_SWITCH $GPIO_MAGSWITCH; do + echo in > /sys/class/gpio/gpio${i}/direction + echo $i > /sys/class/gpio/unexport + done +} + + +beep_invalid() { + for i in `seq 1 5`; do + echo 1 > /sys/class/gpio/gpio${GPIO_BEEP}/value + sleep 0.05s + echo 0 > /sys/class/gpio/gpio${GPIO_BEEP}/value + sleep 0.05s + done +} + +beep_alarm() { + for i in `seq 1 5`; do + echo 1 > /sys/class/gpio/gpio${GPIO_BEEP}/value + sleep 0.5s + echo 0 > /sys/class/gpio/gpio${GPIO_BEEP}/value + sleep 0.5s + done +} + +irc_message() { + if [ ! -p "$IRSSIFIFO" ]; then + echo "irssi fifo '$IRSSIFIFO' does not exist!" + return + fi + for chan in ${IRCCHANS[*]}; do + echo "MSG $chan $1" > "$IRSSIFIFO" + done +} + +irc_status() { + if [ ! -p "$IRSSIFIFO" ]; then + echo "irssi fifo '$IRSSIFIFO' does not exist!" + return + fi + echo "TINFO" > "$IRSSIFIFO" + for chan in ${IRCCHANS[*]}; do + T=`cat "${IRSSITOPICS}/${chan}"` + NT=`echo "$T"|sed "s/BRMBIOLAB OPEN\|BRMBIOLAB CLOSED/BRMBIOLAB $1/"` + if [ "$NT" = "$T" ]; then + continue; + fi + echo "TOPIC $chan $NT" > "$IRSSIFIFO" + done + +} + +log_message() { + echo "`date "+%Y-%m-%d %T"` $1" >> ~/brmdoor.log +} + +trap clean_gpio EXIT + + +for i in $GPIO_LOCK $GPIO_LED $GPIO_BEEP $GPIO_SWITCH $GPIO_MAGSWITCH; do + echo $i > /sys/class/gpio/export +done + +for i in $GPIO_LOCK $GPIO_LED $GPIO_BEEP; do + echo "out" > /sys/class/gpio/gpio${i}/direction +done + +for i in $GPIO_SWITCH $GPIO_MAGSWITCH; do + echo "in" > /sys/class/gpio/gpio${i}/direction +done + + +LOOP=0 + +while true; do + CARD=`$NFC_BINARY` + if [ $? -ne 0 ]; then + + log_message "NFC_FAILURE" + logger -p user.error "[biodoor] NFC failure" + irc_message "[biodoor] NFC error! Might be out of order!" + sleep 15s + fi + + if [ $IGNORE_ALARM -gt 0 ]; then + let IGNORE_ALARM=$IGNORE_ALARM-1 + fi + + if [ -n "$CARD" ]; then # we have a card + NAME=`grep -i "^[0-9a-zA-Z_-]* ${CARD}$" "$ALLOWED_LIST"| cut -d ' ' -f 1` + if [ -z "$NAME" ]; then + log_message "UNKNOWN_CARD $CARD" + logger "[biodoor] unauthorized access denied for card $CARD" + irc_message "[biodoor] unauthorized request denied!" + beep_invalid + else + log_message "DOOR_UNLOCKED $NAME $CARD" + logger "[biodoor] unlocked by $NAME $CARD" + irc_message "[biodoor] door unlocked" + echo 1 > /sys/class/gpio/gpio${GPIO_LOCK}/value + echo 1 > /sys/class/gpio/gpio${GPIO_BEEP}/value + + sleep $LOCK_TIMEOUT + echo 0 > /sys/class/gpio/gpio${GPIO_LOCK}/value + echo 0 > /sys/class/gpio/gpio${GPIO_BEEP}/value + IGNORE_ALARM=$IGNORE_ALARM_SET + fi + fi + + # check open/closed status + CURRENT_OPEN=`cat /sys/class/gpio/gpio${GPIO_SWITCH}/value` + if [ $CURRENT_OPEN -eq 1 -a $OPEN -eq 0 ]; then + log_message "STATUS_CLOSED" + irc_message "BRMBIOLAB is now *CLOSED*" + irc_status "CLOSED" + IGNORE_ALARM=$IGNORE_ALARM_SET + fi + if [ $CURRENT_OPEN -eq 0 -a $OPEN -eq 1 ]; then + log_message "STATUS_OPEN" + irc_message "BRMBIOLAB is now *OPEN*" + irc_status "OPEN" + + fi + + CURRENT_DOOR=`cat /sys/class/gpio/gpio${GPIO_MAGSWITCH}/value` + + OPEN=$CURRENT_OPEN + + if [ $CURRENT_DOOR -eq 1 ] && [ $DOOR -eq 0 ] && [ $OPEN -eq 1 ] && [ $IGNORE_ALARM -eq 0 ]; then # doplnit timeout + log_message "DOOR_ALARM" + irc_message "[biodoor] alarm (door opened without unlock)!!!" + + beep_alarm & + fi + + DOOR=$CURRENT_DOOR + + + # just the led blinking stuff + if [ $LOOP -le 1 ]; then + if [ $OPEN -eq 1 ]; then + echo 0 > /sys/class/gpio/gpio${GPIO_LED}/value + else + echo 1 > /sys/class/gpio/gpio${GPIO_LED}/value + fi + fi + + if [ $LOOP -gt 5 ]; then + LOOP=0 + if [ $OPEN -eq 1 ]; then + echo 1 > /sys/class/gpio/gpio${GPIO_LED}/value + else + echo 0 > /sys/class/gpio/gpio${GPIO_LED}/value + fi + fi + + let LOOP=$LOOP+1 +done diff --git a/brmdoor-rpi/irssi/config b/brmdoor-rpi/irssi/config new file mode 100644 index 0000000..92fa87f --- /dev/null +++ b/brmdoor-rpi/irssi/config @@ -0,0 +1,29 @@ +servers = ( + { + address = "irc.freenode.net"; + chatnet = "Freenode"; + port = "6667"; + autoconnect = "Yes"; + } +); +chatnets = { Freenode = { type = "IRC"; }; }; + +channels = ( + { name = "#brmstatus"; chatnet = "Freenode"; autojoin = "Yes"; }, + { name = "#brmlab"; chatnet = "Freenode"; autojoin = "Yes"; }, + { name = "#brmbiolab"; chatnet = "Freenode"; autojoin = "Yes"; } +); + + +settings = { + core = { + real_name = "Brmbiolabi bot"; + user_name = "brmbiobot"; + nick = "brmbiobot"; + hostname = "foo.bar"; + }; + "fe-text" = { actlist_sort = "refnum"; }; +}; +logs = { }; +hilights = ( ); +ignores = ( ); diff --git a/brmdoor-rpi/irssi/scripts/fifo_remote.pl b/brmdoor-rpi/irssi/scripts/fifo_remote.pl new file mode 100644 index 0000000..a31e37a --- /dev/null +++ b/brmdoor-rpi/irssi/scripts/fifo_remote.pl @@ -0,0 +1,225 @@ +# fifo_remote.pl -- send commands to Irssi through named pipe/fifo +# +# DESCRIPTION +# +# fifo_remote.pl creates a named pipe (a.k.a. fifo). Everything written to the +# fifo will be passed on to Irssi and run as a command. (You need not precede +# you commands with `/', or whatever you've set you `cmdchars' to -- this also +# means that if you want to send a message, you must use the explicit `say' +# command.) +# +# SETTINGS +# +# fifo_remote_file (default is `remote-control') +# +# This is the file name of the named pipe. Any leading `~[USER]' part is +# expanded before use. If the name does not begin with `/' it is taken to +# be relative to Irssi's current configuration dir (usually `~/.irssi'). +# +# The default value thus normally means `~/.irssi/remote-control'. +# +# NOTES +# +# This script may have limited use to you, since it cannot bring back *any* +# return values from Irssi. It can only run Irssi commands from the outside. -- +# I use it to trigger my online/away messages from any shell, and that's about +# it. +# +# CAVEATS +# +# Due to the way named pipes (or fifos) works one must take extra care when +# writing to one of these beasts -- if not, the writing program may well hang +# forever. This is because the writing process will not terminate until the +# fifo has been read from the other end (see also fifo(4)). +# +# To avoid this problem, I usually use something akin to the below shell +# function to write to the Irssi fifo remote. It simply kills off the writing +# process if it's still around after a certain timeout (e.g. the fifo could be +# present but Irssi not running -- and thus the pipe would never be read). The +# entire process is done in the background, so the caller of the function does +# not have to wait. +# +# FILE="$HOME/.irssi/remote-control" +# irssi_command() { +# if [ -p "$FILE" ]; then +# ( echo "$*" > "$FILE" & +# sleep 5 +# kill $! 2>/dev/null )& +# fi +# } +# +# TODO +# +# o Clean up fifo file when Irssi quits -- right now this is not done, so extra +# precautions are required inside your shell scripts to make sure they do not +# hang indefinately when trying to write to the remote control fifo. (See +# above example.) +# +# HISTORY +# +# [2004-08-12, 22.16-00.58] v0.1a - began implementing it +# +# [2004-08-13, 09.52-10-19] v0.2a - began implementing fifo_read +# +# [2004-08-14, 01.12-04.27] v0.3a +# +# [2004-08-14, 14.09-18.13] v0.4a - seems to be fully functional, except for +# the fact that commands aren't run in the proper window/server environment +# +# [2004-08-15, 18.17-19.26] v0.5a - command comming through pipe is now run in +# the active window; removed bug which crashed Irssi, bug was caused by several +# input_add()s being called without having been removed in between +# +# [2004-08-26, 21.46-22.30] v0.5 - wrote above docs +# + +our $VERSION = '0.5'; +our %IRSSI = ( + authors => 'Zrajm C Akfohg', + contact => 'zrajm\@klingonska.org', + name => 'fifo_remote', + description => 'Irssi remote control (for shell scripting etc.) -- ' . + 'run all commands written to named pipe.', + license => 'GPLv2', + url => 'http://www.irssi.org/scripts/', +); # +use strict; # +use Irssi; # +use Fcntl; # provides `O_NONBLOCK' and `O_RDONLY' constants +our ( $FIFO, # fifo absolute filename (expanded from Irssi config) + $FIFO_HANDLE, # fifo filehandle for `open' et al. + $FIFO_TAG ); # fifo signal tag for `input_add' + +# simple subs +sub TRUE() { 1 } # some constants [perlsyn(1) +sub FALSE() { "" } # "Constant Functions"] +sub DEBUG(@) { print "%B", join(":", @_),"%n" }# DEBUG thingy + + +# Irssi settings +Irssi::settings_add_str($IRSSI{name}, # default fifo_remote_file + 'fifo_remote_file', 'remote-control'); # + + +# create named fifo and open it for input +# (called on script load and fifo name changes) +sub create_fifo($) { # [2004-08-14] + my ($new_fifo) = @_; # get args + if (not -p $new_fifo) { # create fifo if non-existant + if (system "mkfifo '$new_fifo' &>/dev/null" and + system "mknod '$new_fifo' &>/dev/null"){ + print CLIENTERROR "`mkfifo' failed -- could not create named pipe"; + # TODO: capture `mkfifo's stderr and show that here + return ""; # + } # + } # + $FIFO = $new_fifo; # remember fifo name + open_fifo($new_fifo); # open fifo for reading +} # + + +# set up signal to trigger on fifo input +# (called when creating named fifo) +sub open_fifo($) { # [2004-08-14] + my ($fifo) = @_; # get args + if (not sysopen $FIFO_HANDLE, $fifo, # open fifo for non-blocking + O_NONBLOCK | O_RDONLY) { # reading + print CLIENTERROR "could not open named pipe for reading"; + return ""; # + } # + Irssi::input_remove($FIFO_TAG) # disable fifo reading signal + if defined $FIFO_TAG; # if there is one + $FIFO_TAG = Irssi::input_add # set up signal called when + fileno($FIFO_HANDLE), INPUT_READ, # there's input in the pipe + \&read_fifo, ''; # + return 1; # +} # + + +# read from fifo +# (called by fifo input signal) +sub read_fifo() { # [2004-08-14] + foreach (<$FIFO_HANDLE>) { # for each input line + chomp; # strip trailing newline + Irssi::print( # + "%B>>%n $IRSSI{name} received command: \"$_\"", + MSGLEVEL_CLIENTCRAP); # +# Irssi::active_win->print( # show incoming commands +# "\u$IRSSI{name} received command: \"$_\"", # +# MSGLEVEL_CLIENTNOTICE); # + Irssi::active_win->command($_); # run incoming commands + } # + open_fifo($FIFO); # re-open fifo + # TODO: Is the above re-opening of fifo really necessary? -- If not + # invoked here `read_fifo' is called repeatedly, even though no input + # is to be found on the fifo. (This seems a waste of resources to me.) +} # + + +# disable fifo and erase fifo file +sub destroy_fifo($) { # [2004-08-14] + my ($fifo) = @_; # get args + if (defined $FIFO_TAG) { # if fifo signal is active + Irssi::input_remove($FIFO_TAG); # disable fifo signal + undef $FIFO_TAG; # and forget its tag + } # + if (defined $FIFO_HANDLE) { # if fifo is open + close $FIFO_HANDLE; # close it + undef $FIFO_HANDLE; # and forget handle + } # + if (-p $fifo) { # if named fifo exists + unlink $fifo; # erase fifo file + undef $FIFO; # and forget filename + } # + return 1; # return +} # + + +# add path to filename (expands `~user', and make +# non-absolute filename relative to Irssi's config dir) +sub absolute_path($) { # [2004-08-14] -- [2004-08-15] + my ($file) = @_; # + return '' if $file eq ''; # don't modify empty value + $file =~ s¶^(~[^/]*)¶ # expand any leading tilde + my $x; # WORKAROUND: glob() + until($x = glob($1)) { }; # sometimes return empty + $x; # string -- avoid that + ¶ex; # + $file = Irssi::get_irssi_dir() . "/$file" # if full path is not given + unless $file =~ m¶^/¶; # prepend irssi config path + # FIXME: clean up multiple slashes, and occuring `/./' and `/../'. + # this sub used in: fifo_remote.pl, xcuses.pl + return $file; # +} # + + +# clean up fifo on unload +# (called on /script unload) +Irssi::signal_add_first # + 'command script unload', sub { # [2004-08-13] + my ($script) = @_; # get args + return unless $script =~ # only do cleanup when + /(?:^|\s) $IRSSI{name} # unloading *this* script + (?:\.[^. ]*)? (?:\s|$) /x; # + destroy_fifo($FIFO) if -p $FIFO; # destroy old fifo + Irssi::print("%B>>%n $IRSSI{name} $VERSION unloaded", MSGLEVEL_CLIENTCRAP); + }; # + + +# create new fifo (erase any old) and get command prefix +# (called on script loading and on user /set) +sub setup() { # [2004-08-13] + my $new_fifo = absolute_path # get fifo_remote_file + Irssi::settings_get_str # setting from Irssi + 'fifo_remote_file'; # (and add path to it) + return if $new_fifo eq $FIFO and -p $FIFO; # do nada if already exists + destroy_fifo($FIFO) if -p $FIFO; # destroy old fifo + create_fifo($new_fifo) # create new fifo + and $FIFO = $new_fifo; # and remember that fifo +} # + +setup(); # initialize setup values +Irssi::signal_add('setup changed', \&setup); # re-read setup when it changes +print CLIENTCRAP "%B>>%n $IRSSI{name} $VERSION (by $IRSSI{authors}) loaded"; +#print CLIENTCRAP " (Fifo name: $FIFO)"; + diff --git a/brmdoor-rpi/irssi/scripts/thistory.pl b/brmdoor-rpi/irssi/scripts/thistory.pl new file mode 100644 index 0000000..9b85e8f --- /dev/null +++ b/brmdoor-rpi/irssi/scripts/thistory.pl @@ -0,0 +1,168 @@ +# thistory.pl v1.05 [10.03.2002] +# Copyright (C) 2001, 2002 Teemu Hjelt +# +# Written for irssi 0.7.98 and later, idea from JSuvanto. +# Modified by Mrkva to save topics to files +# +# Many thanks to fuchs, shasta, Paladin, Koffa and people +# on #irssi for their help and suggestions. +# +# Keeps information about the most recent topics of the +# channels you are on. +# Usage: /thistory [channel] and /tinfo [channel] +# +# v1.00 - Initial release. +# v1.02 - Months and topics with formatting were shown +# incorrectly. (Found by fuchs and shasta) +# v1.03 - event_topic was occasionally using the wrong +# server tag. Also added few variables to ease +# changing the settings and behaviour of this +# script. +# v1.04 - Minor bug-fixes. +# v1.05 - Made the script more consistent with other +# Irssi scripts. + +use Irssi; +use Irssi::Irc; +use vars qw($VERSION %IRSSI); + +# Formatting character. +my $fchar = '%'; + +# Format of the line. +my $format = '"%topic" %nick (%address) [%mday.%mon.%year %hour:%min:%sec]'; + +# Amount of topics stored. +my $tamount = 10; + +###### Don't edit below this unless you know what you're doing ###### + +$VERSION = "1.05"; +%IRSSI = ( + authors => "Teemu Hjelt", + contact => "temex\@iki.fi", + name => "topic history", + description => "Keeps information about the most recent topics of the channels you are on.", + license => "GNU GPLv2 or later", + url => "http://www.iki.fi/temex/", + changed => "Sun Mar 10 14:53:59 EET 2002", +); + +sub cmd_topicinfo { + my ($channel) = @_; + my $tag = Irssi::active_server()->{'tag'}; + $channel =~ s/\s+//; + $channel =~ s/\s+$//; + foreach my $chan (Irssi::channels()) { + open (TOPICLOG, ">/home/brmdoor/.irssi/topics/" . $chan->{name}); + print TOPICLOG "$chan->{topic}\n"; + close (TOPICLOG); + } + + if ($channel eq "") { + if (Irssi::channel_find(Irssi::active_win()->get_active_name())) { + $channel = Irssi::active_win()->get_active_name(); + } + } + if ($channel ne "") { + if ($topiclist{lc($tag)}{lc($channel)}{0}) { + Irssi::print("%W$channel%n: " . $topiclist{lc($tag)}{lc($channel)}{0}, MSGLEVEL_CRAP); + } else { + Irssi::print("No topic information for %W$channel%n", MSGLEVEL_CRAP); + } + } else { + Irssi::print("Usage: /tinfo "); + } +} + +sub cmd_topichistory { + my ($channel) = @_; + my $tag = Irssi::active_server()->{'tag'}; + $channel =~ s/\s+//; + $channel =~ s/\s+$//; + + if ($channel eq "") { + if (Irssi::channel_find(Irssi::active_win()->get_active_name())) { + $channel = Irssi::active_win()->get_active_name(); + } + } + if ($channel ne "") { + if ($topiclist{lc($tag)}{lc($channel)}{0}) { + my $amount = &getamount($tag, $channel); + Irssi::print("Topic history for %W$channel%n:", MSGLEVEL_CRAP); + for (my $i = 0; $i < $amount; $i++) { + if ($topiclist{lc($tag)}{lc($channel)}{$i}) { + my $num = $i + 1; + if (length($amount) >= length($tamount) && length($i + 1) < length($tamount)) { + for (my $j = length($tamount); $j > length($i + 1); $j--) { + $num = " " . $num; + } + } + Irssi::print($num . ". " . $topiclist{lc($tag)}{lc($channel)}{$i}, MSGLEVEL_CRAP); + } else { + last; + } + } + } else { + Irssi::print("No topic history for %W$channel%n", MSGLEVEL_CRAP); + } + } else { + Irssi::print("Usage: /thistory "); + } +} + +sub event_topic { + my ($server, $data, $nick, $address) = @_; + my ($channel, $topic) = split(/ :/, $data, 2); + my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time); + my $tag = $server->{'tag'}; + my $output = $format; + + $topic =~ s/%/%%/g; + #$topic .= '%n'; + + $val{'sec'} = $sec < 10 ? "0$sec" : $sec; + $val{'min'} = $min < 10 ? "0$min" : $min; + $val{'hour'} = $hour < 10 ? "0$hour" : $hour; + $val{'mday'} = $mday < 10 ? "0$mday" : $mday; + $val{'mon'} = $mon + 1 < 10 ? "0" . ($mon + 1) : $mon + 1; + $val{'year'} = $year + 1900; + + $val{'nick'} = $nick; + $val{'address'} = $address; + $val{'channel'} = $channel; + $val{'topic'} = $topic; + $val{'tag'} = $tag; + + $output =~ s/$fchar(\w+)/$val{$1}/g; + + for (my $i = (&getamount($tag, $channel) - 1); $i >= 0; $i--) { + if ($topiclist{lc($tag)}{lc($channel)}{$i}) { + $topiclist{lc($tag)}{lc($channel)}{$i + 1} = $topiclist{lc($tag)}{lc($channel)}{$i}; + } + } + $topiclist{lc($tag)}{lc($channel)}{0} = $output; + open (TOPICLOG, ">/home/brmdoor/.irssi/topics/".$channel); + print TOPICLOG "$topic\n"; + close (TOPICLOG) +} + +sub getamount { + my ($tag, $channel) = @_; + my $amount = 0; + + for (my $i = 0; $i < $tamount; $i++) { + if ($topiclist{lc($tag)}{lc($channel)}{$i}) { + $amount++; + } + } + return $amount; +} + +Irssi::command_bind("topichistory", "cmd_topichistory"); +Irssi::command_bind("thistory", "cmd_topichistory"); +Irssi::command_bind("topicinfo", "cmd_topicinfo"); +Irssi::command_bind("tinfo", "cmd_topicinfo"); +Irssi::signal_add("event topic", "event_topic"); + +Irssi::print("Loaded thistory.pl v$VERSION"); diff --git a/brmdoor-rpi/nfc-getcard.c b/brmdoor-rpi/nfc-getcard.c new file mode 100644 index 0000000..0b6b459 --- /dev/null +++ b/brmdoor-rpi/nfc-getcard.c @@ -0,0 +1,68 @@ +#include +#include + +#include +#include + +static nfc_device *pnd = NULL; +static nfc_context *context; + +int main(int argc, const char *argv[]) { + const uint8_t uiPollNr = 0x01; + const uint8_t uiPeriod = 0x01; + const nfc_modulation nmModulations[5] = { + { .nmt = NMT_ISO14443A, .nbr = NBR_106 }, + { .nmt = NMT_ISO14443B, .nbr = NBR_106 }, + { .nmt = NMT_FELICA, .nbr = NBR_212 }, + { .nmt = NMT_FELICA, .nbr = NBR_424 }, + { .nmt = NMT_JEWEL, .nbr = NBR_106 }, + }; + const size_t szModulations = 5; + + nfc_target nt; + int res = 0; + int i=0; + + nfc_init(&context); + if (context == NULL) { + printf("Unable to init libnfc (malloc)"); + return 1; + } + + pnd = nfc_open(context, NULL); + + if (pnd == NULL) { + printf("Unable to open NFC device."); + nfc_exit(context); + return 1; + } + + if (nfc_initiator_init(pnd) < 0) { + nfc_close(pnd); + nfc_exit(context); + return 1; + } + + if ((res = nfc_initiator_poll_target(pnd, nmModulations, szModulations, uiPollNr, uiPeriod, &nt)) < 0) { + nfc_close(pnd); + nfc_exit(context); + return 0; + } + + if (res > 0) { + if(nt.nm.nmt==NMT_ISO14443A) { + nfc_iso14443a_info info=nt.nti.nai; + for(i=0; i