File Coverage

blib/lib/EAFDSS.pm
Criterion Covered Total %
statement 48 55 87.2
branch 16 24 66.6
condition n/a
subroutine 9 9 100.0
pod 2 2 100.0
total 75 90 83.3


line stmt bran cond sub pod time code
1             # EAFDSS - Electronic Fiscal Signature Devices Library
2             # Ειδική Ασφαλής Φορολογική Διάταξη Σήμανσης (ΕΑΦΔΣΣ)
3             #
4             # Copyright (C) 2008 Hasiotis Nikos
5             #
6             # ID: $Id: EAFDSS.pm 105 2009-05-18 10:52:03Z hasiotis $
7              
8             package EAFDSS;
9              
10             =head1 NAME
11              
12             EAFDSS - Electronic Fiscal Signature Devices Library
13              
14             =head1 SYNOPSIS
15              
16             use EAFDSS;
17              
18             my($dh) = new EAFDSS(
19             "DRIVER" => $driver . "::" . $params,
20             "SN" => $serial,
21             "DIR" => $sDir,
22             "DEBUG" => $verbal
23             );
24              
25             if (! $dh) {
26             print("ERROR: " . EAFDSS->error() ."\n");
27             exit -1;
28             }
29              
30             $result = $dh->Status();
31             $result = $dh->Sign($fname);
32             $result = $dh->Info();
33             $result = $dh->SetTime($time);
34             $result = $dh->GetTime();
35             $result = $dh->SetHeaders($headers);
36             $result = $dh->GetHeaders();
37              
38             if ($result) {
39             printf("%s\n", $result);
40             exit(0);
41             } else {
42             my($errNo) = $dh->error();
43             my($errMsg) = $dh->errMessage($errNo);
44             printf(STDERR "ERROR [0x%02X]: %s\n", $errNo, $errMsg);
45             exit($errNo);
46             }
47              
48              
49             =head1 DESCRIPTION
50              
51             The EAFDSS module handles the communication with an Electronic Signature Device (EAFDSS).
52             It defines a set of methods common to all EAFDSS devices in order to communicate with the
53             device but also handle all necessary file housekeeping requirements by Law, like creating
54             A, B, C files.
55              
56             =head1 ARCHITECTURE of an EAFDSS Application
57              
58             This module is loosely (and shamelessly I may add) influenced by the architecture of the
59             DBI module. There is a layer of a basic API that is common to all EAFDSS device drivers.
60             Usually a developer of an EAFDSS application will only need to deal with functions only
61             at that level. You have to be in need of something really special to access functions
62             that are specific to a certain driver.
63            
64              
65             |<-------- EAFDSS A/B type solution ------->|
66             |<- Your work ->| |<--- Scope of EAFDSS --->| |<-- hardware -->|
67             .-. .-------------. .---------------.
68             .--------------. | |---| SDSP Driver |---| EAFDSS Device |
69             | | |E| `-------------' `---------------'
70             | Perl script | |A| |A| .-------------. .---------------.
71             | using EAFDSS |--|P|--|F|---| SDNP Driver |---| EAFDSS Device |
72             | API methods | |I| |D| `-------------' `---------------'
73             | | |S|...
74             `--------------' |S|... Other drivers
75             | |...
76             `-'
77              
78             =cut
79              
80 4     4   539309 use 5.006_000;
  4         18  
  4         183  
81 4     4   24 use strict;
  4         9  
  4         181  
82 4     4   32 use warnings;
  4         16  
  4         126  
83 4     4   25 use Carp;
  4         10  
  4         292  
84 4     4   4727 use Class::Base;
  4         7132  
  4         138  
85              
86 4     4   29 use base qw ( Class::Base );
  4         8  
  4         9715  
87              
88             our($VERSION) = '0.80';
89              
90             =head1 Methods
91              
92             First of all you have to initialize the driver handle through the EAFDSS constructor.
93              
94             =head2 init, new
95              
96             Returns a newly created $dh driver handle. The DRIVER argument is a combination of a driver and
97             it's parameters. For instance it could be one of the following:
98              
99             EAFDSS::SDNP::127.0.0.1
100              
101             or
102            
103             EAFDSS::Dummy:/tmp/dummy.eafdss
104              
105             or
106              
107             Driver EAFDSS::SDSP::/dev/ttyS0
108              
109             The SN argument is the Serial number of device we want to connect. Each device has it's own unique serial
110             number. If the device's SN does not much with the provided then you will get an error.
111              
112             The DIR argument is the directory were the signature files (A, B and C) will be created. Make sure the
113             directory exist.
114              
115             The last argument is the DEBUG. Use a true value in order to get additional information. This one is only
116             useful to developers of the module itself.
117              
118             my($dh) = new EAFDSS(
119             "DRIVER" => $driver . "::" . $params,
120             "SN" => $serial,
121             "DIR" => $sDir,
122             "DEBUG" => $verbal
123             );
124            
125             if (! $dh) {
126             print("ERROR: " . EAFDSS->error() ."\n");
127             exit -1;
128             }
129              
130             Following are the common methods to all the device drivers.
131              
132             =cut
133              
134             sub init {
135 4     4 1 2308 my($self, $config) = @_;
136              
137 4 50       27 if (! exists $config->{DRIVER}) {
138 0         0 croak "You need to provide the Driver to use";
139             } else {
140 4         35 $self->{DRV} = substr($config->{DRIVER}, 0, rindex($config->{DRIVER}, "::"));
141 4         21 $self->{PARAMS} = substr($config->{DRIVER}, rindex($config->{DRIVER}, "::") + 2);
142 4 50       22 if ($self->{PARAMS} eq '') {
143 0         0 croak "You need to provide params to the driver!";
144             }
145             }
146              
147 4 50       18 if (! exists $config->{DIR}) {
148 0         0 croak "You need to provide the DIR to save the singatures!";
149             } else {
150 4         32 $self->{DIR} = $config->{DIR};
151             }
152              
153 4 50       69 if (! -e $self->{DIR}) {
154 0         0 croak "The directory to save the singatures does not exist!";
155             }
156              
157 4 50       17 if (! exists $config->{SN}) {
158 0         0 croak "You need to provide the Serial Number of the device!";
159             } else {
160 4         12 $self->{SN} = $config->{SN};
161             }
162              
163 4         32 $self->debug("Loading driver \"$self->{DRV}\"\n");
164 4         377 eval qq { require $self->{DRV} };
165 4 50       35 if ($@) {
166 0         0 return $self->error("No such driver \"$self->{DRV}\"");
167             }
168              
169 4         31 $self->debug("Initializing device with \"$self->{PARAMS}\"\n");
170 4         73 my($fd) = $self->{DRV}->new(
171             "PARAMS" => $self->{PARAMS},
172             "SN" => $self->{SN},
173             "DIR" => $self->{DIR},
174             "DEBUG" => $self->{_DEBUG}
175             );
176              
177 4 50       26 if (!defined $fd) {
178 0         0 return $self->error($self->{DRV}->error());
179             }
180              
181 4         12 return $fd;
182             }
183              
184             =head2 EAFDSS->available_drivers
185              
186             Returns an array containing the names of drivers currently installed/supported.
187              
188             my(@drivers) = EAFDSS->available_drivers();
189              
190             =cut
191              
192             sub available_drivers {
193 1     1 1 11 my(@drivers, $curDir, $curFile, $curDirEAFDSS);
194              
195 1         4 foreach $curDir (@INC){
196 11         23 $curDirEAFDSS = $curDir . "/EAFDSS";
197 11 100       287 next unless -d $curDirEAFDSS;
198              
199 3 50       141 opendir(DIR, $curDirEAFDSS) || carp "opendir $curDirEAFDSS: $!\n";
200 3         74 foreach $curFile (readdir(EAFDSS::DIR)){
201 21 100       83 next unless $curFile =~ s/\.pm$//;
202 15 100       37 next if $curFile eq 'Base';
203 12 100       24 next if $curFile eq 'Micrelec';
204 9         18 push(@drivers, $curFile);
205             }
206 3         37 closedir(DIR);
207             }
208              
209 1         9 return @drivers;
210             }
211              
212              
213             sub DESTROY {
214 4     4   46 my($self) = shift;
215             }
216              
217             # Preloaded methods go here.
218              
219             1;
220             __END__