5 use Time::HiRes qw(gettimeofday tv_interval);
9 our $PACKET_SIZE = 9; # 9 bytes + 0x05
10 our $LOG_ROTATE = 600;
13 my ($class, $args) = @_;
15 my $callback = $args->{callback}
16 or die "callback arg not defined";
18 my $portname = $args->{portname}
19 or die "portname not specified";
21 system 'stty', '-F', $portname, '115200', 'raw';
23 die "stty died with code $? (no permissions?)";
26 open my $tty, '<:raw', $portname
27 or die "Can't open $portname: $!";
29 my $logfile = $args->{logfile};
32 open my $logfh, '>', "$logfile.$log_gen"
33 or die "Can't open $logfile.$log_gen: $!";
35 my $now = gettimeofday;
38 portname => $portname,
45 callback => $callback,
54 sub fh { return shift->{fh}; }
60 my $bytes_read = sysread $self->fh, $data, $PACKET_SIZE;
61 die "Read error on $self->{portname}: $!"
64 my @bytes = unpack("C*", $data);
66 push @{ $self->{bytes} }, @bytes;
67 @bytes = @{ $self->{bytes} };
71 while (@bytes > $PACKET_SIZE) {
72 if ($bytes[0] != 0x55) {
73 push @bad_bytes, shift @bytes;
78 if ($bytes[$PACKET_SIZE] != 0x05
79 || SCX::CRC::digest(@bytes[0..$PACKET_SIZE-2])
80 != $bytes[$PACKET_SIZE-1]) {
81 push @bad_bytes, shift @bytes;
85 if (@bad_bytes) { # Report previous bad bytes first
86 $self->log_bytes(\@bad_bytes, "Cannot parse packet");
90 my @packet = splice @bytes, 0, $PACKET_SIZE+1;
91 my $rv = &{ $self->{callback} }(@packet[1..$PACKET_SIZE]);
92 $self->log_bytes(@packet, $rv);
94 $self->log_bad_bytes(\@bad_bytes, "Cannot parse packet");
96 @{ $self->{bytes} } = @bytes;
100 my ($self, $bytes, $msg) = @_;
104 $msg = defined $msg ? ' # ' . $msg : '';
106 my $now = gettimeofday;
108 if ($now - $self->{log_start} >= $LOG_ROTATE) {
109 close $self->{logfh};
110 $self->{log_gen} = $self->{log_gen} ? 0 : 1;
111 open my $fh, '>', $logfile . '.' . $self->{log_gen}
112 or die "Can't open $logfile.$self->{log_gen}: $!";
113 $self->{logfh} = $fh;
114 $self->{log_start} = $now;
117 $self->{logfh}->print(sprintf('% 10.3f', $now - $self->{starttime}),
118 (map { sprintf(" %02x", $_) } @bytes),