How to use tool-bandwidth function using PHP API

Dear expert

  1. I tested command"tool bandwidth test address=192.168.88.99 protocol=udp direction=both username=admin password=‘’
    as show in mtik_bwtest.jp before s
    2.However,I must coding PHP_API to call bandwidth tool command as shown below
    But it did not work and I found error "HTTP 505 internal server Error "at the IE again.
  2. Can I retrieve the value of variable such as tx-current’, rx-current…?
    Please advise
    Banatus S

Here is bwtest.php

<?php use PEAR2\Net\RouterOS; include_once 'PEAR2_Net_RouterOS-1.0.0b4.phar'; try { $client = new RouterOS\Client('192.168.88.98', 'admin', ''); $util = new RouterOS\Util($client); $util->changeMenu('/tool bandwidth-test address='192.168.88.99' protocol='udp' direction='both' user='admin' password='''); $tx-current = $util->get(0, 'tx-current'); echo $util->get(0,'tx-current'); } catch (Exception $e) { echo 'Unable to connect and/or login to the router'; } ![mtik_bwtest.jpg|737x429](upload://juUAOgMuLPDHMdFlE6v2vWCxxsZ.jpeg)

“bandwidth-test” is a command, and as the name “changeMenu” implies, you can only navigate to menus with it.

To run this command, you’d have to use the Client (not Util). Also - double quotes in the arguments, not single ones - THAT is probably the cause of the HTTP error.

If I remember correctly, bandwidth-test is a continuous command - you need to explicitly cancel it at some point. In that case, you need to use async requests - a request where you start the reply at one point, and get responses one by one “later”. This lets you cancel the request eventually.

<?php 
use PEAR2\Net\RouterOS;
include_once 'PEAR2_Net_RouterOS-1.0.0b4.phar';

try {
$client = new RouterOS\Client('192.168.88.98', 'admin', '');
$count = 0;//Count the number of replies we've had.
$client->sendAsync(new RouterOS\Request('/tool bandwidth-test address="192.168.88.99" protocol="udp" direction="both" user="admin" password=""', null, 't'), function ($response) use (&$count) {
    $count++;
    if (10 === $count) {
        return true;//Cancel after 10 replies. Note that we'd get 2 additional responses, but we won't cancel on them.
    }

    if ($response->getType() == RouterOS\Response::TYPE_DATA) {
        echo $response->getArgument('tx-current') . "\n";
    }
});

$client->completeRequest('t');

} catch (Exception $e) {
 echo 'Unable to connect and/or login to the router';
} 

There are also several other approaches you can take, the easiest of which would be to simply add “interval” and “duration”, and make the request synchronous. Without “duration”, your script will hang, because it would loop infinitely if not canceled (as above). Without “interval”, you’d potentially be getting hundreds of messages, which would exhaust your server and/or browser’s memory.

Here’s an example that will again get 1 message every second, for a total of 10 seconds (or, you should get 9 or 10 messages):

<?php 
use PEAR2\Net\RouterOS;
include_once 'PEAR2_Net_RouterOS-1.0.0b4.phar';

try {
$client = new RouterOS\Client('192.168.88.98', 'admin', '');
$count = 0;//Count the number of replies we've had.
$responses = $client->sendSync(new RouterOS\Request('/tool bandwidth-test address="192.168.88.99" protocol="udp" direction="both" user="admin" password="" interval=1 duration=10'));

foreach ($responses->getAllOfType(RouterOS\Response::TYPE_DATA) as $response) {
    echo $response->getArgument('tx-current') . "\n";
} 

Thank you so much boen_robot , I appreciate with you kindness so much.
Actually, The first code (long code) run correctly,
The results are 9 numbers like this" 0 0 8026648 9755608 11160464 15805000 20767088 22864736 20985312 "
I think 0 0, it means waiting for negotiation.
Question

  1. " t" is stand for what?
    $client->sendAsync(new RouterOS\Request(‘/tool bandwidth-test address=“192.168.88.99” protocol=“udp” direction=“both” user=“admin” password=“”’, null, ‘t’), function ($response) use (&$count) {
  2. What is “t” in this line "$client->completeRequest(‘t’);?
  3. The second code (short code) is not running properly.
    The result appears "HTTP 500 interval server again.
    I’m sure I test with your code correctly;
    Here is second code:
<?php use PEAR2\Net\RouterOS; include_once 'PEAR2_Net_RouterOS-1.0.0b4.phar'; try { $client = new RouterOS\Client('192.168.88.98', 'admin', ''); $count = 0;//Count the number of replies we've had. $responses = $client->sendSync(new RouterOS\Request('/tool bandwidth-test address="192.168.88.99" protocol="udp" direction="both" user="admin" password="" interval=1 duration=10')); foreach ($responses->getAllOfType(RouterOS\Response::TYPE_DATA) as $response) { echo $response->getArgument('tx-current') . "\n"; }

Oops. I missed the “catch” at the second example. And there’s no need for the counter there either… So:

<?php 
use PEAR2\Net\RouterOS;
include_once 'PEAR2_Net_RouterOS-1.0.0b4.phar';

try {
    $client = new RouterOS\Client('192.168.88.98', 'admin', '');
    $responses = $client->sendSync(new RouterOS\Request('/tool bandwidth-test address="192.168.88.99" protocol="udp" direction="both" user="admin" password="" interval=1 duration=10'));

    foreach ($responses->getAllOfType(RouterOS\Response::TYPE_DATA) as $response) {
        echo $response->getArgument('tx-current') . "\n";
    }
} catch (Exception $e) {
 echo 'Unable to connect and/or login to the router';
} 



  1. " t" is stand for what?
  2. What is “t” in this line "$client->completeRequest(‘t’);?

The “t” does not stand for anything - it’s an identifier that can be anything you want, as long as it is the same in both places.

The identifier in both places is what the protocol calls a “tag”. When you send a request over the protocol with a tag, RouterOS replies with responses that contain that same tag. If you send several requests at once, using (different) tags is the only way to tell apart the responses for one request from those of the other ones. This is in fact why sendAsync() forces you to supply tags for each request you send with it - because you could call it several times before you start receiving responses, at which point telling the responses apart would be impossible if you hadn’t supplied a tag. Similarly, sendSync() does not force you to supply a tag, because you start receiving responses as soon as you send the request, and it’s therefore clear that if you don’t have a tag, all of the “without a tag” responses are those that you want.

As for completeRequest() - this starts receiving responses until the request with the specified tag is completed (i.e. a !done response is received that has the specified tag). In this case, this essentially means we’re finishing all requests, but if you were sending more than one request at a time, this isn’t necessarily true, since you could never be sure at what order will RouterOS complete each request.

The aforementioned “other” approaches, and this one, are explained at this page in the wiki (though I’m starting to think I should maybe rewrite that…).

Hi Boen_robot
1.I tried to use the second code. It didn’t work again please advise;

<?php use PEAR2\Net\RouterOS; include_once 'PEAR2_Net_RouterOS-1.0.0b4.phar'; try { $client = new RouterOS\Client('192.168.88.98', 'admin', ''); $responses = $client->sendSync(new RouterOS\Request('/tool bandwidth-test address="192.168.88.99" protocol="udp" direction="both" user="admin" password="" interval=1 duration=10')); foreach ($responses->getAllOfType(RouterOS\Response::TYPE_DATA) as $response) { echo $response->getArgument('tx-current') . "\n"; } } catch (Exception $e) { echo 'Unable to connect and/or login to the router'; } 2.I use first code for retrieving more values in Bandwidth test function. (tx-current, tx-10-second-average,rx-current, rx-10second) How to retrieve more values at the same time? Here is modified the first code. Please advise; <?php use PEAR2\Net\RouterOS; include_once 'PEAR2_Net_RouterOS-1.0.0b4.phar'; try { $client = new RouterOS\Client('192.168.88.98', 'admin', ''); $count = 0;//Count the number of replies we've had. $client->sendAsync(new RouterOS\Request('/tool bandwidth-test address="192.168.88.99" protocol="udp" direction="both" user="admin" password=""', null, 't'), function ($response) use (&$count) { $count++; if (10 === $count) { return true;//Cancel after 10 replies. Note that we'd get 2 additional responses, but we won't cancel on them. } if ($response->getType() == RouterOS\Response::TYPE_DATA) { echo $response->getArgument('tx-current') . "\n"; } if ($response->getType() == RouterOS\Response::TYPE_DATA) { echo $response->getArgument('tx-10-second-average') . "\n"; } if ($response->getType() == RouterOS\Response::TYPE_DATA) { echo $response->getArgument('rx-current') . "\n"; } if ($response->getType() == RouterOS\Response::TYPE_DATA) { echo $response->getArgument(''rx-10-second-average') . "\n"; } }); $client->completeRequest('t'); } catch (Exception $e) { echo 'Unable to connect and/or login to the router'; } 3.Can I use Bandwidth test function from one to multipoint at the same time as shown in figure mpoint.jpg? 4.How to use command? 5.How to write php.code? ![mpoint.jpg|416x341](upload://dKB9oKgF8MR4QY9EQzn12xSXMoQ.jpeg)

1.I tried to use the second code. It didn’t work again please advise;

That’s odd… I tried it myself, just replacing the IP and credentials (I don’t have a second router, so I just made the router do a bandwidth test with one of its other IPs), and it worked. It does however take surprisingly long for it to finish. It’s almost as if RouterOS doesn’t honor the duration argument, or is perhaps multiplying it by a large factor. The interval argument seems to work though, so if you want your data to span 10 seconds, you’d need to add interval=1 as an argument, while keeping the counter.

2.I use first code for retrieving more values in Bandwidth test function.

Everything returned at each response is available with getArgument(), where you supply the desired value, just as what you’re doing in your modified code.

You don’t need to check the response type every time though - just once before accessing any value. Also, you have two single quotes, which apparently are causing a syntax error. So

<?php 
use PEAR2\Net\RouterOS;
include_once 'PEAR2_Net_RouterOS-1.0.0b4.phar';

try {
$client = new RouterOS\Client('192.168.88.98', 'admin', '');
$count = 0;//Count the number of replies we've had.
$client->sendAsync(new RouterOS\Request('/tool bandwidth-test address="192.168.88.99" protocol="udp" direction="both" user="admin" password="" interval=1', null, 't'), function ($response) use (&$count) {
 $count++;
 if (10 === $count) {
 return true;//Cancel after 10 replies. Note that we'd get 2 additional responses, but we won't cancel on them.
 }

 if ($response->getType() == RouterOS\Response::TYPE_DATA) {
 echo $response->getArgument('tx-current') . "\n";
 echo $response->getArgument('tx-10-second-average') . "\n";
 echo $response->getArgument('rx-current') . "\n";
 echo $response->getArgument('rx-10-second-average') . "\n";
 }

});

$client->completeRequest('t');

} catch (Exception $e) {
 echo 'Unable to connect and/or login to the router';
}  



3.Can I use Bandwidth test function from one to multipoint at the same time as shown in figure mpoint.jpg?
4.How to use command?
5.How to write php.code?

Sure. Just send a new request for each router before you begin completing the requests.

Also, if you’re going to treat all routers equally, you might as well put away the function, so that you resupply it to all sendAsync() calls, and put away the command and its common arguments (again, for reusability’s sake). e.g.

<?php 
use PEAR2\Net\RouterOS;
include_once 'PEAR2_Net_RouterOS-1.0.0b4.phar';

try {
$client = new RouterOS\Client('192.168.88.98', 'admin', '');

$count = array('99' => 0, '100' => 0, '101' => 0);//Count the number of replies we've had per tag.
$responseHandler = function ($response) use (&$count) {
 $count[$response->getTag()]++;
 if (10 === $count[$response->getTag()]) {
 return true;//Cancel after 10 replies. Note that we'd get 2 additional responses, but we won't cancel on them.
 }

 if ($response->getType() == RouterOS\Response::TYPE_DATA) {
 echo 'Data from "' . $response->getTag() . '":' . "\n";
 echo $response->getArgument('tx-current') . "\n";
 echo $response->getArgument('tx-10-second-average') . "\n";
 echo $response->getArgument('rx-current') . "\n";
 echo $response->getArgument('rx-10-second-average') . "\n";
 echo "\n";
 }

};

$testRequest = new RouterOS\Request('/tool bandwidth-test protocol="udp" direction="both" user="admin" password="" interval=1');

$client->sendAsync(
    $testRequest->setArgument('address', '192.168.88.99')->setTag('99'),
    $responseHandler
)->sendAsync(
    $testRequest->setArgument('address', '192.168.88.100')->setTag('100'),
    $responseHandler
)->sendAsync(
    $testRequest->setArgument('address', '192.168.88.101')->setTag('101'),
    $responseHandler
)->loop();//until all requests are done

} catch (Exception $e) {
 echo 'Unable to connect and/or login to the router';
}