package Agent::SWITCH2;
#<copyright>
# ----------------------------------------------------------
# Sun Proprietary/Confidential Code
# Copyright 2001, Sun Microsystems, Inc. All rights reserved.
# ----------------------------------------------------------
#</copyright>

#  $Id: SWITCH2.pm,v 1.6 2005/11/18 21:27:12 mckenney Exp $

use strict;
use Agent::SWITCH_Parent;
use base 'Agent::SWITCH_Parent';
use Net::Telnet;
use Agent::SWITCH;
use Util;

#  Report::CAT_SWITCH2

sub isSelectable {"Sun 2GB-Switch or 1GB-Upgraded"}
sub revision     {'$Revision: 1.6 $'}

sub HEALTH {
  my($agent, $new_rep) = @_;
  require Health::Switch2;
  Health::Switch2->all_logic($new_rep);
}

sub new {
  my($self) = Agent->new();

  bless ($self, 'Agent::SWITCH2');
  return $self;
}
use vars qw($ERR);


sub getDevStatus {
  my($class, $dev) = @_;
  my %R;

  $ERR = $class->getLinks($dev, \%R);
  $ERR = $class->getPortStatus($dev, \%R);
  return ($ERR, \%R);
}


sub getLinks {
  my($class, $dev, $R) = @_;
  my($x, $err, $ports, $rem);
  my $DIR  = System->get_home() . "/snmp/bin";
  my $MIBDIR  = System->get_home() . "/snmp/share/snmp/mibs";
  my $renv  = System->get_renv();
  my $TO  = $renv->{'timeout.snmp'} || 10;
  my $wwn = $dev->{wwn};
  my $mibwwn = Util->wwn2mib($wwn);
  my $public = $renv->{'snmp.community'} || "public";
 
  my $OPT = "-v1 -c$public -t$TO -r1 -M$MIBDIR -mall " . System->snmpopt() . "b";
  ($err,$ports) = Util->run_command(
                 "$DIR/snmpwalk $OPT $dev->{ipno} connUnitNumports", 
                 "sanbox_version.txt", 2*$TO+5);
  if ($err){
       Debug->errNoRepeat( SNMP_SENSOR => $dev->{name} , 8, "Run Command error: $err: $DIR/snmpwalk $OPT $dev->{ipno} connUnitNumports");   
  }



  foreach my $l (@$ports) {
      if ($l =~ /$mibwwn/) {
         my(@a) = split(/ +\= */, $l);
         $R->{"port.count"} = $a[1];
         last;
      }
  }

  ($err,$rem) = Util->run_command(
                 "$DIR/snmpwalk $OPT $dev->{ipno} connUnitLinkPortWwnX.$mibwwn", 
                 "sanbox_version.txt", 2*$TO+5);
  if ($err){
       Debug->errNoRepeat( SNMP_SENSOR => $dev->{name} , 8, "Run Command error: $err: $DIR/snmpwalk $OPT $dev->{ipno} connUnitLinkPortWwnX.$mibwwn");   
  }


  my @PORTS;
  my $cnt = 1;
  foreach my $l (@$rem) {
     $l =~ /=\s+Hex: (.*)/;
     my $x = lc($1);
     $x =~ s/ //g;
     if ($l =~ /$mibwwn/) {
         $PORTS[$cnt] = hex substr($x,2,2);
     }
     $cnt++;
  }

  ($err,$rem) = Util->run_command(
                 "$DIR/snmpwalk $OPT $dev->{ipno} connUnitLinkPortWwnY.$mibwwn", 
                 "sanbox_version.txt", 2*$TO+5);
  if ($err){
       Debug->errNoRepeat( SNMP_SENSOR => $dev->{name} , 8, "Run Command error: $err: $DIR/snmpwalk $OPT $dev->{ipno} connUnitLinkPortWwnY.$mibwwn");   
  }


  $cnt = 1;
  foreach my $l (@$rem) {
     $l =~ /=\s+Hex: (.*)/;
     my $x = lc($1);
     $x =~ s/ //g;
     if ( defined($PORTS[$cnt]) ) {
        $R->{"port." . $PORTS[$cnt] . ".link_wwn"} = substr($x,0,16);
        #$R->{"port." . $PORTS[$cnt] . ".link_port"} = hex substr($x,2,2);
     }
     $cnt++;
  }
}

sub getPortStatus {
  my($class, $dev, $R) = @_;
  my($x);
  my $DIR   = System->get_home() . "/snmp/bin";
  my $MIBDIR   = System->get_home() . "/snmp/share/snmp/mibs";
  my $renv  = System->get_renv();
  my $TO    = $renv->{'timeout.snmp'} || 10;
  my $wwn   = $dev->{wwn};
  my $mibwwn = Util->wwn2mib($wwn);
  my $public = $renv->{'snmp.community'} || "public";

 
  my $OPT = "-v1 -c$public -t$TO -r2 -M$MIBDIR -mall " . System->snmpopt() . "b";
  my $err;
  my $rem;

  # Get port type
  my $passwd = System->getDevicePassword($dev, "switch");
   
  my $tmpfile = System->get_home() . "/DATA/mytmpdata.$dev->{ipno}";
  open(OOF, ">$tmpfile");
  print OOF "$passwd";
  close OOF;


  my $SDIR = System->get_home() . "/sbin" ;
  ($err,$rem) = Util->run_command(
               "$SDIR/qlogicSwitchPortType $dev->{ipno}", 
               "sanbox_version.txt", 2*$TO+5);

  
  foreach my $l (@$rem) {
     if($l =~ /ERROR/){
        $R->{"port.0.type"} = "ERROR: ENSURE PASSWORD HAS BEEN ENTERED FOR THIS DEVICE";
     }elsif($l =~ /Port /){
        my($f1, $f2) = split(/ = /, $l);
        my ($nport, $port, $ntype) = split(/ /, $f1);
        $R->{"port.$port.type"} = $f2;
     }
  }
  # get port Admin state
  ($err,$rem) = Util->run_command( "$SDIR/qlogicadminstate $dev->{ipno}", 
                      "admin_state.txt", 2*$TO+5, {cache => 0});
  foreach my $l (@$rem) {
    if ($l =~ /(\d+)\s*=\s(.*)/) {
       my $port = $1;
       my $val = $2;
       $R->{"port.$port.state.AdmStatus"} = $val;
    }
    if ($l =~ /Bad password/){
       Debug->errNoRepeat( SNMP_SENSOR => $dev->{name} , 8, "Cannot retrieve port admin state. Ensure password has been entered for this device: $dev->{ipno}");   
    }
  }

  unlink($tmpfile);



  # get port state
  $OPT = "-v1 -c$public -t$TO -r2 -m${MIBDIR}/fa_40.mib " . System->snmpopt() . "b";
  ($err,$rem) = Util->run_command(
               "$DIR/snmpwalk $OPT $dev->{ipno} connUnitPortState.$mibwwn", 
               "sanbox_version.txt", 3*$TO+5);
  if ($err){
       Debug->errNoRepeat( SNMP_SENSOR => $dev->{name} , 8, "Run Command error: $err: $DIR/snmpwalk $OPT $dev->{ipno} connUnitPortState.$mibwwn");   
  }



  foreach my $l (@$rem) {
    if ($l =~ /$mibwwn/) {
      my($f1, $f2) = split(/ = /, $l);
      my $ix = rindex($f1, ".");
      my $port = substr($f1,$ix+1) - 1;
      $ix = index($f2,"(");
      my $type = substr($f2,0,$ix);
      $R->{"port.$port.state"} = $type;
    }
  }


  


  $OPT = "-v1 -c$public -t$TO -r2 -M$MIBDIR -mall " . System->snmpopt() . "b";


  ($err,$rem) = Util->run_command(
               "$DIR/snmpwalk $OPT $dev->{ipno} connUnitPortSpeed.$mibwwn", 
               "sanbox_version.txt", 3*$TO+5);

  if ($err){
       Debug->errNoRepeat( SNMP_SENSOR => $dev->{name} , 8, "Run Command error: $err: $DIR/snmpwalk $OPT $dev->{ipno} connUnitPortSpeed.$mibwwn");   
  }


  my $port_speed;
  foreach my $l (@$rem) {
    if ($l =~ /$mibwwn/) {
      
      my($f1, $f2) = split(/ = /, $l);
      my $ix = rindex($f1, ".");
      my $port = substr($f1,$ix+1) - 1;
      if(($f2 =~ /10625/) || ($f2 =~ /102400/))
      {
         $port_speed = "1Gb";
      }
      else
      {
         $port_speed = "2Gb";
      }
      $R->{"port.$port.speed"} = $port_speed;
    }
  }
  
}


#
# no FC stats yet
#
sub getStats {
   my($class, $timeout, $ip, $R, $dev, $mibwwn) = @_;

   my $DIR   = System->get_home() . "/snmp/bin";
   my $MIBDIR   = System->get_home() . "/snmp/share/snmp/mibs";
   my $renv = System->get_renv();
   my $public = $renv->{'snmp.community'} || "public";
   my $OPT    = "-v1 -c$public -r2 -t$timeout -m$MIBDIR/qlogic/FA.MIB " . System->snmpopt() . "b";

   my $counter;
   foreach $counter('LinkFailures', 'PrimitiveSequenceProtocolErrors', 
                     'InvalidCRC','LossofSynchronization','InvalidTxWords',
                     'Class2RxFrames', 'Class3RxFrames','Class2TxFrames', 
		     'Class3TxFrames')
   {
      my ($err0,$sensors) = Util->run_command("$DIR/snmpwalk $OPT $ip connUnitPortStatCount$counter.$mibwwn", 
                      "sanbox_version.txt", 3*$timeout+5);

      if ($err0){
        Debug->errNoRepeat( SNMP_SENSOR => $dev->{name} , 8, "Run Command error: $err0: $DIR/snmpwalk $OPT $ip connUnitPortStatCount$counter.$mibwwn");
      }


      foreach my $l (@$sensors) {
         if($l =~ /$counter.$mibwwn.+\.(.+) = (.+)/)
         {
	    my $port = $1 -1;
	    my $value = $2;
	    $value =~ s/Hex: //;
	    $value =~ s/ //g;
	    if(length($value) > 16){
	       $value = 0;
	    }
	    if($value =~ /8000000000000000/){
	       # Unsuppported counter
	       $value = 0;
	    }else{
	       $value = hex(substr($value,-8));
	    }

	    $R->{"port.$port.error.$counter"} =  $value;
	    if("Class2RxFrames,Class3RxFrames,Class2TxFrames,Class3TxFrames" =~ /$counter/){
	      $R->{"port.$port.stats.$counter"} =  $value;
	    }
   

         }

      }
   }
   
}


# returns 
#  $V->{ASIC} = "06"
#  $V->{PCB}  = "14"
#  $V->{PROM} = "4.05.00"
#  $V->{FLASH} = "048.71.3D";

sub getVersion {
  my($agent, $device) = @_;

  my $DIR = System->get_home() . "/snmp/bin";
  my $MIBDIR = System->get_home() . "/snmp/share/snmp/mibs";
  my $renv = System->get_renv();
  my $TO = $renv->{'timeout.snmp'} || 10;
  my $ip = $device->{ip};
  my $wwn = $device->{wwn};
  my $mibwwn = Util->wwn2mib($wwn);
  my $public = $renv->{'snmp.community'} || "public";

  $ENV{LD_LIBRARY_PATH} = System->get_home() . "/snmp/lib";
  my $OPT  = "-v1 -c$public -r1 -t$TO -M$MIBDIR -mall " . System->snmpopt() . "b";

  my($err0,$version) = Util->run_command("$DIR/snmpwalk $OPT $ip connUnitRevsRevId.$mibwwn", 
                      "sanbox_version.txt", 2*$TO + 5);

  if ($err0){
    Debug->errNoRepeat( SNMP_SENSOR => $device->{name} , 8, "Run Command error: $err0: $DIR/snmpwalk $OPT $ip connUnitRevsRevId.$mibwwn");
  }


  my %V;

  if ($err0) {
     $ERR = $err0;
     return undef;
  } 
     my (@Val);
     foreach my $l (@$version) {
        next if ($l !~ /$mibwwn/);
        if ($l =~ /RevsRevId/) {
           $l =~ /\.(\d+) = (.*)/;
           my $port = $1;
           my $name = $2;
           $name =~ s/"//g;
           my $ix = index($name, " Hex:");
           $name = substr($name, 0, $ix) if ($ix > 0);
           $Val[$port] = $name;
        } 
     }

  ($err0,$version) = Util->run_command("$DIR/snmpwalk $OPT $ip connUnitRevsDescription.$mibwwn", 
                      "sanbox_version.txt", 2*$TO + 5);
  if ($err0) {
     Debug->errNoRepeat( SNMP_SENSOR => $device->{name} , 8, "Run Command error: $err0: $DIR/snmpwalk $OPT $ip connUnitRevsDescription.$mibwwn");
     $ERR = $err0;
     return undef;
  } 
  my (@N);
  foreach my $l (@$version) {
     next if ($l !~ /$mibwwn/);
     if ($l =~ /RevsDescription/) {
        $l =~ /\.(\d+) = (.*)/;
        my $port = $1;
        my $name = $2;
        $name =~ s/"//g;
        $name =~ s/ /_/g;
        $N[$port] = $name;
     }
  }
  my $x;
  for ($x=1; $x <= $#N; $x++) {
     $V{$N[$x]} = $Val[$x];
  }
  return \%V;

}

sub INSTRUMENTATION {
  my($agent, $device) = @_;
  my(@s, %dev, $in, %info);
  my($connect_err, %C, $err0, $system, $sensors);
  my($port,  $config, $err4);
  my(%R);
  my $ip     = $device->{ip};
  my(@counts, @stats, $stat, $x);
  my $DIR    = System->get_home() . "/snmp/bin";
  my $MIBDIR = System->get_home() . "/snmp/share/snmp/mibs";
  my $renv   = System->get_renv();
  my $TO     = $renv->{'timeout.snmp'};
  my $wwn    = $device->{wwn};
  my $mibwwn = Util->wwn2mib($wwn);
  my $ping_to  = $renv->{'timeout.ping'} || 10;
  $DB::single = 1;
  my $public = $renv->{'snmp.community'} || "public";

  return Report->readTest($device) if (System->get_testMode());

  $ENV{LD_LIBRARY_PATH} = System->get_home() . "/snmp/lib";
  my $OPT    = "-v1 -c$public -r1 -t$TO -M$MIBDIR -mall " . System->snmpopt() . "b";

  if (!Util->ping($device->{ipno}, $ping_to)) {
       $R{'rc.error'} = "Cannot ping $device->{ipno} Util ping: $Util::PING_ERR DONE";
       return \%R;
  }

  Timelapse->startDev( $device);

  my ($stderr);
  ($err0,$system, $stderr) = Util->run_command("$DIR/snmpwalk $OPT $ip system", 
                      "sanbox_version.txt", 2*$TO+5);

  if ($stderr =~ /Timeout/) {
     $R{'rc.error'} = $stderr;
     return \%R;
  } elsif ($err0) {
     Debug->errNoRepeat( SNMP_SENSOR => $device->{name} , 8, "Run Command error: $err0: $DIR/snmpwalk $OPT $ip system");
     $R{'rc.error'} = $err0;
     return \%R;
  } elsif ($#$system < 0) {
     $R{'rc.error'} = "No answer from switch at $ip";
     return \%R;
  } elsif ("@$system" =~ /Timeout:/) {
     $R{'rc.error'} = "@$system";
     return \%R;
  }

  foreach my $x (@$system) {
     my(@a) = split(/ +\= */, $x);
     $a[1] = substr($a[1],1,-1) if (substr($a[1],0,1) eq "\"");
     $a[0] = substr($a[0],0,-2) if (substr($a[0], -2) eq ".0");
     $a[1] =~ s/Counter\d\d\://;
     $R{"system.$a[0]"} =  $a[1];
  }


  my($max) = 0;
  my( @T, %CNT, @MAP);

  foreach my $el ('Type','Status','Message','Name') {
    ($err0,$sensors) = Util->run_command("$DIR/snmpwalk $OPT $ip connUnitSensor$el.$mibwwn", 
                      "sanbox_version.txt", 2*$TO+5);

    if ($err0 || $#$sensors < 0) {
       Debug->errNoRepeat( SNMP_SENSOR => $device->{name} , 8, "Run Command error: $err0: $DIR/snmpwalk $OPT $ip connUnitSensor$el.$mibwwn");   
    }

    foreach my $x (@$sensors) {
       next if ($x !~ /$mibwwn/);
       $x =~ /(.*)\.(\d+) = (.*)/;
       my $name = $1; 
       my $ix   = $2; 
       my $val  = $3;
       $val =~ s/"//g;
       my $i = index($val,"(");
       $val = substr($val,0,$i) if ($i > 0);
       if ($el eq "Type") {
          $CNT{$val}++;
          $MAP[$ix] = "$val." . $CNT{$val};
       } else {
          my $ix2 = $MAP[$ix];
	  my $el1 = lc($el);
          $R{"sensor.$ix2.$el1"} = $val;
          $max = $ix if ($ix > $max);
       }
    }
  }

  $R{"sensor.count"} = $max;

  # Get switch uptime
  my($err8,$uptime) = Util->run_command("$DIR/snmpwalk $OPT $ip sysuptime ", 
                       "sanbox_version.txt", 2*$TO+5);

  if ($err8){
       Debug->errNoRepeat( SNMP_SENSOR => $device->{name} , 8, "Run Command error: $err8: $DIR/snmpwalk $OPT $ip sysuptime");   
  }
  foreach my $x (@$uptime) {
     my(@a) = split(/\(/, $x);
     my(@b) = split(/\)/, $a[1]);
     $R{"system.uptime"} =  $b[0];

  }

  $agent->getStats($TO, $ip, \%R, $device, $mibwwn);
  $agent->getLinks($device, \%R);
  $agent->getPortStatus($device, \%R);

  if (index("|$renv->{categories}|", "|san|") >= 0) {
     $R{"FC_COUNTERS"} = $agent->FCfromDevice($device);
  }

  $agent->addIdentification(\%R);
  my $Version = $agent->getVersion($device);
  foreach my $el (keys %$Version) {
     $R{"info.version.$el"} = $Version->{$el};
  }

  $R{"id.wwn"} = $device->{wwn};
  Timelapse->stopDev( $device);

  $R{'rc.key'} = $R{"id.wwn"};
  return \%R;
}



sub DESTROY {}

sub FCfromDevice {
  my($class, $dev) = @_;

  my($db, $VAR1);
  $ERR = undef;
  my $renv = System->get_renv();
  my $rc;
  if ($dev->{host} && ($dev->{host} ne $renv->{hostname} )) {
    $rc = Util::Http->getCommand($dev->{hostIpno},
             "Agent::SWITCH2::FC1&telnet=$dev->{telnet}".
                "&wwn=$dev->{wwn}&key=$dev->{key}".
                "&ipno=$dev->{ipno}&HTTP=1&name=$dev->{name}", 
                30);
    $rc = "ERR $Util::Http::ERROR" if (!defined($rc));

    if (substr($rc,0,3) eq "ERR" ) {
      $ERR = $rc;
      return undef;
    } else {
      eval substr($rc,3);
      $ERR = $rc if (!$VAR1);
      return $VAR1;
    }
  } else {
    return &get_FC1($dev);
  }
}

sub ERR {
  return $ERR;
}


#  telnet, ipno, wwn, key, name

sub get_FC1 {
  my($dev) = @_;

  
  my (%X, @R, $x);
  my $renv = System->get_renv();
  my $DIR = System->get_home() . "/snmp/bin";
  my $TO = 10;
  my $max = 0;

  my $passwd = System->getDevicePassword($dev, "switch");
  my $tmpfile = System->get_home() . "/DATA/mytmpdata.$dev->{ipno}";
  open(OOF, ">$tmpfile");
  print OOF "$passwd";
  close OOF;



  my $SDIR = System->get_home() . "/sbin" ;
  my($err,$rem, $stderr) = Util->run_command( "$SDIR/qlogiccounters $dev->{ipno}", 
                      "sanbox_version.txt", 2*$TO+5, {cache => 0});
  $ERR = $err . $stderr;
  unlink ($tmpfile);
  foreach my $l (@$rem) {
    if ($l =~ /(\d+)\.(\d+)\s*=\s*(\d+)/) {
       my $port = $1;
       my $fc_no = $2;
       my $val = $3;
       $R[$port][$fc_no] = $val;
       $max = $port if ($port > $max);
    }
  }
  for ($x=0; $x <= $max; $x++) {
      my $key = "|$dev->{key}|port.$x|switch";
      next if (!defined($R[$x]));

      $X{$key} = ($R[$x][1]+0) . "\t" .
                 ($R[$x][2]+0) . "\t" .
                 ($R[$x][3]+0) . "\t" .
                 ($R[$x][4]+0) . "\t" .
                 ($R[$x][5]+0) . "\t" .
                 ($R[$x][6]+0) . "\t" . 
                 ($R[$x][7]+0) . "\t" . 
                 ($R[$x][8]+0) . "\t";

  }

  my $out = {enc => {$dev->{wwn} => $dev->{name}} , data => \%X };

  if ($dev->{HTTP}) {
require Data::Dumper;
    print "OK " . Data::Dumper::Dumper($out);
  } else {
    return $out;
  }
}



sub old_FC_counters {
  my ($TO, $dev, $DIR , $max);
  my $ip = $dev->{ipno} || $dev->{ip};
  my $wwn    = $dev->{wwn};
  my $mibwwn = Util->wwn2mib($wwn);
  my $cnt = 1;

  my $renv = System->get_renv();
  my $public = $renv->{'snmp.community'} || "public";
  my $MIBDIR = System->get_home() . "/snmp/share/snmp/mibs";
  my $OPT    = "-v1 -c$public -r1 -t$TO -M$MIBDIR -mall " . System->snmpopt() . "b";

  my($err5, $errors) = Util->run_command("$DIR/snmpwalk $OPT $ip fcFxPortName");
  if ($err5){
       Debug->errNoRepeat( SNMP_SENSOR => $dev->{name} , 8, "Run Command error: $err5: $DIR/snmpwalk $OPT $ip fcFxPortName");   
  }
  my %ENC;
  my $enc_no;
  foreach my $l (@$errors) {
     if ($l =~ /(\d+)\.(\d+) = Hex: (.+)/) {
          my $lwwn = $3;
          $lwwn =~ s/ //g;
          $lwwn  = lc($lwwn);
          $lwwn = substr($lwwn,4);
          my $port = $2;
          $enc_no = $1;
          if ($port == 1) {
            last if (substr($wwn,4) eq $lwwn);
          }
      }
  }

  my(@ALL, @R); 
  my $err;
  my $fc;

  # CRC
  ($err,$fc) = Util->run_command( 
          "$DIR/snmpwalk $OPT $ip .1.3.6.1.2.1.75.1.3.1.1.6.$enc_no", "sanbox_version.txt", 2*$TO+5, {cache => 0});
  $ALL[4] = $fc;

  # ITW
  ($err,$fc) = Util->run_command( 
          "$DIR/snmpwalk $OPT $ip .1.3.6.1.2.1.75.1.3.1.1.5.$enc_no", "sanbox_version.txt", 2*$TO+5, {cache => 0});
  $ALL[6] = $fc;
  # IN
  ($err,$fc)  = Util->run_command( 
          "$DIR/snmpwalk $OPT $ip mib-2.75.1.4.3.1.1.$enc_no", "sanbox_version.txt", 2*$TO+5, {cache => 0});
  $ALL[7] = $fc;

  # OUT
  ($err,$fc) = Util->run_command( 
          "$DIR/snmpwalk $OPT $ip mib-2.75.1.4.3.1.2.$enc_no", "sanbox_version.txt", 2*$TO+5, {cache => 0});
  $ALL[8] = $fc;

  foreach my $order (4,6,7,8) {
     my $values = $ALL[$order];
     foreach my $l (@$values) {
       if ($l =~ /\.(\d+) = Counter32: (\d+)/) {
         my $port = $1 - 1;
         my $val = $2;
         $R[$port][$order] = $val;
         $max = $port if ($port > $max);
       }
     }
  }

}

sub FRUS {
  my($class, $r, $name) = @_;
  my($v) = $r->{_value};
  my $devtype = $r->category();
  my $model = $v->{'info.Product'} || $v->{"system.sysDescr"};
  my @FRUS;
  my $rev;
  if (exists($v->{"info.version.PROM_Firmware_Revision"})) {
     $rev = $v->{"info.version.PROM_Firmware_Revision"} . "-" . 
            $v->{"info.version.FLASH_Firmware_Revision"};
  } else {
     $rev = $v->{"info.version.Active_Firmware_image"};
  }
  my $type = $v->{"id.device_userLabel"};
  push(@FRUS, [$name, "switch", "switch", $type, "Qlogic", $model, " N/A", $rev, " N/A"]);
  return \@FRUS;

}

sub REPORT {
  my($class, $host, $r, $arg) = @_;

  my($out);
  my($tableCnt) = $arg->{tableCnt};
  my($v) = $r->content();

  $out .= $class->reportHead("SWITCH2", $r, undef, $v->{"id.connect_errs"});

  my($version) = $v->subset("info.version.");
  my($cnt) =0;
  my $prod = $v->{'info.Product'} || $v->{"system.sysDescr"};
  $out .= "<tr><td colspan=4><center>$prod</td>
    <tr><td align=right bgcolor=$Style::LIGHT>IP :<td colspan=3>&nbsp;$v->{'id.ipno'}</td>\n";
  

  foreach my $x (sort keys %$version) {
    next if($x =~ /ASIC/);
    next if($x =~ /Hardware_PCB/);
    $out .= "<tr>";
    my $x0 = $x;
    $x0 =~ s/Version//;
    $x0 =~ s/_/ /g;
    $out .= "<td align=right width=40% bgcolor=$Style::LIGHT>$x0 :<td colspan=3>&nbsp;$version->{$x}</td>\n";
  }
  $out .= "<tr><td align=right bgcolor=$Style::LIGHT> WWN :</td>
               <td colspan=3>&nbsp;$v->{'id.device_wwn'}</td>\n";

  $out .= "</table><table border=1 cellspacing=0 width=100% bgcolor=white>";

  my $x;
  $out .= "<tr bgcolor=$Style::LIGHT><th>Sensor<th>Status<th colspan=2>Description</th>";
  foreach my $el ('board','fan','power-supply') {
    for ($x = 1; $x <= 20; $x++) {
       my $name = $v->{"sensor.$el.$x.name"};
       next if (!$name);
       if($name =~ /Temperature Status Blade (.*)/){
         $name = "Temperature Sensor $1";
       }
       my $status;
       my $desc = $v->{"sensor.$el.$x.message"};
       if($desc =~ /NotInstalled/){
         $status = "na"
       }else{
          $status = $v->{"sensor.$el.$x.status"};
       }
       $out .= "<tr><td>&nbsp;$name<td>&nbsp;$status<td colspan=2>&nbsp;$desc</td>\n";
    }
  }

  $out .= "</table><table border=1 cellspacing=0 width=100% bgcolor=white>\n";
  if($v->{"port.count"} > 33){
     $out .= "<tr bgcolor=$Style::LIGHT><th>Port<th>Slot / Port<th>Admin State<th>State<th>WWN of Connected Device<th>Speed</th>\n";
  }else{
     $out .= "<tr bgcolor=$Style::LIGHT><th>Port<th>Admin State<th>State<th>WWN of Connected Device<th>Speed</th>\n";
  }
  my $blade = 0;
  my $blade_port;
  for ($x=0; $x <= 64; $x++) {
     my $type   = $v->{"port.$x.type"};
     my $speed  = $v->{"port.$x.speed"};
     my $state  = $v->{"port.$x.state"};
     my $adminstate  = $v->{"port.$x.state.AdmStatus"};
     my $wwn    = $v->{"port.$x.link_wwn"};
     next if (!$state);
     my $bg = "";
     my $abg = "";
     if(!($state eq "online")){
        $bg = "bgcolor=#FFFFD0";
     }
     if(!($adminstate eq "online")){
        $abg = "bgcolor=#FFFFD0";
     }
     
     if($v->{"port.count"} > 33){
        # show blades -  8 ports/blade
	$blade_port = $x%8;
	if($blade_port == 0){
	   $blade++;
	   if($blade == 5){
	     # blade 5 is CPU
	     $blade++;
	   }
	}
	$out .= "<tr><td>&nbsp;$x<td>$blade - $blade_port<td $abg>&nbsp;$adminstate<td $bg>&nbsp;$state<td>&nbsp;$wwn<td>&nbsp;$speed</td>\n";

     }
     else{
        $out .= "<tr><td>&nbsp;$x<td $abg>&nbsp;$adminstate<td $bg>&nbsp;$state<td>&nbsp;$wwn<td>&nbsp;$speed</td>\n";
     }
  }

  if (!$tableCnt) {
    $out .= "</table>";
  }
  return $out;

}



sub REPORT2 {
  my($class, $host, $r, $arg) = @_;

  my($out);
  my($v) = $r->{_value};

  my $last;
  $out = $class->reportHead("Sun Switch2", $r);
  foreach my $el (sort keys %$v) {
     my($a, $b) = split(/\./, $el);
     if ($a ne $last) {
        $out .= "<tr bgcolor=$Style::LIGHT><td colspan=2>&nbsp;<b>$a</td>\n" if ($a);
        $last = $a;
     }

     $out .= "<tr><td>&nbsp;$el<td>&nbsp;$v->{$el}</td>";
  }
  $out .= "</table>";
  return $out;

}


sub getZones {
  my($class, $DIR, $s_ip, $TO, $V, $dev) = @_;
  my($err);
  my $totzones;
  $totzones = -1;
  my $passwd = System->getDevicePassword($dev, "switch");

  my $tmpfile = System->get_home() . "/DATA/mytmpdata.$dev->{ipno}";
  open(OOF, ">$tmpfile");
  print OOF "$passwd";
  close OOF;


  my($err1,$info) = Util->run_command("$DIR/qlogicswitchzones $s_ip", "sanbox_status.txt", 2*$TO+5);
  $err .= $err1;
  unlink($tmpfile);

  foreach my $l (@$info) {
     if ($l =~ /Number of members/) {
        $totzones++;
     }elsif ($l =~ /Name = (.*)/){
       my $zone_name = $1;
       $V->{"zone.hd_name.$totzones.name"} = $zone_name;
     } elsif ($l =~ /Port = (\d+)/) {
        my $po = $1;
        $V->{"zone.hd.$totzones.members"} .= "$po ";
     }
  }
     $V->{"zone.total"} = $totzones;

  return $err;

}



1;
