This is because the original coder failed to take into account the reply length criteria as defined on http://wiki.mikrotik.com/wiki/API. It took me an hour or so to get my head around how the length works and therefore how to fix the PHP code. Unfortunately, my account doesn't have the ability to edit the API page on the wiki and so I can't update the page to make the description more clear. However.....
I have changed the read() function in the PHP class as follows:
Code: Select all
function read($parse = true) {
$RESPONSE = array();
while (true) {
// Read the first byte of input which gives us some or all of the length
// of the remaining reply.
$BYTE = ord(fread($this->socket, 1) );
$LENGTH = 0;
echo "$BYTE\n";
// If the first bit is set then we need to remove the first four bits, shift left 8
// and then read another byte in.
// We repeat this for the second and third bits.
// If the fourth bit is set, we need to remove anything left in the first byte
// and then read in yet another byte.
if ($BYTE & 128) {
if (($BYTE & 192) == 128) {
$LENGTH = (($BYTE & 63) << 8 ) + ord(fread($this->socket, 1)) ;
} else {
if (($BYTE & 224) == 192) {
$LENGTH = (($BYTE & 31) << 8 ) + ord(fread($this->socket, 1)) ;
$LENGTH = ($LENGTH << 8 ) + ord(fread($this->socket, 1)) ;
} else {
if (($BYTE & 240) == 224) {
$LENGTH = (($BYTE & 15) << 8 ) + ord(fread($this->socket, 1)) ;
$LENGTH = ($LENGTH << 8 ) + ord(fread($this->socket, 1)) ;
$LENGTH = ($LENGTH << 8 ) + ord(fread($this->socket, 1)) ;
} else {
$LENGTH = ord(fread($this->socket, 1)) ;
$LENGTH = ($LENGTH << 8 ) + ord(fread($this->socket, 1)) ;
$LENGTH = ($LENGTH << 8 ) + ord(fread($this->socket, 1)) ;
$LENGTH = ($LENGTH << 8 ) + ord(fread($this->socket, 1)) ;
}
}
}
} else {
$LENGTH = $BYTE;
}
// If we have got more characters to read, read them in.
if ($LENGTH > 0) {
$_ = "";
$retlen=0;
while ($retlen < $LENGTH) {
$toread = $LENGTH - $retlen ;
$_ .= fread($this->socket, $toread);
$retlen = strlen($_);
}
$RESPONSE[] = $_ ;
$this->debug('>>> [' . $retlen . '/' . $LENGTH . ' bytes read.');
}
// If we get a !done, make a note of it.
if ($_ == "!done")
$receiveddone=true;
$STATUS = socket_get_status($this->socket);
if ($LENGTH > 0)
$this->debug('>>> [' . $LENGTH . ', ' . $STATUS['unread_bytes'] . '] ' . $_);
if ( (!$this->connected && !$STATUS['unread_bytes']) ||
($this->connected && !$STATUS['unread_bytes'] && $receiveddone) )
break;
}
if ($parse)
$RESPONSE = $this->parse_response($RESPONSE);
return $RESPONSE;
}