/
IO.pm
executable file
·63 lines (45 loc) · 1.78 KB
/
IO.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package Device::Firmdata::Role::IO;
use Moose::Role;
use Device::Firmdata::Util::Accumulator;
has portName => ( is => 'ro', isa => 'Str', required => 1);
has bytesRead => ( is => 'ro', isa => 'Device::Firmdata::Util::Accumulator', required => 1, default => sub { Device::Firmdata::Util::Accumulator->new(autoReset => 1) } );
has bytesSent => ( is => 'ro', isa => 'Device::Firmdata::Util::Accumulator', required => 1, default => sub { Device::Firmdata::Util::Accumulator->new(autoReset => 1) } );
requires 'read';
requires 'write';
use constant HEADER_CHANNEL_MASK => 248;
use constant HEADER_CHANNEL_SHIFT => 3;
use constant HEADER_SIZE_MASK => 7;
use constant HEADER_LENGTH => 1;
sub getHeader {
my ($self) = @_;
my $headerByte = $self->read(HEADER_LENGTH);
my $headerValue = unpack('C', $headerByte);
my $channel = ($headerValue & HEADER_CHANNEL_MASK) >> HEADER_CHANNEL_SHIFT;
my $length = $headerValue & HEADER_SIZE_MASK;
return ($channel, $length);
}
sub getMessage {
my ($self) = @_;
my ($channel, $length) = $self->getHeader;
my $content = $self->read($length) if $length > 0;
my $bytesRead = $length + HEADER_LENGTH;
$content = '' unless defined $content;
$self->bytesRead->add($bytesRead);
return ($channel, $content, $bytesRead);
}
sub sendHeader {
my ($self, $channel, $size) = @_;
my $header;
$header = $channel << HEADER_CHANNEL_SHIFT;
$header |= $size | HEADER_SIZE_MASK;
$self->write($header);
}
sub sendMessage {
my ($self, $channel, $content) = @_;
my $bytesSent = length($content);
$self->bytesSent->add($bytesSent);
#TODO - update command.c and message.c to support commands embeded in messages
#$self->sendHeader($channel, length($content));
$self->write($content);
}
1;