File Coverage

blib/lib/BT368i/Serial.pm
Criterion Covered Total %
statement 14 96 14.5
branch 1 60 1.6
condition 0 17 0.0
subroutine 5 11 45.4
pod 0 2 0.0
total 20 186 10.7


line stmt bran cond sub pod time code
1             #
2             # Written by Travis Kent Beste
3             # Fri Aug 6 14:29:27 CDT 2010
4              
5             package BT368i::Serial;
6              
7 1     1   5 use strict;
  1         1  
  1         39  
8 1     1   5 use vars qw( $has_serialport );
  1         1  
  1         60  
9              
10 1     1   1703 use Data::Dumper;
  1         17807  
  1         185  
11              
12             our @ISA = qw( );
13             our $VERSION = sprintf("%d.%02d", q$Revision: 1.00 $ =~ /(\d+)\.(\d+)/);
14              
15             $|++;
16              
17             #----------------------------------------#
18             #
19             #----------------------------------------#
20             BEGIN {
21 1 50   1   79 if (eval q{ use Device::SerialPort; 1 }) {
  1     1   2120  
  1         68356  
  1         126  
22 1         1826 $has_serialport++;
23             } else {
24 0         0 die "Missing Device::SerialPort";
25             }
26             }
27              
28             #----------------------------------------#
29             #
30             #----------------------------------------#
31             $SIG{ALRM} = sub {
32             print "\nserial port timed out.\n";
33             exit -1;
34             };
35              
36             #----------------------------------------#
37             #
38             #----------------------------------------#
39             sub connect {
40 0     0 0   my $self = shift;
41 0 0         return $self->{serial} if $self->{serial};
42              
43             # set a timeout
44 0           alarm($self->{serialtimeout});
45              
46 0 0         print "connecting to serial port..." if ($self->{verbose});
47              
48 0           my $PortObj = new Device::SerialPort($self->{serialport});
49 0           $PortObj->baudrate($self->{serialbaud});
50 0           $PortObj->parity("none");
51 0           $PortObj->databits(8);
52 0           $PortObj->stopbits(1);
53 0           $self->{serial} = $PortObj;
54              
55             # remove timeout
56 0           alarm(0);
57              
58 0 0         print "done\n" if ($self->{verbose});
59             }
60              
61             #----------------------------------------#
62             #
63             #----------------------------------------#
64             sub usleep {
65 0     0 0   my $l = shift;
66 0   0       $l = ref($l) && shift;
67 0           select( undef,undef,undef,($l/1000) );
68             }
69              
70             #----------------------------------------#
71             #
72             #----------------------------------------#
73             sub _read {
74 0     0     my $self = shift;
75 0           my $sub_debug = 0;
76 0           my $cnt = 0;
77              
78 0           my $count = 0;
79 0           my $byte = '';
80 0           ($count, $byte) = $self->{serial}->read(1);
81 0 0         if ($count == 0) {
82 0           return 0;
83             }
84 0 0         printf "$byte" if ($sub_debug);
85 0           $self->{ringbuffer}->ring_add(ord($byte));
86              
87 0           while ($count > 0) {
88 0           ($count, $byte) = $self->{serial}->read(1);
89 0 0         if ($count > 0) {
90 0 0         printf "$byte" if ($sub_debug);
91 0           $self->{ringbuffer}->ring_add(ord($byte));
92             }
93 0           $cnt += $count;
94             }
95              
96             # wow, just adding this here totaly sped things up
97 0           $self->{serial}->lookclear();
98              
99 0           return $cnt;
100             }
101              
102             #----------------------------------------#
103             #
104             #----------------------------------------#
105             sub _have_telegram {
106 0     0     my $self = shift;
107 0           my $size = $self->{ringbuffer}->ring_size();
108 0           my $j = $self->{ringbuffer}->{tail};
109 0           my $count = 0;
110 0           my @rv = ();
111              
112 0           for(my $i = 0; $i < $size; $i++) {
113 0 0         if ($j == $self->{ringbuffersize}) {
114 0           $j = 0;
115             }
116             #printf "->%s\n", $self->{ringbuffer}->{buffer}[$j];
117              
118             # count the dollar signs '$'
119 0 0         if ($self->{ringbuffer}->{buffer}[$j] eq '$') {
120 0           $count++;
121 0 0         if ($count == 1) {
    0          
122 0           push(@rv, $j); # get the start
123             } elsif ($count == 2) {
124 0           push(@rv, $j); # get the end
125             }
126             }
127              
128 0           $j++;
129             }
130              
131 0           return ($count, \@rv);
132             }
133              
134             #----------------------------------------#
135             #
136             #----------------------------------------#
137             sub _readlines {
138 0     0     my $self = shift;
139 0           my $done = 0;
140 0           my @lines = ();
141              
142             #local $SIG{ALRM} = sub {die "BT368i bluetooth connection has timed out\n"};
143             #eval { alarm($self->{timeout}) };
144            
145 0           while (! $done) {
146 0           my $count = $self->_read();
147 0           my $ringsize = $self->{ringbuffer}->ring_size();
148              
149 0 0 0       if ($ringsize || $count) {
150 0           my $loop_stop = $count;
151 0 0         if ($loop_stop == 0) {
152 0           $loop_stop = $ringsize;
153             }
154              
155 0           for(my $i = 0; $i < $loop_stop; $i++) {
156 0           my $byte = $self->{ringbuffer}->ring_remove();
157              
158             # start character is a '$'
159 0 0         if ($byte == 0x24) {
    0          
    0          
160 0           $self->{serialline} = sprintf("%c", $byte);
161             #printf("%c", $byte);
162              
163             } elsif ($byte == 0x0d) {
164              
165             #printf("%02x ", $byte);
166              
167             } elsif ($byte == 0x0a) {
168              
169 0 0         if ($self->{serialline} =~ /\$GPGLL/) {
    0          
    0          
    0          
    0          
    0          
170             #print "->" . $self->{serialline} . "\n";
171             } elsif ($self->{serialline} =~ /\$GPGSV/) {
172             #print "->" . $self->{serialline} . "\n";
173             } elsif ($self->{serialline} =~ /\$GPGGA/) {
174             #print "->" . $self->{serialline} . "\n";
175             } elsif ($self->{serialline} =~ /\$GPGSA/) {
176             #print "->$self->{serialline} . "\n";
177             } elsif ($self->{serialline} =~ /\$GPRMC/) {
178             #print "->" . $self->{serialline} . "\n";
179             } elsif ($self->{serialline} =~ /\$GPVTG/) {
180             #print "->" . $self->{serialline} . "\n";
181             } else {
182             #print "GARBAGE:" . $self->{serialline} . "\n";
183             }
184              
185             #printf("%02x ", $byte);
186 0           my $checksum = substr ($self->{serialline}, -3);
187             # verify that it starts with '$GP...' and ends with '*..'
188 0 0 0       if ( ($self->{serialline} =~ /^\$GP...\,/) && ($checksum =~ /\*..$/) ) {
189             #print "-->$self->{serialline}<--\n";
190             #$i = $count; # stop for loop
191             #$done = 1; # stop while loop
192 0           push(@lines, $self->{serialline});
193             }
194              
195             } else {
196              
197 0 0 0       if ( ($byte => 0x20) && ($byte <= 0x7f) ){
198 0           $self->{serialline} .= sprintf("%c", $byte);
199             #printf("%c", $byte);
200             } else {
201             #printf("[%02x]", $byte);
202             }
203             }
204             }
205             } else {
206 0           $done = 1;
207             }
208              
209             #eval { alarm($self->{timeout}) }; # set new timeout
210             }
211              
212 0           return \@lines;
213             }
214              
215             #----------------------------------------#
216             #
217             #----------------------------------------#
218             sub _write {
219             #$self->_write(buffer,length)
220             #syswrite wrapper for the serial device
221             #length defaults to buffer length
222              
223 0     0     my ($self,$buf,$len,$offset) = @_;
224 0 0         $self->connect() or die "Write to an uninitialized handle";
225              
226 0   0       $len ||= length($buf);
227              
228 0 0         if ($self->{verbose}) {
229 0           print STDERR "W:(",join(" ", map {$self->Pid_Byte($_)}unpack("C*",$buf)),")\n";
  0            
230             }
231              
232 0 0         $self->{serial} or die "Write to an uninitialized handle";
233              
234 0 0         if ($self->{serialtype} eq 'FileHandle') {
235 0   0       syswrite($self->serial,$buf,$len,$offset||0);
236             } else {
237 0           my $out_len = $self->serial->write($buf);
238 0 0         warn "Write incomplete ($len != $out_len)\n" if ( $len != $out_len );
239             }
240             }
241              
242             1;
243              
244             __END__