API-MikroTik
view release on metacpan or search on metacpan
lib/API/MikroTik.pm view on Meta::CPAN
},
sub {
$self->$cb($_[1]);
},
);
}
sub _read {
my ($self, $loop, $bytes) = @_;
warn "-- read bytes from socket: " . (length $bytes) . "\n" if DEBUG;
my $response = $self->{responses}{$loop} ||= API::MikroTik::Response->new();
my $data = $response->parse(\$bytes);
for (@$data) {
next unless my $r = $self->{requests}{delete $_->{'.tag'}};
my $type = delete $_->{'.type'};
push @{$r->{data} ||= Mojo::Collection->new()}, $_
if %$_ && !$r->{subscription};
lib/API/MikroTik/Sentence.pm view on Meta::CPAN
sub is_incomplete {
return exists $_[0]->{_buff};
}
sub reset {
delete @{$_[0]}{qw(words _buff)};
return $_[0];
}
sub _encode_length {
my $len = shift;
my $packed;
# Screw you, mikrotik engineers, just pack length as 4 bytes. >_<
if ($len < 0x80) {
$packed = pack 'C', $len;
}
elsif ($len < 0x4000) {
$packed = pack 'n', ($len | 0x8000) & 0xffff;
}
elsif ($len < 0x200000) {
$len |= 0xc00000;
$packed = pack 'Cn', (($len >> 16) & 0xff), ($len & 0xffff);
}
lib/API/MikroTik/Sentence.pm view on Meta::CPAN
$packed = pack 'N', ($len | 0xe0000000);
}
else {
$packed = pack 'CN', 0xf0, $len;
}
return $packed;
}
sub _encode_word {
return _encode_length(length($_[0])) . $_[0];
}
sub _fetch_word {
my ($self, $buff) = @_;
return $self->{_buff} = '' unless my $buff_bytes = length $$buff;
return do { $self->{_buff} = $$buff; $$buff = ''; }
if $buff_bytes < 5 && $$buff ne "\x00";
my $len = _strip_length($buff);
my $word = substr $$buff, 0, $len, '';
return do { $self->{_buff} = _encode_length($len) . $word; ''; }
if (length $word) < $len;
return $word;
}
sub _strip_length {
my $buff = shift;
my $len = unpack 'C', substr $$buff, 0, 1, '';
if (($len & 0x80) == 0x00) {
return $len;
}
elsif (($len & 0xc0) == 0x80) {
$len &= ~0x80;
$len <<= 8;
t/lib/API/MikroTik/Mockup.pm view on Meta::CPAN
return (
['!trap', {category => 2, message => 'interrupted'}, undef, $cmd_tag],
_done($tag), _done($cmd_tag));
}
sub cmd_close_premature {
my ($self, $attr) = @_;
my $sent = encode_sentence('!re', {message => 'response'}, undef,
$attr->{'.tag'});
substr $sent, (length($sent) / 2), -1, '';
$self->{h}->write($sent);
$self->ioloop->timer(0.5 => sub { $self->{h}->close() });
return ();
}
sub cmd_err {
my (undef, $attr) = @_;
my $tag = $attr->{'.tag'};
t/sentence.t view on Meta::CPAN
use warnings;
use strict;
use lib './';
use Test::More;
use API::MikroTik::Sentence qw(encode_sentence);
my $s = API::MikroTik::Sentence->new();
# length encoding
my ($packed, $len);
for (0x7f, 0x3fff, 0x1fffff, 0xfffffff, 0x10000000) {
$packed = API::MikroTik::Sentence::_encode_length($_);
($len, undef) = API::MikroTik::Sentence::_strip_length(\$packed);
is $len, $_, "length encoding: $_";
}
# encode word
my $encoded = API::MikroTik::Sentence::_encode_word('bla' x 3);
$encoded .= API::MikroTik::Sentence::_encode_word('bla' x 50);
is length($encoded), 162, 'right length';
is $s->_fetch_word(\$encoded), 'bla' x 3, 'right decoded word';
is length($encoded), 152, 'right length';
is $s->_fetch_word(\$encoded), 'bla' x 50, 'right decoded word';
$packed = encode_sentence('/cmd/1', {a => 1, b => 2});
$packed
.= encode_sentence('/cmd/2', {c => 'foo', d => 'bar'}, {e => 'baz'}, 11);
my $words = $s->fetch(\$packed);
is shift @$words, '/cmd/1', 'right command';
is_deeply [sort @$words], ['=a=1', '=b=2'], 'right attributes';
$words = $s->fetch(\$packed);
is shift @$words, '/cmd/2', 'right command';
( run in 0.659 second using v1.01-cache-2.11-cpan-65fba6d93b7 )