Skip to content

Instantly share code, notes, and snippets.

@robinsmidsrod
Created September 29, 2021 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save robinsmidsrod/34f6d5f16fc4699d16e3f501fd3b8a0c to your computer and use it in GitHub Desktop.
Save robinsmidsrod/34f6d5f16fc4699d16e3f501fd3b8a0c to your computer and use it in GitHub Desktop.
OMNIKey chipcard reader Perl
#!/usr/bin/perl
use strict;
use warnings;
use Chipcard::PCSC;
use Data::Dumper qw(Dumper);
use HTTP::Tiny ();
my $http = HTTP::Tiny->new();
my $webhook_url = 'http://ha.lan.folkeverkstedet.com:8123/api/webhook/3e4d7fb6-b97d-4ad7-8a60-ab154340f835';
my $context = Chipcard::PCSC->new()
or die "Unable to communicate with pcscd: $Chipcard::PCSC::errno\n";
my @readers = $context->ListReaders();
my $reader_states = [
map { { "reader_name" => $_ } }
# grep { /HID OMNIKEY/i }
@readers
];
while ( my $rc = $context->GetStatusChange($reader_states) ) {
foreach my $rs ( @$reader_states ) {
my $atr = $rs->{'ATR'} ? arr2asc($rs->{'ATR'}) : "";
print join(": ",
$rs->{'reader_name'},
$rs->{'current_state'},
$rs->{'event_state'},
$atr,
), "\n";
#foreach my $key ( keys %$rs ) {
# my $value = $rs->{$key};
# print "State: $key => $value\n";
#}
# Read next state
if ( $atr =~ m/^3B 8F 80 01 80 4F 0C A0 00 00 03 06/) {
read_id($rs->{'reader_name'});
}
$rs->{'current_state'} = $rs->{'event_state'};
}
last unless $rc;
}
sub read_id {
my ($reader) = @_;
my $card = Chipcard::PCSC::Card->new(
$context,
$reader,
$Chipcard::PCSC::SCARD_SHARE_EXCLUSIVE
);
my $tx = [0xFF, 0xCA, 0x00, 0x00, 0x00]; # https://stackoverflow.com/a/13178889
my $rx = $card->Transmit($tx);
if ( ref $rx ne ref [] ) {
warn("Not an array response: $rx\n");
return;
}
my $sw2 = pop @$rx;
my $sw1 = pop @$rx;
unless ( $sw1 == 0x90 && $sw2 == 0x00 ) {
warn("Read ID command not understood." . arr2asc([$sw1,$sw2]) . "\n");
return;
}
emit_id($rx);
return 1;
}
sub arr2asc {
return Chipcard::PCSC::array_to_ascii(shift @_);
}
sub emit_id {
my ($id) = @_;
my $id_str = arr2asc($id);
print "ID: $id_str...";
my $response = $http->request(
'POST',
$webhook_url,
{
'headers' => { 'Content-Type' => 'application/json'},
'content' => "{\"id\":\"$id_str\"}",
}
);
print $response->{'status'}, " ", $response->{'content'}, "\n";
return 1;
}
exit;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment