feat: publish NIRO Gen5W research overview and reviewed source examples
This commit is contained in:
commit
ccad0ed9f3
23 files changed
+1279
No files matched your search
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Tracks the MQTT client keepalive independently from inbound broker traffic.
|
||||
*
|
||||
* MQTT keepalive is a client-to-broker obligation. Receiving a continuous
|
||||
* stream of PUBLISH packets must therefore never postpone the next PINGREQ.
|
||||
*/
|
||||
final class NiroMqttKeepalive
|
||||
{
|
||||
private int $lastPingAt;
|
||||
|
||||
public function __construct(int $connectedAt, private readonly int $intervalSeconds = 15)
|
||||
{
|
||||
if ($intervalSeconds < 1) {
|
||||
throw new InvalidArgumentException('MQTT keepalive interval must be positive');
|
||||
}
|
||||
$this->lastPingAt = $connectedAt;
|
||||
}
|
||||
|
||||
public function isDue(int $now): bool
|
||||
{
|
||||
return $now - $this->lastPingAt >= $this->intervalSeconds;
|
||||
}
|
||||
|
||||
public function markSent(int $now): void
|
||||
{
|
||||
$this->lastPingAt = $now;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Minimal raw Snappy encoder for the V038 native TFS decoder.
|
||||
*
|
||||
* The head unit advertises application/x-snappy-framed, but the native
|
||||
* response path calls snappy::Uncompress on a raw Snappy block. Literal-only
|
||||
* blocks are valid raw Snappy and avoid a platform extension dependency.
|
||||
*/
|
||||
final class NiroRawSnappy
|
||||
{
|
||||
public static function encodeLiteral(string $plain): string
|
||||
{
|
||||
$length = strlen($plain);
|
||||
if ($length > 8 * 1024 * 1024) {
|
||||
throw new InvalidArgumentException('Snappy input exceeds limit');
|
||||
}
|
||||
|
||||
$encoded = self::varint($length);
|
||||
$offset = 0;
|
||||
while ($offset < $length) {
|
||||
$chunkLength = min(65536, $length - $offset);
|
||||
$encoded .= self::literalTag($chunkLength);
|
||||
$encoded .= substr($plain, $offset, $chunkLength);
|
||||
$offset += $chunkLength;
|
||||
}
|
||||
return $encoded;
|
||||
}
|
||||
|
||||
private static function varint(int $value): string
|
||||
{
|
||||
$encoded = '';
|
||||
do {
|
||||
$byte = $value & 0x7f;
|
||||
$value >>= 7;
|
||||
if ($value !== 0) {
|
||||
$byte |= 0x80;
|
||||
}
|
||||
$encoded .= chr($byte);
|
||||
} while ($value !== 0);
|
||||
return $encoded;
|
||||
}
|
||||
|
||||
private static function literalTag(int $length): string
|
||||
{
|
||||
if ($length < 1 || $length > 65536) {
|
||||
throw new InvalidArgumentException('Invalid Snappy literal length');
|
||||
}
|
||||
if ($length <= 60) {
|
||||
return chr(($length - 1) << 2);
|
||||
}
|
||||
|
||||
$value = $length - 1;
|
||||
$bytes = '';
|
||||
while ($value !== 0) {
|
||||
$bytes .= chr($value & 0xff);
|
||||
$value >>= 8;
|
||||
}
|
||||
return chr((59 + strlen($bytes)) << 2) . $bytes;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user