Commit 4b3d341b authored by Gary Wong's avatar Gary Wong

RF spectrum handling WIP. Processes spectrum limits given in rspecs.

Maintains database state per interface, for use by the RF monitoring
daemon.

Not tested yet!
parent 47a1d9c9
......@@ -691,6 +691,7 @@ sub TBDB_PHYSICAL_NODE_TABLES() {
'delays' => [ 'node_id' ],
'iface_counters' => [ 'node_id' ],
'interfaces' => [ 'node_id' ],
'interfaces_rf_limit' => [ 'node_id' ],
'interface_settings' => [ 'node_id' ],
'interface_state' => [ 'node_id' ],
'last_reservation' => [ 'node_id' ],
......
......@@ -3759,6 +3759,10 @@ sub RemovePhysicalState($;$)
"where ($clause) and ".
" role='" . TBDB_IFACEROLE_EXPERIMENT() . "' ")
or $errors++;
# RF interfaces (also cleaned in nfree).
DBQueryWarn( "DELETE FROM interfaces_rf_limit WHERE $clause" )
or $errors++;
}
foreach my $table (keys(%physicalTables)) {
......
......@@ -1024,6 +1024,33 @@ sub TypeCapability($$$)
return 0;
}
#
# Add an RF limit to an interface.
#
sub AddRFLimit($$$$)
{
my ($self, $f_low, $f_high, $power) = @_;
my $nodeif = $self->node_id();
my $iface = $self->iface();
# force numeric
$f_low += 0;
$f_high += 0;
$power += 0;
return -1
if( $f_low <= 0 || $f_high <= f_low );
if( !DBQueryWarn( "INSERT INTO interfaces_rf_limit SET node_id='$node_id', " .
"iface='$iface', freq_low='$f_low', freq_high='$f_high', " .
"power='$power'" ) ) {
return -1;
}
return 0;
}
##############################################################################
package Interface::VInterface;
use libdb;
......
......@@ -551,6 +551,10 @@ foreach my $node (@freed_nodes) {
DBQueryWarn("delete from interface_settings where node_id='$node_id'")
or $error++;
# Clean the interfaces_rf_limit table for this node
DBQueryWarn( "DELETE FROM interfaces_rf_limit WHERE node_id='$node_id'" )
or $error++;
# If it's a robot, we need to reset its physical location.
my $result =
DBQueryFatal("select building,floor,loc_x,loc_y,orientation ".
......
......@@ -3123,6 +3123,12 @@ sub GetTicketAuxAux($)
$ip = GeniXML::GetIp($ref, $nodemap{$node_nickname}->{'rspec'});
$mask = GeniXML::GetMask($ref, $nodemap{$node_nickname}->{'rspec'});
$spectrum = GeniXML::GetSpectrum( $ref, $iface_ref );
goto bad unless( defined( $spectrum ) );
foreach my $req( @$spectrum ) {
# FIXME apply policy constraints to requested spectrum...
# these are not defined yet
}
}
# XXX
......@@ -5513,6 +5519,12 @@ sub SliverWorkAux($)
goto bad;
}
}
my $spectrum = GeniXML::GetSpectrum( $ifaceref, $ifaceref );
goto bad unless( defined( $spectrum ) );
foreach my $req (@$spectrum) {
my ($f_low, $f_high, $power) = $req;
$interface->AddRFLimit( $f_low, $f_high, $power );
}
# Initial update of the manifest.
$ifaceref = $sliver->AnnotateManifest($ifaceref);
my $outref;
......
......@@ -544,6 +544,41 @@ sub GetIp($$)
return $result;
}
# Returns undef if input is invalid (e.g., negative or overlapping
# frequencies).
# Returns empty list if no spectrum requested.
# Otherwise, returns list of (f_low, f_high, power) tuples.
sub GetSpectrum($$)
{
my ($ifaceref, $node) = @_;
my @requests = ();
my $id = GetInterfaceId( $ifaceref );
my @ifaces = FindNodes( "n:interface", $node )->get_nodelist();
foreach my $iface (@ifaces) {
my $testid = GetInterfaceId( $iface );
if( defined( $id ) && defined( $testid ) && $testid eq $id ) {
my @ranges = FindNodes( "n:spectrum", $iface );
foreach my $r (@ranges) {
$f_low = GetText( "f-low", $r );
$f_high = GetText( "f-high", $r );
$power = GetText( "power", $r );
return undef if( $f_low >= $f_high );
return undef if( $f_low <= 0 );
foreach $existing (@requests) {
($old_low, $old_high, $old_power) = @$existing;
$f_low > $old_high or $f_high < $old_low or return undef;
}
push $requests, [ $f_low, $f_high, $power ];
}
}
}
return \@requests;
}
# Returns the vnode id in the emulab extension or failing that the component_id
sub GetVnodeId($)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment