More complete rework of packet parsing and packet generation with 29710c
This commit is contained in:
@@ -12,9 +12,9 @@ use Illuminate\Validation\Validator as ValidatorResult;
|
||||
|
||||
use App\Classes\FTN as FTNBase;
|
||||
use App\Exceptions\InvalidPacketException;
|
||||
use App\Models\{Address,Domain,Echomail,Netmail,Zone};
|
||||
use App\Models\{Address,Domain,Echomail,Netmail,Setup,Zone};
|
||||
use App\Rules\{TwoByteInteger,TwoByteIntegerWithZero};
|
||||
use App\Traits\{EncodeUTF8,ObjectIssetFix};
|
||||
use App\Traits\ObjectIssetFix;
|
||||
|
||||
/**
|
||||
* Class Message
|
||||
@@ -91,6 +91,7 @@ class Message extends FTNBase
|
||||
private array $header; // Message Header
|
||||
private int $tzutc = 0; // TZUTC that needs to be converted to be used by Carbon @see self::kludges
|
||||
private Echomail|Netmail $mo; // The object storing this packet message
|
||||
private Address $us; // Our address for this message
|
||||
|
||||
/** @deprecated Not sure why this is needed? */
|
||||
public bool $packed = FALSE; // Has the message been packed successfully
|
||||
@@ -156,6 +157,7 @@ class Message extends FTNBase
|
||||
{
|
||||
$oo = new self($o->fftn->zone);
|
||||
$oo->mo = $o;
|
||||
$oo->us = our_address($o->tftn);
|
||||
|
||||
return $oo;
|
||||
}
|
||||
@@ -507,6 +509,8 @@ class Message extends FTNBase
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
$s = Setup::findOrFail(config('app.id'));
|
||||
|
||||
$return = pack(collect(self::HEADER)->pluck(1)->join(''),
|
||||
$this->mo->fftn->node_id, // Originating Node
|
||||
$this->mo->tftn->node_id, // Destination Node
|
||||
@@ -521,22 +525,26 @@ class Message extends FTNBase
|
||||
$return .= $this->mo->from."\00";
|
||||
$return .= $this->mo->subject."\00";
|
||||
|
||||
if (($this->mo instanceof Netmail) && $this->mo->isFlagSet(self::FLAG_LOCAL)) {
|
||||
// If there isnt an INTL kludge, we'll add it
|
||||
if (! $this->mo->kludges->has('INTL'))
|
||||
$this->mo->kludges->put('INTL',sprintf('%s %s',$this->mo->tftn->ftn3d,$this->mo->fftn->ftn3d));
|
||||
|
||||
if ((! $this->mo->kludges->has('FMPT')) && $this->mo->fftn->point_id)
|
||||
$this->mo->kludges->put('FMPT',$this->mo->fftn->point_id);
|
||||
|
||||
if ((! $this->mo->kludges->has('TOPT')) && $this->mo->tftn->point_id)
|
||||
$this->mo->kludges->put('TOPT',$this->mo->tftn->point_id);
|
||||
}
|
||||
|
||||
if ($this->mo->isFlagSet(self::FLAG_LOCAL))
|
||||
$this->mo->kludges->put('PID',sprintf('clrghouz %s',$s->version));
|
||||
else
|
||||
$this->mo->kludges->put('TID',sprintf('clrghouz %s',$s->version));
|
||||
|
||||
if ($this->mo instanceof Echomail)
|
||||
$return .= sprintf("AREA:%s\r",strtoupper($this->mo->echoarea->name));
|
||||
|
||||
if ($this->mo instanceof Netmail) {
|
||||
// @todo If the message is local, then our kludges are not in the msg itself, we'll add them
|
||||
if ($this->isFlagSet(self::FLAG_LOCAL))
|
||||
Log::debug(sprintf('%s:^ Local message, we may need to set our INTL/FMPT/TOPT',self::LOGKEY));
|
||||
|
||||
$return .= sprintf("\01INTL %s\r",$this->mo->kludges->get('INTL'));
|
||||
|
||||
if ($this->mo->kludges->has('FMPT'))
|
||||
$return .= sprintf("\01FMPT %d\r",$this->mo->kludges->get('FMPT'));
|
||||
if ($this->mo->kludges->has('TOPT'))
|
||||
$return .= sprintf("\01TOPT %d\r",$this->mo->kludges->get('TOPT'));
|
||||
}
|
||||
|
||||
// Add some kludges
|
||||
$return .= sprintf("\01TZUTC: %s\r",str_replace('+','',$this->mo->date->getOffsetString('')));
|
||||
|
||||
@@ -551,11 +559,15 @@ class Message extends FTNBase
|
||||
$return .= $this->mo->content;
|
||||
|
||||
if ($this->mo instanceof Netmail) {
|
||||
// @todo automatically include our address in the path
|
||||
|
||||
foreach ($this->mo->path as $ao)
|
||||
$return .= sprintf("\x01Via %s\r",$this->mo->via($ao));
|
||||
|
||||
// Add our address
|
||||
$return .= sprintf("\x01Via %s @%s.UTC %s (%04X)\r",
|
||||
$this->us->ftn3d,
|
||||
Carbon::now()->format('Ymd.His'),
|
||||
Setup::PRODUCT_NAME,Setup::PRODUCT_ID);
|
||||
|
||||
} else {
|
||||
// FTS-0004.001/FSC-0068.001 The message SEEN-BY lines
|
||||
// FTS-0004.001/FSC-0068.001 The message PATH lines
|
||||
|
@@ -50,6 +50,20 @@ abstract class Packet extends FTNBase implements \Iterator, \Countable
|
||||
protected Collection $messages; // Messages in the Packet
|
||||
public Collection $errors; // Messages that fail validation
|
||||
protected int $index; // Our array index
|
||||
protected $pass_p = NULL; // Overwrite the packet password (when packing messages)
|
||||
|
||||
/* ABSTRACT */
|
||||
|
||||
/**
|
||||
* This function is intended to be implemented in child classes to test if the packet
|
||||
* is defined by the child object
|
||||
*
|
||||
* @see self::PACKET_TYPES
|
||||
* @param string $header
|
||||
* @return bool
|
||||
*/
|
||||
abstract public static function is_type(string $header): bool;
|
||||
abstract protected function header(): string;
|
||||
|
||||
/* STATIC */
|
||||
|
||||
@@ -63,16 +77,6 @@ abstract class Packet extends FTNBase implements \Iterator, \Countable
|
||||
return collect(static::HEADER)->sum(function($item) { return Arr::get($item,2); });
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is intended to be implemented in child classes to test if the packet
|
||||
* is defined by the child object
|
||||
*
|
||||
* @see self::PACKET_TYPES
|
||||
* @param string $header
|
||||
* @return bool
|
||||
*/
|
||||
abstract public static function is_type(string $header): bool;
|
||||
|
||||
/**
|
||||
* Process a packet file
|
||||
*
|
||||
@@ -261,6 +265,9 @@ abstract class Packet extends FTNBase implements \Iterator, \Countable
|
||||
case 'name':
|
||||
return $this->{$key} ?: sprintf('%08x',timew());
|
||||
|
||||
case 'messages':
|
||||
return $this->{$key};
|
||||
|
||||
default:
|
||||
throw new \Exception('Unknown key: '.$key);
|
||||
}
|
||||
@@ -274,6 +281,12 @@ abstract class Packet extends FTNBase implements \Iterator, \Countable
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
if (empty($this->messages))
|
||||
throw new InvalidPacketException('Refusing to make an empty packet');
|
||||
|
||||
if (empty($this->tftn_p) || empty($this->fftn_p))
|
||||
throw new InvalidPacketException('Cannot generate a packet without a destination address');
|
||||
|
||||
$return = $this->header();
|
||||
|
||||
foreach ($this->messages as $o)
|
||||
@@ -379,18 +392,18 @@ abstract class Packet extends FTNBase implements \Iterator, \Countable
|
||||
/**
|
||||
* Generate a packet
|
||||
*
|
||||
* @param Collection $msgs
|
||||
* @return string
|
||||
* @throws InvalidPacketException
|
||||
*/
|
||||
public function generate(Collection $msgs): string
|
||||
public function generate(): string
|
||||
{
|
||||
return (string)$this;
|
||||
}
|
||||
|
||||
public function mail(Collection $msgs): self
|
||||
{
|
||||
$this->messages = $msgs;
|
||||
|
||||
if (empty($this->tftn_p) || empty($this->fftn_p))
|
||||
throw new InvalidPacketException('Cannot generate a packet without a destination address');
|
||||
|
||||
return (string)$this;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -500,6 +513,20 @@ abstract class Packet extends FTNBase implements \Iterator, \Countable
|
||||
$this->messages->push($msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrite the packet password
|
||||
*
|
||||
* @param string|null $password
|
||||
* @return self
|
||||
*/
|
||||
public function password(string $password=NULL): self
|
||||
{
|
||||
if ($password && (strlen($password) < 9))
|
||||
$this->pass_p = $password;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/** @deprecated Is this used? */
|
||||
public function pluck(string $key): Collection
|
||||
{
|
||||
|
@@ -59,11 +59,10 @@ final class FSC48 extends Packet
|
||||
|
||||
/**
|
||||
* Create our message packet header
|
||||
* // @todo add the ability to overwrite the password
|
||||
*/
|
||||
protected function header(): string
|
||||
{
|
||||
$oldest = $this->messages->sortBy(function($item) { return $item->datetime; })->last();
|
||||
$oldest = $this->messages->sortBy('datetime')->last();
|
||||
|
||||
try {
|
||||
return pack(collect(self::HEADER)->pluck(1)->join(''),
|
||||
@@ -77,22 +76,22 @@ final class FSC48 extends Packet
|
||||
$oldest->datetime->format('s'), // Second
|
||||
0, // Baud
|
||||
2, // Packet Version (should be 2)
|
||||
$this->fftn_p->point_id ? 0xffff : $this->fftn_p->node_id, // Orig Net (0xFFFF when OrigPoint != 0)
|
||||
$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->tftn_p->session('pktpass'), // 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->node_id : 0x00, // Aux Net
|
||||
$this->pass_p ?: $this->tftn_p->session('pktpass'), // 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
|
||||
1<<0, // fsc-0039.004 (copy of 0x2c)
|
||||
((Setup::PRODUCT_ID >> 8) & 0xff), // Product Code Hi
|
||||
Setup::PRODUCT_VERSION_MIN, // Product Version Minor
|
||||
1<<0, // 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
|
||||
$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
|
||||
);
|
||||
|
||||
|
@@ -9,11 +9,9 @@ use App\Models\{Echoarea,Echomail,Netmail};
|
||||
*/
|
||||
abstract class Process
|
||||
{
|
||||
public static function canProcess(string $echoarea): bool
|
||||
public static function canProcess(Echoarea $eao): bool
|
||||
{
|
||||
$eao = Echoarea::where('name',$echoarea)->single();
|
||||
|
||||
return $eao && $eao->automsgs;
|
||||
return $eao->automsgs;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -27,9 +27,9 @@ final class Test extends Process
|
||||
|| (! in_array(strtolower($mo->subject),self::testing)))
|
||||
return FALSE;
|
||||
|
||||
Log::info(sprintf('%s:- Processing TEST message from (%s) [%s] in [%s]',self::LOGKEY,$msg->user_from,$msg->fftn,$msg->echoarea));
|
||||
Log::info(sprintf('%s:- Processing TEST message from (%s) [%s] in [%s]',self::LOGKEY,$mo->from,$mo->fftn->ftn,$mo->echoarea->name));
|
||||
|
||||
Notification::route('echomail',$mo->echoarea)->notify(new TestNotification($msg));
|
||||
Notification::route('echomail',$mo->echoarea->withoutRelations())->notify(new TestNotification($mo));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -5,7 +5,8 @@ namespace App\Classes\FTN\Process\Netmail;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Classes\FTN\{Message,Process};
|
||||
use App\Classes\FTN\Process;
|
||||
use App\Models\{Echomail,Netmail};
|
||||
use App\Notifications\Netmails\Areafix as AreafixNotification;
|
||||
use App\Notifications\Netmails\Areafix\NotConfiguredHere as AreafixNotConfiguredHereNotification;
|
||||
|
||||
@@ -18,18 +19,18 @@ final class Areafix extends Process
|
||||
{
|
||||
private const LOGKEY = 'RP-';
|
||||
|
||||
public static function handle(Message $msg): bool
|
||||
public static function handle(Echomail|Netmail $mo): bool
|
||||
{
|
||||
if (strtolower($msg->user_to) !== 'areafix')
|
||||
if (strtolower($mo->to) !== 'areafix')
|
||||
return FALSE;
|
||||
|
||||
Log::info(sprintf('%s:- Processing AREAFIX message from (%s) [%s]',self::LOGKEY,$msg->user_from,$msg->fftn));
|
||||
Log::info(sprintf('%s:- Processing AREAFIX message from (%s) [%s]',self::LOGKEY,$mo->from,$mo->fftn));
|
||||
|
||||
// If this is not a node we manage, then respond with a sorry can help you
|
||||
if ($msg->fftn_o->system->sessions->count())
|
||||
Notification::route('netmail',$msg->fftn_o)->notify(new AreafixNotification($msg));
|
||||
if ($mo->fftn->system->sessions->count())
|
||||
Notification::route('netmail',$mo->fftn)->notify(new AreafixNotification($mo));
|
||||
else
|
||||
Notification::route('netmail',$msg->fftn_o)->notify(new AreafixNotConfiguredHereNotification($msg));
|
||||
Notification::route('netmail',$mo->fftn)->notify(new AreafixNotConfiguredHereNotification($mo));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@@ -5,7 +5,8 @@ namespace App\Classes\FTN\Process\Netmail;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
use App\Classes\FTN\{Message,Process};
|
||||
use App\Classes\FTN\Process;
|
||||
use App\Models\{Echomail,Netmail};
|
||||
use App\Notifications\Netmails\Ping as PingNotification;
|
||||
|
||||
/**
|
||||
@@ -17,14 +18,14 @@ final class Ping extends Process
|
||||
{
|
||||
private const LOGKEY = 'RP-';
|
||||
|
||||
public static function handle(Message $msg): bool
|
||||
public static function handle(Echomail|Netmail $mo): bool
|
||||
{
|
||||
if (strtolower($msg->user_to) !== 'ping')
|
||||
if (strtolower($mo->to) !== 'ping')
|
||||
return FALSE;
|
||||
|
||||
Log::info(sprintf('%s:- Processing PING message from (%s) [%s]',self::LOGKEY,$msg->user_from,$msg->fftn));
|
||||
Log::info(sprintf('%s:- Processing PING message from (%s) [%s]',self::LOGKEY,$mo->from,$mo->fftn->ftn));
|
||||
|
||||
Notification::route('netmail',$msg->fftn_o)->notify(new PingNotification($msg));
|
||||
Notification::route('netmail',$mo->fftn)->notify(new PingNotification($mo));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
Reference in New Issue
Block a user