+28Jan25======================================================================
+1. Set default Spot qrg granularity to 1KHz (was 25KHz).
+2. Refine Incoming CCLuster connection handling. It is a requirement that a
+ node is either currently known as a node (probably automagickly marked as
+ dxspider previously by receiving PC92 K record) or doing it explicitly
+ with a 'set/ccluster' command.
27Jan25======================================================================
1. Make SURE that spot dupe checks do not add yet more dupe (dupe) records
to the dupe file.
=== 5^SET/CLX <call> [<call>..]^Make the callsign an CLX node
+=== 5^SET/CCLUSTER <call> [<call>..]^Make the callsign an CC Cluster node
+
=== 9^SET/DEBUG <name>^Add a debug level to the debug set
=== 9^UNSET/DEBUG <name>^Remove a debug level from the debug set
You can choose to log several different levels. The levels are
--- /dev/null
+#
+# set user type to 'L' for Lee's CCluster node
+#
+# Please note that this is only effective if the user is not on-line
+#
+# Copyright (c) 2025 - Dirk Koopman
+#
+#
+#
+
+my ($self, $line) = @_;
+my @args = split /\s+/, $line;
+my $call;
+my @out;
+my $user;
+my $create;
+
+return (1, $self->msg('e5')) if $self->priv < 5;
+
+foreach $call (@args) {
+ $call = uc $call;
+ if ($call eq $main::mycall) {
+ push @out, $self->msg('e11', $call);
+ next;
+ }
+ if ($call eq $main::myalias) {
+ push @out, $self->msg('e11', $call);
+ next;
+ }
+ my $chan = DXChannel::get($call);
+ if ($chan) {
+ push @out, $self->msg('nodee1', $call);
+ } else {
+ $user = DXUser::get($call);
+ $create = !$user;
+ $user = DXUser->new($call) if $create;
+ if ($user) {
+ $user->sort('L');
+ $user->homenode($call);
+ $user->lockout(0);
+ $user->priv(1) unless $user->priv;
+ $user->close();
+ push @out, $self->msg($create ? 'nodecclc' : 'nodeccl', $call);
+ } else {
+ push @out, $self->msg('e3', "Set CCCluster", $call);
+ }
+ }
+}
+return (1, @out);
sub is_node
{
- return $_[0]->{sort} =~ /^[ACRSX]$/;
+ return $_[0]->{sort} =~ /^[ACRSXL]$/;
}
# is it an ak1a node ?
sub is_ak1a
return $_[0]->{sort} eq 'N';
}
-sub is_dslink
+sub is_ccluster
{
return $_[0]->{sort} eq 'L';
}
my $pc = shift;
my $conn = $self->conn;
- unless ($self->outbound) {
- dbg("PC18 on startup an incoming connection from $self->{call} ignored as iappropriate");
- return;
- }
$self->state('init');
$self->{build} = $build;
$self->user->build($build);
$parent->build($build);
- dbg("$self->{call} = $software version $version build $build");
- unless ($self->is_spider) {
- dbg("Change U " . $self->user->sort . " C $self->{sort} -> S");
+ dbg("PC18 $self->{call} = $software version $version build $build");
+ if ($software =~ /^DXSp/ && !$self->is_spider) {
+ dbg("PC18 Change sort U " . $self->user->sort . " C $self->{sort} -> S");
+ $self->sort('S');
$self->user->sort('S');
$self->user->put;
- $self->sort('S');
}
-# $self->{handle_xml}++ if DXXml::available() && $pc->[1] =~ /\bxml/;
+ if ($software =~ /^CC/ && !$self->is_ccluster) {
+ dbg("PC18 Change sort U " . $self->user->sort . " C $self->{sort} -> L");
+ $self->sort('L');
+ $self->user->sort('L');
+ $self->user->put;
+ }
} elsif (($software, $version, $build) = $pc->[1] =~ /(AR-Cluster)\s+Version:\s+(\d+\.\d+).?(\d+\.\d+)?/) {
- dbg("$self->{call} = $software version $version build $build");
+ dbg("PC18 $self->{call} = $software version $version build $build");
$self->{version} = $version;
$self->user->version($version);
$parent->version($version);
$self->sort('R');
}
} else {
- dbg("$self->{call} = Unknown software ($pc->[1] $pc->[2])");
+ dbg("PC18 $self->{call} = Unknown software ($pc->[1] $pc->[2])");
$self->version(50.0);
$self->version($pc->[2] / 100) if $pc->[2] && $pc->[2] =~ /^\d+$/;
$self->user->version($self->version);
}
+ # for incoming CC Clusters go straight to state 'normal', otherwise bang out.
+ # In future this may well cause a disconnection
+ unless ($self->outbound) {
+ if ($self->is_ccluster) {
+ my @rout = $parent->del_nodes;
+ $self->route_pc21($origin, $line, @rout, $parent) if @rout;
+ $self->send_local_config();
+ $self->state('normal');
+ $self->{lastping} = 0;
+ $self->route_pc92a($main::mycall, undef, $main::routeroot, Route::Node::get($self->{call}));
+ } else {
+ dbg("PC18 on startup an incoming connection from $self->{call} ignored as iappropriate");
+ return;
+ }
+ }
+
if ($pc->[1] =~ /CC\s*Cluster/i || $pc->[1] =~ /\bpc9x/i) {
if ($self->{isolate}) {
- dbg("$self->{call} pc9x recognised, but node is isolated, using old protocol");
+ dbg("PC18 $self->{call} pc9x recognised, but node is isolated, using old protocol");
} elsif (!$self->user->wantpc9x) {
- dbg("$self->{call} pc9x explicitly switched off, using old protocol");
+ dbg("PC18 $self->{call} pc9x explicitly switched off, using old protocol");
} else {
$self->{do_pc9x} = 1;
- dbg("$self->{call} Set do PC9x");
+ dbg("PC18 $self->{call} Set do PC9x");
}
}
nodeac => q{$_[0] created as AK1A style Node},
nodeb => q{$_[0] set as BBS},
nodebc => q{$_[0] created as BBS},
+ nodeccl => q{$_[0] set as CCCluster style Node},
+ nodecclc => q{$_[0] created as CCCluster style Node},
nodec => q{$_[0] set as CLX style Node},
nodecc => q{$_[0] created as CLX style Node},
noder => q{$_[0] set as AR-Cluster style Node},
our $minselfspotqrg = 1240000; # minimum freq above which self spotting is allowed
our $readback = $main::is_win ? 0 : 1; # don't read spot files backwards if it's windows
-our $qrggranularity = 25; # normalise the qrg to this number of hz (default: 25khz), so tough luck if you have a fumble fingers moment
+our $qrggranularity = 1; # normalise the qrg to this number of khz (default: 25khz), so tough luck if you have a fumble fingers moment
our $timegranularity = 600; # ditto to the nearest 100 seconds
our $oldstyle = 0; # revert to traditional dupe key format
our $no_node_in_dupe = 1; # remove the node field from dupe considerations.