use FileHandle;
use SCX::CRC;
-our $PACKET_SIZE = 10;
+our $PACKET_SIZE = 9; # 9 bytes + 0x05
our $LOG_ROTATE = 600;
sub new {
die "Read error on $self->{portname}: $!"
if !$bytes_read;
- my $now = gettimeofday;
- if ($now - $self->{log_start} >= $LOG_ROTATE) {
- close $self->{logfh};
- $self->{log_gen} = $self->{log_gen} ? 0 : 1;
- open my $fh, '>', $logfile . '.' . $self->{log_gen}
- or die "Can't open $logfile.$self->{log_gen}: $!";
- $self->{logfh} = $fh;
- $self->{log_start} = $now;
- }
-
my @bytes = unpack("C*", $data);
- $self->{logfh}->print(sprintf('% 10.3f', $now - $self->{starttime}),
- (map { sprintf(" %02x", $_) } @bytes),
- "\n");
-
push @{ $self->{bytes} }, @bytes;
@bytes = @{ $self->{bytes} };
my @bad_bytes;
- while (@bytes >= 2) {
+ while (@bytes > $PACKET_SIZE) {
if ($bytes[0] != 0x55) {
push @bad_bytes, shift @bytes;
next;
}
my $cmd = $bytes[1];
- my $packet_size = $cmd >= 0x40 && $cmd <= 0x46 ? 4 : 9;
- last if @bytes <= $packet_size;
-
- if ($bytes[$packet_size] != 0x05
- || SCX::CRC::digest(@bytes[0..$packet_size-2])
- != $bytes[$packet_size-1]) {
+ if ($bytes[$PACKET_SIZE] != 0x05
+ || SCX::CRC::digest(@bytes[0..$PACKET_SIZE-2])
+ != $bytes[$PACKET_SIZE-1]) {
push @bad_bytes, shift @bytes;
next;
}
- if (@bad_bytes) {
- $self->{logfh}->print("Cannot parse bytes",
- (map { sprintf(' %02x', $_) } @bad_bytes),
- "\n");
+ if (@bad_bytes) { # Report previous bad bytes first
+ $self->log_bytes(\@bad_bytes, "Cannot parse packet");
@bad_bytes = ();
}
- $self->{logfh}->print("Callback\n");
- &{ $self->{callback} }(@bytes[1..$packet_size]);
- splice @bytes, 0, $packet_size+1;
- }
- if (@bad_bytes) {
- $self->{logfh}->print("Cannot parse bytes",
- (map { sprintf(' %02x', $_) } @bad_bytes),
- "\n");
- @bad_bytes = ();
+ my @packet = splice @bytes, 0, $PACKET_SIZE+1;
+ my $rv = &{ $self->{callback} }(@packet[1..$PACKET_SIZE]);
+ $self->log_bytes(@packet, $rv);
}
+ $self->log_bad_bytes(\@bad_bytes, "Cannot parse packet");
@{ $self->{bytes} } = @bytes;
}
+sub log_bytes {
+ my ($self, $bytes, $msg) = @_;
+
+ return if !@$bytes;
+
+ $msg = defined $msg ? ' # ' . $msg : '';
+
+ my $now = gettimeofday;
+
+ if ($now - $self->{log_start} >= $LOG_ROTATE) {
+ close $self->{logfh};
+ $self->{log_gen} = $self->{log_gen} ? 0 : 1;
+ open my $fh, '>', $logfile . '.' . $self->{log_gen}
+ or die "Can't open $logfile.$self->{log_gen}: $!";
+ $self->{logfh} = $fh;
+ $self->{log_start} = $now;
+ }
+
+ $self->{logfh}->print(sprintf('% 10.3f', $now - $self->{starttime}),
+ (map { sprintf(" %02x", $_) } @bytes),
+ $msg, "\n");
+}
+
1;