Community discussions

MikroTik App
 
mmtik
just joined
Topic Author
Posts: 13
Joined: Tue Jun 07, 2016 3:28 pm

Problem or bug in API

Tue Jun 07, 2016 4:01 pm

We have variable "status" in environment.

Run the command by API:
>>> /system/script/environment/set
>>> =numbers=status
>>> =value=1465304159
Check read_len, got '5'
recv 5
<<< !done
Check read_len, got '0'

>>> /ip/firewall/address-list/add
>>> =address=10.20.20.253
>>> =list=accept
Check read_len, got '5'
recv 5
<<< !done
Check read_len, got '8'
recv 8
<<< =ret=*3C
Check read_len, got '0'
We dont have variable "status" in environment.
Run the command:
>>> /system/script/environment/set
>>> =numbers=status
>>> =value=1465304300
Check read_len, got '5'
recv 5
<<< !trap
Check read_len, got '21'
recv 21
<<< =message=no such item
Check read_len, got '0'

>>> /ip/firewall/address-list/add
>>> =address=10.20.20.253
>>> =list=accept
Check read_len, got '5'
recv 5
<<< !done
Check read_len, got '0'
Command "/ip/firewall/address-list/add" is not apply...

P.S.
version: 6.35.1 (stable)
cpu: MIPS 24Kc V7.4
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Problem or bug in API

Tue Jun 07, 2016 4:17 pm

What about
/set
=name=status
=value=1465304159
(assuming the variable already exists)

or
/global
=name=status
=value=1465304159
(if it doesn't)
 
mmtik
just joined
Topic Author
Posts: 13
Joined: Tue Jun 07, 2016 3:28 pm

Re: Problem or bug in API

Wed Jun 08, 2016 8:29 am

Not variable problem. It is taken as an example.

The problem is that the subsequent instruction is not satisfied ...
More accurately - it will be done after the following command:
>>> /system/script/environment/set
>>> =numbers=status
>>> =value=1465363657
Check read_len, got '5'
recv 5
<<< !trap
Check read_len, got '21'
recv 21
<<< =message=no such item
Check read_len, got '0'

>>> /ip/firewall/address-list/add
>>> =address=10.20.20.253
>>> =list=accept
Check read_len, got '5'
recv 5
<<< !done
Check read_len, got '0'


>>> /system/script/environment/print
Check read_len, got '5'
recv 5
<<< !done
Check read_len, got '8'
recv 8
<<< =ret=*3E
Check read_len, got '0'
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Problem or bug in API

Sat Jun 11, 2016 4:53 am

Right. The "/system/environment/print" is the one that fails... But what I'm saying is that it fails because the command
/system/script/environment/set
=numbers=status
=value=1465363657
Fails.

The failure is detectable - that's what the !trap is, i.e. the part
!trap
=message=no such item
is telling you that the "set" failed, supposedly because the variable doesn't exist prior to the call.

And if you want to create the variable, you need to use "/global" instead of "/system/script/environment/set".
 
mmtik
just joined
Topic Author
Posts: 13
Joined: Tue Jun 07, 2016 3:28 pm

Re: Problem or bug in API

Mon Jun 13, 2016 2:30 pm

The problem is not the creation of a variable. The problem is the following command after creating the variable.

If the command has caused the error, execution of subsequent commands via the API becomes problematic.
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: Problem or bug in API

Tue Jun 14, 2016 10:48 am

You cannot get the value if you have not set it in the first place. No variable - no value to get.
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Problem or bug in API

Tue Jun 14, 2016 2:21 pm

Aaah. I see it now. You're intentionally causing a !trap to demonstrate its handling...

But I'm not sure the bug is in RouterOS. It looks more like a bug of either your API client of choice (which one is it anyway?) or the code you're using around it.

When there are errors, RouterOS returns a !trap reply AND a !done reply, not just a !trap reply. At the same time, a command is only REALLY executed when you receive its !done reply. What your code does is that it sends two commands, but only keeps reading until it gets one !done reply, and it should instead keep reading until it gets two !done replies.

How exactly should you solve this depends on whether the bug is in the API client or your code. Show us the code you're using.
 
mmtik
just joined
Topic Author
Posts: 13
Joined: Tue Jun 07, 2016 3:28 pm

Re: Problem or bug in API

Mon Jun 27, 2016 2:22 pm

Using PERL API based on https://github.com/akschu/MikroTikPerl, with my rework.

sub read_byte{
    my $line;

    if ($error_msg) {return 0}

    eval {
        local $SIG{__DIE__} = 'IGNORE';
        local $SIG{ALRM} = sub {die};
        alarm 5;
        eval {
            $sock->read($line,1);
        };
        alarm 0;
    };
    alarm 0;

    if ($!){
    $error_msg=$!;
    if ($debug > 4)
    {
        print "\nERROR: $!\n";
    }
    return 0;
    }

    return ord($line);
}

sub read_len {
    my $len;

    if ($debug > 4) {print "Check read_len"}
    $len = read_byte();
    if ($debug > 4) {print ", got '$len'\n"}

    if ($len==0) {
    $error_len++;
    if ($error_len>3){$error_msg='connection lost'}
    } else {$error_len=0}

    if (($len & 0x80) == 0x00)
    {
    return $len
    }
    elsif (($len & 0xC0) == 0x80)
    {
        $len &= ~0x80;
        $len <<= 8;
        $len += read_byte();
    }
    elsif (($len & 0xE0) == 0xC0)
    {
    $len &= ~0xC0;
        $len <<= 8;
        $len += read_byte();
        $len <<= 8;
        $len += read_byte();
    }
    elsif (($len & 0xF0) == 0xE0)
    {
        $len &= ~0xE0;
        $len <<= 8;
        $len += read_byte();
        $len <<= 8;
        $len += read_byte();
        $len <<= 8;
        $len += read_byte();
    }
    elsif (($len & 0xF8) == 0xF0)
    {
        $len = read_byte();
        $len <<= 8;
        $len += read_byte();
        $len <<= 8;
        $len += read_byte();
        $len <<= 8;
        $len += read_byte();
    } 

    return $len;
}
focus on problem:
after recive from router: "=message=no such item"
check the router is still something send to me, but not send: "Check read_len, got '0'"
 
User avatar
janisk
MikroTik Support
MikroTik Support
Posts: 6263
Joined: Tue Feb 14, 2006 9:46 am
Location: Riga, Latvia

Re: Problem or bug in API

Mon Jun 27, 2016 4:05 pm

when you send a command to the router, router will respond with the response and then indicate that it ended sending stuff. In your case it sends !trap as your command caused some error and then sends !done, indicating that the command is done.
see here for examples:

http://wiki.mikrotik.com/wiki/Manual:AP ... d_examples

->> /command
<<- !re  item
<<- !re item
<<- !done


when you have traps, see /cancel command example where you can cancel individual tagged commands or what happens when you cancel everything.
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: Problem or bug in API

Mon Jun 27, 2016 5:18 pm

Using PERL API based on https://github.com/akschu/MikroTikPerl, with my rework.
focus on problem:
after recive from router: "=message=no such item"
check the router is still something send to me, but not send: "Check read_len, got '0'"
OK, that's your API client... And the Perl code from which you call it (feel free to replace your router credentials)?

Trying a similar test with my router (and API client), I get, as expected:
MODE |   LENGTH    |    LENGTH    |  CONTENTS
     |  (decoded)  |  (encoded)   |
-----|-------------|--------------|--------------------------------------------
SEND |    <prompt> |     <prompt> | /system/script/environment/set

SEND |    <prompt> |     <prompt> | =numbers=status

SEND |    <prompt> |     <prompt> | =value=1465363657

SEND |    <prompt> |     <prompt> |

SENT |          30 |         0x1E | /system/script/environment/set
SENT |          15 |         0x0F | =numbers=status
SENT |          17 |         0x11 | =value=1465363657
SENT |           0 |         0x00 |
RECV |           5 |         0x05 | !trap
RECV |          21 |         0x15 | =message=no such item
RECV |           0 |         0x00 |
SEND |    <prompt> |     <prompt> | /put

SEND |    <prompt> |     <prompt> | =message=test

SEND |    <prompt> |     <prompt> |

SENT |           4 |         0x04 | /put
SENT |          13 |         0x0D | =message=test
SENT |           0 |         0x00 |
RECV |           5 |         0x05 | !done
RECV |           0 |         0x00 |
SEND |    <prompt> |     <prompt> |

SENT |           0 |         0x00 |
RECV |           5 |         0x05 | !done
RECV |           9 |         0x09 | =ret=test
RECV |           0 |         0x00 |
SEND |    <prompt> |     <prompt> |

SENT |           0 |         0x00 |
NOTE |    Receiving timed out     |
SEND |    <prompt> |     <prompt> | /quit

SEND |    <prompt> |     <prompt> |

SENT |           5 |         0x05 | /quit
SENT |           0 |         0x00 |
RECV |           6 |         0x06 | !fatal
RECV |          29 |         0x1D | session terminated on request
RECV |           0 |         0x00 |
NOTE |   Connection terminated    |
Notice how I do the second command before I get the first one's !done... Maybe if you were to keep reading until the !done sentence, and only send the second command there, it would work as you'd expect, e.g.
MODE |   LENGTH    |    LENGTH    |  CONTENTS
     |  (decoded)  |  (encoded)   |
-----|-------------|--------------|--------------------------------------------
SEND |    <prompt> |     <prompt> | /system/script/environment/set

SEND |    <prompt> |     <prompt> | =numbers=status

SEND |    <prompt> |     <prompt> | =value=1465363657

SEND |    <prompt> |     <prompt> |

SENT |          30 |         0x1E | /system/script/environment/set
SENT |          15 |         0x0F | =numbers=status
SENT |          17 |         0x11 | =value=1465363657
SENT |           0 |         0x00 |
RECV |           5 |         0x05 | !trap
RECV |          21 |         0x15 | =message=no such item
RECV |           0 |         0x00 |
RECV |           5 |         0x05 | !done
RECV |           0 |         0x00 |
NOTE |    Receiving timed out     |
SEND |    <prompt> |     <prompt> | /put

SEND |    <prompt> |     <prompt> | =message=test

SEND |    <prompt> |     <prompt> |

SENT |           4 |         0x04 | /put
SENT |          13 |         0x0D | =message=test
SENT |           0 |         0x00 |
RECV |           5 |         0x05 | !done
RECV |           9 |         0x09 | =ret=test
RECV |           0 |         0x00 |
NOTE |    Receiving timed out     |
SEND |    <prompt> |     <prompt> | /quit

SEND |    <prompt> |     <prompt> |

SENT |           5 |         0x05 | /quit
SENT |           0 |         0x00 |
RECV |           6 |         0x06 | !fatal
RECV |          29 |         0x1D | session terminated on request
RECV |           0 |         0x00 |
NOTE |   Connection terminated    |

Who is online

Users browsing this forum: No registered users and 8 guests