File Coverage

blib/lib/Device/RFXCOM/Base.pm
Criterion Covered Total %
statement 92 92 100.0
branch 23 24 95.8
condition n/a
subroutine 23 23 100.0
pod 3 3 100.0
total 141 142 99.3


line stmt bran cond sub pod time code
1 5     5   31 use strict;
  5         7  
  5         179  
2 5     5   20 use warnings;
  5         8  
  5         270  
3             package Device::RFXCOM::Base;
4             $Device::RFXCOM::Base::VERSION = '1.163170';
5             # ABSTRACT: module for RFXCOM device base class
6              
7              
8 5     5   92 use 5.006;
  5         17  
9             use constant {
10             DEBUG => $ENV{DEVICE_RFXCOM_BASE_DEBUG},
11             TESTING => $ENV{DEVICE_RFXCOM_TESTING},
12 5     5   23 };
  5         7  
  5         420  
13 5     5   37 use Carp qw/croak/;
  5         8  
  5         367  
14 5     5   1392 use IO::Handle;
  5         15632  
  5         287  
15 5     5   2955 use IO::Select;
  5         8228  
  5         265  
16 5     5   3233 use Time::HiRes;
  5         7517  
  5         28  
17 5     5   679 use Symbol qw/gensym/;
  5         8  
  5         392  
18 5     5   4163 use Device::SerialPort qw( :PARAM :STAT 0.07 );
  5         100477  
  5         1445  
19 5     5   52 use Fcntl;
  5         9  
  5         6613  
20              
21             sub _new {
22 12     12   84 my ($pkg, %p) = @_;
23 12         205 my $self = bless
24             {
25             baud => 4800,
26             port => 10001,
27             discard_timeout => 0.03,
28             ack_timeout => 2,
29             dup_timeout => 0.5,
30             _q => [],
31             _buf => '',
32             _last_read => 0,
33             init_callback => undef,
34             %p,
35             }, $pkg;
36 12 100       143 $self->{plugins} = [$self->plugins()] unless ($self->{plugins});
37 12         293 $self->_open();
38 6         59 $self->_init();
39 6         49 $self;
40             }
41              
42             sub DESTROY {
43 12     12   7611 my $self = shift;
44 12         494 delete $self->{init};
45             }
46              
47              
48             sub queue {
49 1     1 1 614 scalar @{$_[0]->{_q}};
  1         7  
50             }
51              
52              
53             sub _write {
54 22     22   38 my $self = shift;
55 22         76 my %p = @_;
56 22 100       112 $p{raw} = pack 'H*', $p{hex} unless (exists $p{raw});
57 22 100       86 $p{hex} = unpack 'H*', $p{raw} unless (exists $p{hex});
58 22         25 print STDERR "Queued: ", $p{hex}, ' ', ($p{desc}||''), "\n" if DEBUG;
59 22         27 push @{$self->{_q}}, \%p;
  22         64  
60 22 100       89 $self->_write_now unless ($self->{_waiting});
61 22         63 1;
62             }
63              
64             sub _write_now {
65 28     28   54 my $self = shift;
66 28         36 my $rec = shift @{$self->{_q}};
  28         71  
67 28         52 my $wait_record = $self->{_waiting};
68 28 100       70 if ($wait_record) {
69 19         37 delete $self->{_waiting};
70 19         34 my $cb = $wait_record->[1]->{callback};
71 19 100       61 $cb->() if ($cb);
72             }
73 28 100       105 return unless (defined $rec);
74 19         55 $self->_real_write($rec);
75 19         69 $self->{_waiting} = [ $self->_time_now, $rec ];
76             }
77              
78             sub _real_write {
79 19     19   35 my ($self, $rec) = @_;
80 19         21 print STDERR "Sending: ", $rec->{hex}, ' ', ($rec->{desc}||''), "\n" if DEBUG;
81 19         708 syswrite $self->{fh}, $rec->{raw}, length $rec->{raw};
82             }
83              
84              
85             sub filehandle {
86             shift->{fh}
87 26     26 1 1946 }
88              
89             sub _open {
90 11     11   24 my $self = shift;
91 11 100       123 $self->{device} =~ m![/\\]! ?
92             $self->_open_serial_port(@_) : $self->_open_tcp_port(@_)
93             }
94              
95             sub _open_tcp_port {
96 9     9   64 my $self = shift;
97 9         22 my $dev = $self->{device};
98 9         13 print STDERR "Opening $dev as tcp socket\n" if DEBUG;
99 9         2179 require IO::Socket::INET; import IO::Socket::INET;
  9         36557  
100 9 100       7007 $dev .= ':'.$self->{port} unless ($dev =~ /:/);
101 9 100       69 my $fh = IO::Socket::INET->new($dev) or
102             croak "TCP connect to '$dev' failed: $!";
103 4         2224 return $self->{fh} = $fh;
104             }
105              
106             sub _open_serial_port {
107 2     2   5 my $self = shift;
108 2         3 my $dev = $self->{device};
109 2         3 print STDERR "Opening $dev as serial port\n" if DEBUG;
110 2         8 my $fh = gensym();
111 2 50       41 my $sport = tie (*$fh, 'Device::SerialPort', $dev) or
112             croak "Could not tie serial port, $dev, to file handle: $!";
113 2         27 $sport->baudrate($self->baud);
114 2         19 $sport->databits(8);
115 2         13 $sport->parity("none");
116 2         14 $sport->stopbits(1);
117 2         12 $sport->datatype("raw");
118 2         12 $sport->write_settings();
119              
120 2 100       328 sysopen $fh, $dev, O_RDWR|O_NOCTTY|O_NDELAY or
121             croak "sysopen of '$dev' failed: $!";
122 1         12 $fh->autoflush(1);
123 1         49 return $self->{fh} = $fh;
124             }
125              
126              
127             sub baud {
128             shift->{baud}
129 3     3 1 20 }
130              
131             sub _time_now {
132 132     132   1167 Time::HiRes::time
133             }
134              
135             1;
136              
137             __END__