...
 
Commits (1)
......@@ -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($)
{
......