File Coverage

blib/lib/Net/CSTA.pm
Criterion Covered Total %
statement 25 61 40.9
branch 0 6 0.0
condition 0 9 0.0
subroutine 9 15 60.0
pod n/a
total 34 91 37.3


line stmt bran cond sub pod time code
1             package Net::CSTA;
2              
3 1     1   24913 use strict;
  1         3  
  1         42  
4 1     1   4 use warnings;
  1         2  
  1         34  
5              
6             require Exporter;
7 1     1   1057 use AutoLoader qw(AUTOLOAD);
  1         1482  
  1         4  
8              
9             our @ISA = qw(Exporter);
10              
11             # Items to export into callers namespace by default. Note: do not export
12             # names by default without a very good reason. Use EXPORT_OK instead.
13             # Do not simply export all your public functions/methods/constants.
14              
15             # This allows declaration use Net::CSTA ':all';
16             # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
17             # will save memory.
18             our %EXPORT_TAGS = ( 'all' => [ qw(
19            
20             ) ] );
21              
22             our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
23              
24             our @EXPORT = qw(
25            
26             );
27              
28             our $VERSION = '0.04';
29 1     1   794 use IO::Socket::INET;
  1         25713  
  1         8  
30 1     1   1660 use Net::CSTA::ASN qw(CSTAapdu);
  1         3  
  1         12  
31 1     1   14 use Convert::ASN1 qw(:io);
  1         2  
  1         299  
32              
33             sub new {
34 0     0     my $self = shift;
35 0   0       my $class = ref $self || $self;
36 0           my %me = @_;
37 0           my $this = bless \%me,$class;
38 0           $this->init();
39             }
40              
41             package Net::CSTA::PDU;
42 1     1   7 use Net::CSTA::ASN qw(CSTAapdu);
  1         1  
  1         7  
43 1     1   987 use MIME::Base64;
  1         841  
  1         1700  
44              
45             sub decode {
46 0     0     my $self = shift;
47 0   0       my $class = ref $self || $self;
48 0           my $pdu = shift;
49 0           my $this = bless $CSTAapdu->decode($pdu),$class;
50 0           $this->init();
51             }
52              
53             sub _hexenc {
54 0     0     join(":",map { sprintf("%2.2x",$_); } unpack("C*",$_[0]))
  0            
55             }
56              
57             sub isError {
58 0     0     my $self = shift;
59 0           defined $self->{typeOfError};
60             }
61              
62             sub _b64 {
63 0     0     my $x = encode_base64($_[0]);
64            
65 0           chomp($x);
66 0           $x;
67             }
68              
69             sub _safe_copy {
70 0     0     my $self = shift;
71            
72 0           my $copy;
73             SWITCH: {
74 0 0         UNIVERSAL::isa($self,'ARRAY') and do {
  0            
75 0           $copy = [];
76 0           foreach (@{$self})
  0            
77             {
78 0           push(@{$copy},_safe_copy($_));
  0            
79             }
80             },last SWITCH;
81            
82 0 0 0       UNIVERSAL::isa($self,'HASH') || UNIVERSAL::isa($self,'Net::CSTA::PDU') and do {
83 0           $copy = {};
84 0           foreach (keys %{$self})
  0            
85             {
86 0           $copy->{$_} = _safe_copy($self->{$_});
87             }
88             },last SWITCH;
89            
90 0           do {
91 0 0         $copy = $self =~ /^[[:print:]^>^<^^=]*$/ ? $self : _hexenc($self);
92             },last SWITCH;
93             };
94            
95 0           $copy;
96             }
97              
98             sub toXML {
99             my $pdu = _safe_copy($_[0]);
100 1     1   851 use XML::Simple;
  0            
  0            
101            
102             XMLout($pdu,RootName=>'csta');
103             }
104              
105             sub init {
106             $_[0];
107             }
108              
109             package Net::CSTA;
110              
111             sub init {
112             my $self = shift;
113             $self->{_csock} = IO::Socket::INET->new(Proto=>'tcp',PeerHost=>$self->{Host},PeerPort=>$self->{Port})
114             or die "Unable to connect to CSTA server at $self->{Host}:$self->{Port}: $!\n";
115             $self->{_ssock} = IO::Socket::INET->new(Proto=>'udp',LocalHost=>'localhost',LocalPort=>$self->{LocalPort} || 3333)
116             or die "Unable to create local UDP port: $!\n";
117             $self->{_req} = $$;
118             $self->{Debug} = 0 unless defined $self->{Debug};
119             $self;
120             }
121              
122             sub next_request {
123             $_[0]->{_req}++;
124             }
125              
126             sub this_request {
127             $_[0]->{_req};
128             }
129              
130             sub debug
131             {
132             $_[0]->{Debug};
133             }
134              
135             sub close
136             {
137             my $self = shift;
138             my $sock = shift || $self->{_csock};
139             shutdown($sock,2);
140             close($sock);
141             }
142              
143             sub write_pdu {
144             my $self = shift;
145             my $pdu = shift;
146             my $len = length($pdu);
147             my $sock = shift || $self->{_csock};
148              
149             if ($self->debug > 1)
150             {
151             warn "C ---> S\n";
152             Convert::ASN1::asn_dump(*STDERR, $pdu);
153             Convert::ASN1::asn_hexdump(*STDERR, $pdu) if $self->debug > 2;
154             }
155              
156             $sock->write(pack "n",$len);
157             $sock->write($pdu);
158             }
159              
160             sub read_pdu {
161             my $self = shift;
162             my $timeout = shift || undef;
163             my $sock = shift || $self->{_csock};
164              
165             my $buf = "";
166            
167             my ($rin,$win,$ein) = ("","","");
168             my ($rout,$wout,$eout) = ("","","");
169            
170             vec($rin,$sock->fileno,1) = 1;
171             $ein = $rin | $win;
172            
173             my $n = select($rout=$rin,$wout=$win,$eout=$ein,$timeout);
174             return undef unless $n > 0;
175            
176             eval {
177             local $SIG{ALRM} = sub { die "alarm\n" };
178             alarm ($timeout || 30);
179             my $nread = $sock->sysread($buf,2);
180             my $len = unpack "n",$buf;
181             $sock->sysread($buf,$len);
182             alarm 0;
183             }; if ($@) {
184             die unless $@ eq "alarm\n";
185             warn "Caught timeout\n";
186             return undef;
187             }
188              
189             if ($self->debug > 1)
190             {
191             warn "C <--- S\n";
192             Convert::ASN1::asn_dump(*STDERR, $buf);
193             Convert::ASN1::asn_hexdump(*STDERR, $buf) if $self->debug > 2;
194             }
195             $buf;
196             }
197              
198             sub send_and_receive {
199             my $self = shift;
200              
201             $self->send(@_);
202             $self->receive();
203             }
204              
205             sub request {
206             my $self = shift;
207             my %op = @_;
208              
209             $op{invokeID} = $self->next_request;
210             $self->send_and_receive(svcRequest=>\%op);
211             }
212              
213             sub send {
214             my $self = shift;
215             my $pdu = $CSTAapdu->encode(@_);
216              
217             $self->write_pdu($pdu);
218             }
219              
220             sub receive {
221             my $self = shift;
222             my $pdu = $self->read_pdu(@_);
223             return undef unless $pdu;
224              
225             Net::CSTA::PDU->decode($pdu);
226             }
227              
228             sub recv_pdu {
229             my $self = shift;
230             my $sock = shift || $self->{_ssock};
231              
232             my $buf = "";
233             my $nread = $sock->recv($buf,2);
234             my $len = unpack "n",$buf;
235             $sock->recv_pdu($buf,$len);
236              
237             if ($self->debug > 1)
238             {
239             warn "C <--- S\n";
240             Convert::ASN1::asn_dump(*STDERR, $buf);
241             Convert::ASN1::asn_hexdump(*STDERR, $buf) if $self->debug > 2;
242             }
243            
244             $buf;
245             }
246              
247             # Preloaded methods go here.
248              
249             # Autoload methods go after =cut, and are processed by the autosplit program.
250              
251             1;
252             __END__