2023-06-25 10:45:02 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Classes\FTN\Packet;
|
|
|
|
|
|
|
|
use Illuminate\Support\Arr;
|
2024-06-17 09:03:48 +00:00
|
|
|
use Illuminate\Support\Collection;
|
2023-06-25 10:45:02 +00:00
|
|
|
|
|
|
|
use App\Classes\FTN\Packet;
|
|
|
|
use App\Models\Setup;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* FSC-0048 http://ftsc.org/docs/fsc-0048.002
|
|
|
|
*
|
|
|
|
* Commonly known as Type 2+ packets, based on FSC-0039 with improved support for FTS-0001
|
2024-05-28 02:23:59 +00:00
|
|
|
* @note: These packets will be detected as FSC-0039 packets unless it is addressed to a point
|
2023-06-25 10:45:02 +00:00
|
|
|
*/
|
|
|
|
final class FSC48 extends Packet
|
|
|
|
{
|
|
|
|
protected const HEADER = [
|
|
|
|
'onode' => [0x00,'v',2], // Orig Node
|
|
|
|
'dnode' => [0x02,'v',2], // Dest Node
|
|
|
|
'y' => [0x04,'v',2], // Year
|
|
|
|
'm' => [0x06,'v',2], // Month
|
|
|
|
'd' => [0x08,'v',2], // Day
|
|
|
|
'H' => [0x0a,'v',2], // Hour
|
|
|
|
'M' => [0x0c,'v',2], // Minute
|
|
|
|
'S' => [0x0e,'v',2], // Second
|
|
|
|
'baud' => [0x10,'v',2], // Baud
|
|
|
|
'type' => [0x12,'v',2], // Packet Version (should be 2)
|
|
|
|
'onet' => [0x14,'v',2], // Orig Net (0xFFFF when OrigPoint != 0)
|
|
|
|
'dnet' => [0x16,'v',2], // Dest Net
|
|
|
|
'prodcode-lo' => [0x18,'C',1], // Product Code Lo
|
|
|
|
'prodrev-maj' => [0x19,'C',1], // Product Version Major
|
|
|
|
'password' => [0x1a,'a8',8], // Packet Password
|
|
|
|
'ozone' => [0x22,'v',2], // Orig Zone
|
|
|
|
'dzone' => [0x24,'v',2], // Dest Zone
|
|
|
|
'auxnet' => [0x26,'v',2], // Aux Net
|
|
|
|
'capvalid' => [0x28,'n',2], // fsc-0039.004 (copy of 0x2c)
|
|
|
|
'prodcode-hi' => [0x2a,'C',1], // Product Code Hi
|
|
|
|
'prodrev-min' => [0x2b,'C',1], // Product Version Minor
|
2024-05-28 02:23:59 +00:00
|
|
|
'capword' => [0x2c,'v',2], // Capability Word fsc-0039.004/fsc-0048.002
|
2023-06-25 10:45:02 +00:00
|
|
|
'dozone' => [0x2e,'v',2], // Orig Zone
|
|
|
|
'ddzone' => [0x30,'v',2], // Dest Zone
|
|
|
|
'opoint' => [0x32,'v',2], // Orig Point
|
|
|
|
'dpoint' => [0x34,'v',2], // Dest Point
|
|
|
|
'proddata' => [0x36,'a4',4], // ProdData
|
|
|
|
];
|
|
|
|
|
|
|
|
public const TYPE = '2+';
|
2024-05-28 02:23:59 +00:00
|
|
|
public const VERS = self::MSG_TYPE2; //|self::MSG_TYPE4;
|
2023-06-25 10:45:02 +00:00
|
|
|
|
|
|
|
public function __get($key)
|
|
|
|
{
|
|
|
|
switch ($key) {
|
|
|
|
case 'capability':
|
|
|
|
return sprintf('%016b',Arr::get($this->header,'capword'));
|
|
|
|
|
|
|
|
default:
|
|
|
|
return parent::__get($key);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create our message packet header
|
|
|
|
*/
|
2024-06-17 09:03:48 +00:00
|
|
|
protected function header(Collection $msgs): string
|
2023-06-25 10:45:02 +00:00
|
|
|
{
|
2024-06-28 13:27:06 +00:00
|
|
|
$oldest = $msgs->sortBy('date')->last();
|
2024-05-17 12:10:54 +00:00
|
|
|
|
2024-06-17 09:03:48 +00:00
|
|
|
return pack(collect(self::HEADER)->pluck(1)->join(''),
|
|
|
|
$this->fftn_p->node_id, // Orig Node
|
|
|
|
$this->tftn_p->node_id, // Dest Node
|
|
|
|
$oldest->datetime->format('Y'), // Year
|
|
|
|
$oldest->datetime->format('m')-1, // Month
|
|
|
|
$oldest->datetime->format('d'), // Day
|
|
|
|
$oldest->datetime->format('H'), // Hour
|
|
|
|
$oldest->datetime->format('i'), // Minute
|
|
|
|
$oldest->datetime->format('s'), // Second
|
|
|
|
0, // Baud
|
|
|
|
2, // Packet Version (should be 2)
|
|
|
|
$this->fftn_p->point_id ? 0xffff : $this->fftn_p->host_id, // Orig Net (0xFFFF when OrigPoint != 0)
|
|
|
|
$this->tftn_p->host_id, // Dest Net
|
|
|
|
(Setup::PRODUCT_ID & 0xff), // Product Code Lo
|
|
|
|
Setup::PRODUCT_VERSION_MAJ, // Product Version Major
|
|
|
|
$this->pass_p ?: $this->tftn_p->pass_packet, // Packet Password
|
|
|
|
$this->fftn_p->zone->zone_id, // Orig Zone
|
|
|
|
$this->tftn_p->zone->zone_id, // Dest Zone
|
|
|
|
$this->fftn_p->point_id ? $this->fftn_p->host_id : 0x00, // Aux Net
|
|
|
|
static::VERS, // fsc-0039.004 (copy of 0x2c)
|
|
|
|
((Setup::PRODUCT_ID >> 8) & 0xff), // Product Code Hi
|
|
|
|
Setup::PRODUCT_VERSION_MIN, // Product Version Minor
|
|
|
|
static::VERS, // Capability Word
|
|
|
|
$this->fftn_p->zone->zone_id, // Orig Zone
|
|
|
|
$this->tftn_p->zone->zone_id, // Dest Zone
|
|
|
|
$this->fftn_p->point_id, // Orig Point
|
|
|
|
$this->tftn_p->point_id, // Dest Point
|
|
|
|
strtoupper(hexstr(Setup::PRODUCT_ID)), // ProdData
|
|
|
|
);
|
2023-06-25 10:45:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determine if this is a fsc-0045 packet
|
|
|
|
*
|
|
|
|
* @param string $header
|
|
|
|
* @return bool
|
|
|
|
* @throws \Exception
|
|
|
|
*/
|
|
|
|
public static function is_type(string $header): bool
|
|
|
|
{
|
|
|
|
$head = unpack(self::unpackheader(self::HEADER),$header);
|
|
|
|
|
|
|
|
return (
|
|
|
|
(Arr::get($head,'type') === 2)
|
|
|
|
&& (Arr::get($head,'capword') === Arr::get($head,'capvalid'))
|
|
|
|
&& ((Arr::get($head,'opoint') === 0) || (Arr::get($head,'onet') === 0xffff))
|
|
|
|
&& Arr::get($head,'auxnet')
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|