diff --git a/xCAT-server/lib/xcat/plugins/ipmi.pm.2 b/xCAT-server/lib/xcat/plugins/ipmi.pm.2
deleted file mode 100644
index 0461f62e6..000000000
--- a/xCAT-server/lib/xcat/plugins/ipmi.pm.2
+++ /dev/null
@@ -1,6688 +0,0 @@
-#!/usr/bin/perl
-# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
-#egan@us.ibm.com
-#modified by jbjohnso@us.ibm.com
-#(C)IBM Corp
-
-package xCAT_plugin::ipmi;
-BEGIN
-{
-  $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat';
-}
-use lib "$::XCATROOT/lib/perl";
-use strict;
-use warnings "all";
-use xCAT::GlobalDef;
-use xCAT_monitoring::monitorctrl;
-use xCAT::SPD qw/decode_spd/;
-
-use POSIX qw(ceil floor);
-use Storable qw(store_fd retrieve_fd thaw freeze);
-use xCAT::Utils;
-use xCAT::SvrUtils;
-use xCAT::Usage;
-use Thread qw(yield);
-use LWP 5.64;
-use HTTP::Request::Common;
-my $tfactor = 0;
-my $vpdhash;
-my %bmc_comm_pids;
-my $iem_support;
-eval {
-    require IBM::EnergyManager;
-    $iem_support=1;
-};
-
-require Exporter;
-our @ISA = qw(Exporter);
-our @EXPORT = qw(
-	ipmiinit
-	ipmicmd
-);
-
-sub handled_commands {
-  return {
-    rpower => 'nodehm:power,mgt',
-    renergy => 'nodehm:power,mgt',
-    getipmicons => 'ipmi',
-    rspconfig => 'nodehm:mgt',
-    rvitals => 'nodehm:mgt',
-    rinv => 'nodehm:mgt',
-    rsetboot => 'nodehm:mgt',
-    rbeacon => 'nodehm:mgt',
-    reventlog => 'nodehm:mgt',
-    rfrurewrite => 'nodehm:mgt',
-    getrvidparms => 'nodehm:mgt'
-  }
-}
-
-    
-#use Data::Dumper;
-use POSIX "WNOHANG";
-use IO::Handle;
-use IO::Socket;
-use IO::Select;
-use Class::Struct;
-use Digest::MD5 qw(md5);
-use Digest::SHA1 qw(sha1);
-use POSIX qw(WNOHANG mkfifo strftime);
-use Fcntl qw(:flock);
-
-
-#local to module
-my @rmcp = (0x06,0x00,0xff,0x07);
-my $auth;
-my $rssa = 0x20;
-my $rqsa = 0x81;
-my $seqlun = 0x00;
-my @session_id = (0,0,0,0);
-my @challenge = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
-my @seqnum = (0,0,0,0);
-my $outfd; #File descriptor for children to send messages to parent
-my $currnode; #string to describe current node, presumably nodename
-my $globrc=0;
-my $userid;
-my $passwd;
-my $ipmi_bmcipaddr;
-my $timeout;
-my $port;
-my $debug;
-my $ndebug = 0;
-my @cmdargv;
-my $sock;
-my @user;
-my @pass;
-my $channel_number;
-my %sdr_hash;
-my %fru_hash;
-my %sessiondata; #hold per session variables, in preparation for single-process strategy
-my %pendingtransactions; #list of peers with callbacks, callback arguments, and timer expiry data
-my $ipmiv2=0;
-my $authoffset=0;
-my $enable_cache="yes";
-my $cache_dir = "/var/cache/xcat";
-#my $ibmledtab = $ENV{XCATROOT}."/lib/GUMI/ibmleds.tab";
-use xCAT::data::ibmleds;
-use xCAT::data::ipmigenericevents;
-use xCAT::data::ipmisensorevents;
-my $cache_version = 2;
-my $frudex; #iterator for initfru to use
-
-my $status_noop="XXXno-opXXX";
-
-my %idpxthermprofiles = (
-    '0z' => [0x37,0x41,0,0,0,0,5,0xa,0x3c,0xa,0xa,0x1e],
-    '1a' => [0x30,0x3c,0,0,0,0,5,0xa,0x3c,0xa,0xa,0x1e], 
-    '2b' => [0x30,0x3c,0,0,0,0,5,0xa,0x3c,0xa,0xa,0x1e], 
-    '3c' => [0x30,0x3c,0,0,0,0,5,0xa,0x3c,0xa,0xa,0x1e], 
-    '4d' => [0x37,0x44,0,0,0,0,5,0xa,0x3c,0xa,0xa,0x1e], 
-    '5e' => [0x37,0x44,0,0,0,0,5,0xa,0x3c,0xa,0xa,0x1e], 
-    '6f' => [0x35,0x44,0,0,0,0,5,0xa,0x3c,0xa,0xa,0x1e], 
-);
-my %codes = (
-	0x00 => "Command Completed Normal",
-	0xC0 => "Node busy, command could not be processed",
-	0xC1 => "Invalid or unsupported command",
-	0xC2 => "Command invalid for given LUN",
-	0xC3 => "Timeout while processing command, response unavailable",
-	0xC4 => "Out of space, could not execute command",
-	0xC5 => "Reservation canceled or invalid reservation ID",
-	0xC6 => "Request data truncated",
-	0xC7 => "Request data length invalid",
-	0xC8 => "Request data field length limit exceeded",
-	0xC9 => "Parameter out of range",
-	0xCA => "Cannot return number of requested data bytes",
-	0xCB => "Requested Sensor, data, or record not present",
-	0xCB => "Not present",
-	0xCC => "Invalid data field in Request",
-	0xCD => "Command illegal for specified sensor or record type",
-	0xCE => "Command response could not be provided",
-	0xCF => "Cannot execute duplicated request",
-	0xD0 => "Command reqponse could not be provided. SDR Repository in update mode",
-	0xD1 => "Command response could not be provided. Device in firmware update mode",
-	0xD2 => "Command response could not be provided. BMC initialization or initialization agent in progress",
-	0xD3 => "Destination unavailable",
-	0xD4 => "Insufficient privilege level",
-	0xD5 => "Command or request parameter(s) not supported in present state",
-	0xFF => "Unspecified error",
-);
-
-#Payload types:
-#  0 => IPMI  (format 1 0)
-#  1 => SOL 1 0
-#  0x10 => rmcp+ open req 1 0
-#  0x11 => rmcp+ response 1 0
-#  0x12 => rakp1 (all 1 0)
-#  0x13 => rakp2
-#  0x14 => rakp3
-#  0x15 => rakp4
-  
-my %units = (
-	0 => "", #"unspecified",
-	1 => "C",
-	2 => "F",
-	3 => "K",
-	4 => "Volts",
-	5 => "Amps",
-	6 => "Watts",
-	7 => "Joules",
-	8 => "Coulombs",
-	9 => "VA",
-	10 => "Nits",
-	11 => "lumen",
-	12 => "lux",
-	13 => "Candela",
-	14 => "kPa",
-	15 => "PSI",
-	16 => "Newton",
-	17 => "CFM",
-	18 => "RPM",
-	19 => "Hz",
-	20 => "microsecond",
-	21 => "millisecond",
-	22 => "second",
-	23 => "minute",
-	24 => "hour",
-	25 => "day",
-	26 => "week",
-	27 => "mil",
-	28 => "inches",
-	29 => "feet",
-	30 => "cu in",
-	31 => "cu feet",
-	32 => "mm",
-	33 => "cm",
-	34 => "m",
-	35 => "cu cm",
-	36 => "cu m",
-	37 => "liters",
-	38 => "fluid ounce",
-	39 => "radians",
-	40 => "steradians",
-	41 => "revolutions",
-	42 => "cycles",
-	43 => "gravities",
-	44 => "ounce",
-	45 => "pound",
-	46 => "ft-lb",
-	47 => "oz-in",
-	48 => "gauss",
-	49 => "gilberts",
-	50 => "henry",
-	51 => "millihenry",
-	52 => "farad",
-	53 => "microfarad",
-	54 => "ohms",
-	55 => "siemens",
-	56 => "mole",
-	57 => "becquerel",
-	58 => "PPM",
-	59 => "reserved",
-	60 => "Decibels",
-	61 => "DbA",
-	62 => "DbC",
-	63 => "gray",
-	64 => "sievert",
-	65 => "color temp deg K",
-	66 => "bit",
-	67 => "kilobit",
-	68 => "megabit",
-	69 => "gigabit",
-	70 => "byte",
-	71 => "kilobyte",
-	72 => "megabyte",
-	73 => "gigabyte",
-	74 => "word",
-	75 => "dword",
-	76 => "qword",
-	77 => "line",
-	78 => "hit",
-	79 => "miss",
-	80 => "retry",
-	81 => "reset",
-	82 => "overflow",
-	83 => "underrun",
-	84 => "collision",
-	85 => "packets",
-	86 => "messages",
-	87 => "characters",
-	88 => "error",
-	89 => "correctable error",
-	90 => "uncorrectable error",
-);
-
-my %chassis_types = (
-	0 => "Unspecified",
-	1 => "Other",
-	2 => "Unknown",
-	3 => "Desktop",
-	4 => "Low Profile Desktop",
-	5 => "Pizza Box",
-	6 => "Mini Tower",
-	7 => "Tower",
-	8 => "Portable",
-	9 => "LapTop",
-	10 => "Notebook",
-	11 => "Hand Held",
-	12 => "Docking Station",
-	13 => "All in One",
-	14 => "Sub Notebook",
-	15 => "Space-saving",
-	16 => "Lunch Box",
-	17 => "Main Server Chassis",
-	18 => "Expansion Chassis",
-	19 => "SubChassis",
-	20 => "Bus Expansion Chassis",
-	21 => "Peripheral Chassis",
-	22 => "RAID Chassis",
-	23 => "Rack Mount Chassis",
-);
-
-my %MFG_ID = (
-	2 => "IBM",
-	343 => "Intel",
-);
-
-my %PROD_ID = (
-	"2:34869" => "e325",
-	"2:3" => "x346",
-	"2:4" => "x336",
-	"343:258" => "Tiger 2",
-	"343:256" => "Tiger 4",
-);
-
-my $localtrys = 3;
-my $localdebug = 0;
-
-struct SDR_rep_info => {
-	version		=> '$',
-	rec_count	=> '$',
-	resv_sdr	=> '$',
-};
-
-struct SDR => {
-	rec_type			=> '$',
-	sensor_owner_id		=> '$',
-	sensor_owner_lun	=> '$',
-	sensor_number		=> '$',
-	entity_id			=> '$',
-	entity_instance		=> '$',
-	sensor_init			=> '$',
-	sensor_cap			=> '$',
-	sensor_type			=> '$',
-	event_type_code		=> '$',
-	ass_event_mask		=> '@',
-	deass_event_mask	=> '@',
-	dis_read_mask		=> '@',
-	sensor_units_1		=> '$',
-	sensor_units_2		=> '$',
-	sensor_units_3		=> '$',
-	linearization		=> '$',
-	M					=> '$',
-	tolerance			=> '$',
-	B					=> '$',
-	accuracy			=> '$',
-	accuracy_exp		=> '$',
-	R_exp				=> '$',
-	B_exp				=> '$',
-	analog_char_flag	=> '$',
-	nominal_reading		=> '$',
-	normal_max			=> '$',
-	normal_min			=> '$',
-	sensor_max_read		=> '$',
-	sensor_min_read		=> '$',
-	upper_nr_threshold	=> '$',
-	upper_crit_thres	=> '$',
-	upper_ncrit_thres	=> '$',
-	lower_nr_threshold	=> '$',
-	lower_crit_thres	=> '$',
-	lower_ncrit_thres	=> '$',
-	pos_threshold		=> '$',
-	neg_threshold		=> '$',
-	id_string_type		=> '$',
-	id_string		=> '$',
-	#LED id
-	led_id		=> '$',
-    fru_type  => '$',
-    fru_subtype  => '$',
-};
-
-struct FRU => {
-	rec_type			=> '$',
-	desc				=> '$',
-	value				=> '$',
-};
-
-sub decode_fru_locator { #Handle fru locator records
-    my @locator = @_;
-	my $sdr = SDR->new();
-	$sdr->rec_type(0x11);
-    $sdr->sensor_owner_id("FRU");
-    $sdr->sensor_owner_lun("FRU");
-    $sdr->sensor_number($locator[7]);
-    unless ($locator[8] & 0x80 and ($locator[8] & 0x1f) == 0 and $locator[9] == 0) {
-        #only logical devices at lun 0 supported for now
-        return undef;
-    }
-    unless (($locator[16] & 0xc0) == 0xc0) { #Only unpacked ASCII for now, no unicode or BCD plus yet
-        return undef;
-    }
-    my $idlen = $locator[16] & 0x3f;
-    unless ($idlen > 1) { return undef; }
-    $sdr->id_string(pack("C*",@locator[17..17+$idlen-1]));
-    $sdr->fru_type($locator[11]);
-    $sdr->fru_subtype($locator[12]);
-
-    return $sdr;
-}
-
-sub waitforack {
-    my $sock = shift;
-    my $select = new IO::Select;
-    $select->add($sock);
-    my $str;
-    if ($select->can_read(60)) { # Continue after 60 seconds, even if not acked...
-        if ($str = <$sock>) {
-        } else {
-           $select->remove($sock); #Block until parent acks data
-        }
-    }
-}
-sub translate_sensor {
-   my $reading = shift;
-   my $sdr = shift;
-   my $unitdesc;
-   my $value;
-   my $lformat;
-   my $per;
-   $unitdesc = $units{$sdr->sensor_units_2};
-   if ($sdr->rec_type == 1) {
-    $value = (($sdr->M * $reading) + ($sdr->B * (10**$sdr->B_exp))) * (10**$sdr->R_exp);
-   } else {
-    $value = $reading;
-   }
-   if($sdr->rec_type !=1 or $sdr->linearization == 0) {
-      $reading = $value;
-      if($value == int($value)) {
-         $lformat = "%-30s%8d%-20s";
-      } else {
-         $lformat = "%-30s%8.3f%-20s";
-      }
-   } elsif($sdr->linearization == 7) {
-      if($value > 0) {
-         $reading = 1/$value;
-      } else {
-         $reading = 0;
-      }
-      $lformat = "%-30s%8d %-20s";
-   } else {
-      $reading = "RAW($sdr->linearization) $reading";
-   }
-   if($sdr->sensor_units_1 & 1) {
-      $per = "% ";
-   } else {
-      $per = " ";
-   }
-   my $numformat = ($sdr->sensor_units_1 & 0b11000000) >> 6;
-   if ($numformat) {
-     if ($numformat eq 0b11)  {
-        #Not sure what to do.. leave it alone for now
-     } else {
-        if ($reading & 0b10000000) {
-          if ($numformat eq 0b01) {
-             $reading = 0-((~($reading&0b01111111))&0b1111111);
-          } elsif ($numformat eq 0b10) {
-             $reading = 0-(((~($reading&0b01111111))&0b1111111)+1);
-          }
-        }
-     }
-   }
-   if($unitdesc eq "Watts") {
-      my $f = ($reading * 3.413);
-      $unitdesc = "Watts (" . int($f + .5) . " BTUs/hr)";
-      #$f = ($reading * 0.00134);
-      #$unitdesc .= " $f horsepower)";
-   }
-   if($unitdesc eq "C") {
-      my $f = ($reading * 9/5) + 32;
-      $unitdesc = "C (" . int($f + .5) . " F)";
-   }
-   if($unitdesc eq "F") {
-      my $c = ($reading - 32) * 5/9;
-      $unitdesc = "F (" . int($c + .5) . " C)";
-   }
-   return "$reading $unitdesc";
-}
-
-
-sub openrmcpplussession {
-    #we would request ciphersuite 3, but because AES encryption is surprisingly not included in most distro perl
-    #crypt::cbc may be of interest
-    #we are going to start with ciphersuite 2 for now.  This is roughly equivalent to 1.5 security
-    #table 13-9
-    #table 13-7 has 1 == SHA1, so does 13-18
-    #table 13-9 has AES-CBC-128 as 1, none as 0
-    my $sessdata = shift;
-    my @msg = (6,0,0xff,7,6); #RMCP header, ASF 2, FF seq#, 07 for IPMI, authtype of ipmi2
-    push @msg, 0x10; #Set payload type to 10h to indicate an open rmcp+ session request
-    push @msg, (0,0,0,0); #session id of null as it is non-applicable
-    push @msg, (0,0,0,0); #seqnum should be zero for this
-#   need to calculate the payload length, store in 16 bits
-    my @payload;
-    my $tag = rand(255); #tag to identify this packet to IPMI device and ourlesves
-    push @payload, $tag;
-    push @payload, 0; #request max privilege level rather than specific privileged
-    push @payload, (0,0); #reserved space, making zero
-    my $sessid = rand(4294967295); #pick a session id, then put the pieces in the message
-    $sessdata->{client_sessionid} = $sessid; #Store with the session data for future reference
-    push @payload, $sessid >> 24 & 0xff;
-    push @payload, $sessid >> 16 & 0xff;
-    push @payload, $sessid >> 8 & 0xff;
-    push @payload, $sessid >> 0 & 0xff;
-    push @payload, (0,0,0,8,1,0,0,0); #SHA1-96 auth
-    push @payload, (1,0,0,8,1,0,0,0); #sha1-96 integrity
-    push @payload, (2,0,0,8,0,0,0,0); #no confidentiality (TODO: AES)
-    my $psize = scalar @payload;
-    push @msg, $psize >> 0 & 0xff;
-    push @msg, $psize >> 8 & 0xff;
-    push @msg, @payload;
-	my $send = pack('C*',@msg);#TODO: split here and register callback instead of blocking
-    my $error;
-	if(!$sock->send($send)) {
-		$error = $!;
-	}
-    if ($error) {
-        return $error;
-    }
-	my $s = IO::Select->new($sock); 
-	#local $SIG{ALRM} = sub { $timedout = 1 and die };
-	#alarm($timeout);
-	my $received = $s->can_read($timeout);
-    my $recv;
-	if($received and $received > 0) {
-		if ($sock->recv($recv,1300)) {
-			if($recv) {
-				my @response = unpack("C*",$recv);
-                use Data::Dumper;
-                print Dumper(\@response);
-                die 'happy';
-			}
-        }
-    }
-}
-
-sub ipmi_event_loop_iter { #one iteration of an event loop
-	my $s = IO::Select->new($sock); 
-    my $received = $s->can_read(0);
-    my $data;
-    my $peerinf;
-    my $peerport;
-    my $peeraddr;
-    my @cookeddata;
-    while ($s->can_read(0)) {
-        $peerinf = $sock->recv($data,1500); #No Jumbo frames I suppose
-        ($peerport,$peeraddr) = sockaddr_in($peerinf);
-        $peeraddr = inet_ntoa($peeraddr); #Perhaps not IPv6 friendly, but neither is IPMI currently
-        unless ($pendingtransactions{$peeraddr}) { #if we have no pending transactions for this peer, skip him
-            next; #In theory, an SOL function would just leave a callback registered
-        }
-        #For now, we only support one transaction per peer, as we have no mechanism to distinguish one packet from another
-        #may extend this segment to deep dive and support one pending transaction per payload type per peer (where we classify IPMI 1.5 as a 'payload of its own) to allow SOL data and a request to live together on single sessions and be properly sorted on the wa out. 
-        @cookeddata = unpack('C*',$data);
-        if (defined $pendingtransactions{$peeraddr}->{callback}) {
-            pendingtransactions{$peeraddr}->{callback}->($pendingtransactions{$peeraddr}->{callback_args},{},@cookeddata);
-        }
-    }
-    my $currtime = time;
-
-    foreach $peeraddr (keys %pendingtransactions) {
-        if ($pendingtransactions{$peeraddr}->{timeout_time} > $currtime) {
-            if ($pendingtransactions{$peeraddr}->{retries} > 0) {
-                $pendingtransactions{$peeraddr}->{retries} -= 1;
-                $pendingtransactions{$peeraddr}->{timeout_time} = time()+$timeout;
-            } else {
-                $pendingtransactions{$peeraddr}->{callback}->($pendingtransactions{$peeraddr}->{callback_args},{timedout=>1});
-                unless ($pendingtransactions{$peeraddr}->{persist_callback}) {
-                    delete $pendingtransactions{$peeraddr};
-                }
-            }
-        }
-    }
-}
-        
-
-
-
-
-
-sub ipmiv2sessionestablish {
-    my $sessdata = shift;
-    openrmcpplussession($sessdata);
-}
-sub ipmiinit {
-	my $ipmimaxp = 80;
-	my $ipmitimeout = 3;
-	my $ipmitrys = 3;
-	my $ipmiuser = 'USERID';
-	my $ipmipass = 'PASSW0RD';
-	my $tmp;
-
-	
-	my $table = xCAT::Table->new('site');
-	if ($table) {
-		($tmp)=$table->getAttribs({'key'=>'ipmimaxp'},'value');
-		if (defined($tmp)) { $ipmimaxp=$tmp->{value}; }
-		($tmp)=$table->getAttribs({'key'=>'ipmitimeout'},'value');
-		if (defined($tmp)) { $ipmitimeout=$tmp->{value}; }
-		($tmp)=$table->getAttribs({'key'=>'ipmiretries'},'value');
-		if (defined($tmp)) { $ipmitrys=$tmp->{value}; }
-		($tmp)=$table->getAttribs({'key'=>'ipmisdrcache'},'value');
-	}
-	$table = xCAT::Table->new('passwd');
-	if ($table) {
-		($tmp)=$table->getAttribs({'key'=>'ipmi'},'username','password');
-		if (defined($tmp)) {
-			$ipmiuser = $tmp->{username};
-			$ipmipass = $tmp->{password};
-		}	
-	}
-	return($ipmiuser,$ipmipass,$ipmimaxp,$ipmitimeout,$ipmitrys);
-}
-
-sub ipmicmd {
-	my $node = shift;
-	$port = shift;
-	$userid = shift;
-	$passwd = shift;
-	$timeout = shift;
-	$localtrys = shift;
-	$debug = shift;
-    my $sessdata = shift;
-	$localdebug = $debug;
-
-	if($userid eq "(null)") {
-		$userid = "";
-	}
-	if($passwd eq "(null)") {
-		$passwd = "";
-	}
-
-	@user = dopad16($userid);
-	@pass = dopad16($passwd);
-
-	$seqlun = 0x00;
-	@session_id = (0,0,0,0);
-    $sessdata->{session_id} = [0,0,0,0];
-	@challenge = (0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
-	@seqnum = (0,0,0,0);
-	$authoffset=0;
-
-	my $command = shift;
-    @cmdargv = @_;
-	my $subcommand = shift;
-
-
-	my $rc=0;
-	my $text="";
-	my $error="";
-	my @output;
-	my $noclose=0;
-
-	my $packed_ip = gethostbyname($node);
-	if(!defined($packed_ip)) {
-		$text = "failed to get IP for $node";
-		return(2,$text);
-	}
-    $ipmi_bmcipaddr=inet_ntoa($packed_ip);
-
-    #TODO: open only one socket for multiple bmcs (http://docstore.mik.ua/orelly/perl/cookbook/ch17_05.htm)
-	$sock = IO::Socket::INET->new(
-		Proto => 'udp',
-		PeerHost => $ipmi_bmcipaddr, #this would change in a multi-client-single-socket scenario, see url above for how
-		PeerPort => $port,
-	);
-	if(!defined($sock)) {
-		$text = "failed to get socket: $@\n";
-		return(2,$text);
-	}
-
-	$error = getchanauthcap($sessdata); #TODO: split function into submission and response handling halves here
-	if($error) {
-		return(1,$error);
-	}
-	if($debug) {
-		print "$node: gotchanauthcap\n";
-	}
-
-	if($command eq "ping") {
-		return(0,"ping");
-	}
-
-    if (defined $sessdata->{ipmi_version} and $sessdata->{ipmi_version} eq '2,0') { #perform RAKP transation to get session going
-        $error = ipmiv2sessionestablish($sessdata); #TODO: chain to 'setprivlevel' on completion in an asynchronous model
-    } else {
-    	$error = getsessionchallenge(); #TODO: split here to chain to activatesession
-    	if($error) {
-    		return(1,$error);
-    	}
-    	if($debug) {
-    		print "$node: gotsessionchallenge\n";
-    	}
-    
-    	$error = activatesession();
-    	if($error) {
-    		return(1,$error);
-    	}
-    	if($debug) {
-    		print "$node: active session\n";
-    	}
-    }
-    #TODO: split here to setprivlevel
-
-	$error = setprivlevel(); #TODO: split here to generic function call
-	if($error) {
-		return(1,$error);
-	}
-	if($debug) {
-		print "$node: priv level set\n";
-	}
-
-	if($command eq "rpower") { #TODO: this should have been a function on it's own instead of all here
-		if($subcommand eq "stat" || $subcommand eq "state" || $subcommand eq "status") {
-			($rc,$text) = power("stat");
-		}
-		elsif($subcommand eq "on") {
-                   my ($oldrc,$oldtext) = power("stat");
-		   ($rc,$text) = power("on");
-                   if(($rc == 0) && ($text eq "on") && ($oldtext eq "on")) { $text .= " $status_noop"; }
-		}
-		elsif($subcommand eq "nmi") {
-			($rc,$text) = power("nmi");
-		}
-		elsif($subcommand eq "off" or $subcommand eq "softoff") {
-                        my ($oldrc,$oldtext) = power("stat");
-			($rc,$text) = power($subcommand);
-                         if(($rc == 0) && ($text eq "off") && ($oldtext eq "off")) { $text .= " $status_noop"; }
-	
-#			if($text0 ne "") {
-#				$text = $text0 . " " . $text;
-#			}
-		}
-		elsif($subcommand eq "reset") {
-                        my ($oldrc,$oldtext) = power("stat");
-			($rc,$text) = power("reset");
-			$noclose = 0;
-                        if(($rc == 0) && ($text eq "off") && ($oldtext eq "off")) { $text .= " $status_noop"; }
-		}
-		elsif($subcommand eq "cycle") {
-			my $text2;
-
-			($rc,$text) = power("stat");
-
-			if($rc == 0 && $text eq "on") {
-				($rc,$text) = power("off");
-				if($rc == 0) {
-					sleep(5);
-				}
-			}
-
-			if($rc == 0 && $text eq "off") {
-				($rc,$text2) = power("on");
-			}
-
-			if($rc == 0) {	
-				$text = $text . " " . $text2
-			}
-		}
-		elsif($subcommand eq "boot") {
-			my $text2;
-
-			($rc,$text) = power("stat");
-
-			if($rc == 0) {
-				if($text eq "on") {
-					($rc,$text2) = power("reset");
-					$noclose = 0;
-				}
-				elsif($text eq "off") {
-					($rc,$text2) = power("on");
-				}
-				else {
-					$rc = 1;
-				}
-			
-				$text = $text . " " . $text2
-			}
-		}
-		else {
-			$rc = 1;
-			$text = "unsupported command $command $subcommand";
-		}
-	}
-	elsif($command eq "rbeacon") {
-		($rc,$text) = beacon($subcommand);
-	}
-	elsif($command eq "getrvidparms") {
-		($rc,@output) = getrvidparms($subcommand); #TODO: tricky, this wouldn't fit into the non-fork diagram cleanly
-	}
-#	elsif($command eq "info") {
-#		if($subcommand eq "sensorname") {
-#			($rc,$text) = initsdr();
-#			if($rc == 0) {
-#				my $key;
-#				$text="";
-#				foreach $key (keys %sdr_hash) {
-#					my $sdr = $sdr_hash{$key};
-#					if($sdr->sensor_number == @_) {
-#						$text = $sdr_hash{$key}->id_string;
-#						last;
-#					}
-#				}
-##				if(defined $sdr_hash{@_}) {
-##					$text = $sdr_hash{@_}->id_string;
-##				}
-#			}
-#		}
-#	}
-	elsif($command eq "rvitals") {
-		($rc,@output) = vitals($subcommand);
-	}
-	elsif($command eq "renergy") {
-		($rc,@output) = renergy($subcommand);
-	}
-	elsif($command eq "rspreset") {
-		($rc,@output) = resetbmc();
-		$noclose=1;
-	}
-	elsif($command eq "reventlog") {
-		if($subcommand eq "decodealert") {
-			($rc,$text) = decodealert(@_);
-		}
-		else {
-			($rc,@output) = eventlog($subcommand);
-		}
-	}
-	elsif($command eq "rinv") {
-		($rc,@output) = inv($subcommand);
-	}
-	elsif($command eq "fru") {
-		($rc,@output) = fru($subcommand);
-	}
-	elsif($command eq "sol.command") { #TODO: if this is actually still used, it needs to be moved, else, killed
-		my $dc=0;
-
-		$@ = "";
-		eval {
-			my $cc=0;
-			my $kid;
-			my $pid=$$;
-
-			$SIG{USR1} = sub {$cc=0;};
-			$SIG{USR2} = sub {$dc++;};
-			$SIG{CHLD} = sub {while(waitpid(-1,WNOHANG) > 0) { sleep(1); }};
-
-			mkfifo("/tmp/.sol.$pid",0666);
-
-			my $child = xCAT::Utils->xfork();
-			if(!defined $child) {
-				die;
-			}
-
-			if($child > 0) {
-				$cc=1;
-			}
-			else {
-				system("$subcommand /tmp/.sol.$pid");
-
-				if($?/256 == 1) {
-					kill(12,$pid);
-				}
-				if($?/256 == 2) {
-					kill(12,$pid);
-					sleep(1);
-					kill(12,$pid);
-				}
-
-				kill(10,$pid);
-				exit(0);
-			}
-
-			open(FH,"< /tmp/.sol.$pid");
-			my $kpid = <FH>;
-			close(FH);
-			unlink("/tmp/.sol.$pid");
-
-			while($cc == 1) {
-				sleep(5);
-				($rc,$text) = power("stat");
-				$text="";
-				if($rc != 0) {
-					kill(15,$kpid);
-					$cc=0;
-				}
-			}
-
-			do {
-				$kid = waitpid(-1,WNOHANG);
-				sleep(1);
-			} until($kid == -1);
-		};
-		if($@) {
-			@output = $@;
-		}
-
-		$rc = $dc;
-		if($rc == 1) {
-			$noclose = 1;
-		}
-	}
-	elsif($command eq "rgetnetinfo") {
-      my @subcommands = ($subcommand);
-		if($subcommand eq "all") {
-			@subcommands = (
-				"ip",
-				"netmask",
-				"gateway",
-				"backupgateway",
-				"snmpdest1",
-				"snmpdest2",
-				"snmpdest3",
-				"snmpdest4",
-				"community",
-			);
-
-			my @coutput;
-
-			foreach(@subcommands) {
-				$subcommand = $_;
-				($rc,@output) = getnetinfo($subcommand);
-				push(@coutput,@output);
-			}
-
-			@output = @coutput;
-		}
-		else {
-			($rc,@output) = getnetinfo($subcommand);
-		}
-	}
-	elsif($command eq "rspconfig") {
-      foreach ($subcommand,@_) {
-         my @coutput;
-		   ($rc,@coutput) = setnetinfo($_);
-		   if($rc == 0) {
-			   ($rc,@coutput) = getnetinfo($_);
-		   }
-         push(@output,@coutput);
-      }
-	}
-	elsif($command eq "sete325cli") {
-		($rc,@output) = sete325cli($subcommand);
-	}
-	elsif($command eq "sete326cli") {
-		($rc,@output) = sete325cli($subcommand);
-	}
-	elsif($command eq "generic") {
-		($rc,@output) = generic($subcommand);
-	}
-	elsif($command eq "rfrurewrite") {
-		($rc,@output) = writefru($subcommand,shift);
-	}
-	elsif($command eq "fru") {
-		($rc,@output) = fru($subcommand);
-	}
-	elsif($command eq "rsetboot") {
-        	($rc,@output) = setboot($subcommand);
-	}
-
-	else {
-		$rc = 1;
-		$text = "unsupported command $command $subcommand";
-	}
-	if($debug) {
-		print "$node: command completed\n";
-	}
-
-	if($noclose == 0) {
-		$error = closesession();
-		if($error) {
-			return(1,"$text, session close: $error");
-		}
-		if($debug) {
-			print "$node: session closed.\n";
-		}
-	}
-
-	if($text) {
-		push(@output,$text);
-	}
-
-	$sock->close();
-	return($rc,@output);
-}
-
-sub resetbmc {
-	my $netfun = 0x18;
-	my @cmd = (0x02);
-	my @returnd = ();
-	my $rc = 0;
-	my $text;
-	my $error;
-
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-	if ($error) {
-		$rc = 1;
-		$text = $error;
-	} else {
-		if (0 == $returnd[0]) {
-			$text = "BMC reset";
-		} else {
-            if ($codes{$returnd[0]}) {
-                $text = $codes{$returnd[0]};
-            } else {
-			    $text = sprintf("BMC Responded with code %d",$returnd[36]);
-            }
-		}
-	}
-	return($rc,$text);
-}
-
-sub setnetinfo {
-	my $subcommand = shift;
-   my $argument;
-   ($subcommand,$argument) = split(/=/,$subcommand);
-	my @input = @_;
-
-	my $netfun = 0x30;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-	my $match;
-
-	if($subcommand eq "snmpdest") {
-		$subcommand = "snmpdest1";
-	}
-        
-
-   unless(defined($argument)) { 
-      return 0;
-   }
-   if ($subcommand eq "thermprofile") {
-       return idpxthermprofile($argument);
-   }
-   if ($subcommand eq "alert" and $argument eq "on" or $argument =~ /^en/ or $argument =~ /^enable/) {
-      $netfun = 0x10;
-      @cmd = (0x12,0x9,0x1,0x18,0x11,0x00);
-   } elsif ($subcommand eq "alert" and $argument eq "off" or $argument =~ /^dis/ or $argument =~ /^disable/) {
-      $netfun = 0x10;
-      @cmd = (0x12,0x9,0x1,0x10,0x11,0x00);
-   }
-	elsif($subcommand eq "garp") {
-		my $halfsec = $argument * 2; #pop(@input) * 2;
-
-		if($halfsec > 255) {
-			$halfsec = 255;
-		}
-		if($halfsec < 4) {
-			$halfsec = 4;
-		}
-
-		@cmd = (0x01,$channel_number,0x0b,$halfsec);
-	}
-   elsif($subcommand =~ m/community/ ) {
-      my $cindex = 0;
-      my @clist;
-      foreach (0..17) {
-         push @clist,0;
-      }
-      foreach (split //,$argument)  {
-         $clist[$cindex++]=ord($_);
-      }
-      @cmd = (1,$channel_number,0x10,@clist);
-   }
-	elsif($subcommand =~ m/snmpdest(\d+)/ ) {
-		my $dstip = $argument; #pop(@input);
-		my @dip = split /\./, $dstip;
-		@cmd = (0x01,$channel_number,0x13,$1,0x00,0x00,$dip[0],$dip[1],$dip[2],$dip[3],0,0,0,0,0,0);
-	}
-	#elsif($subcommand eq "alert" ) {
-	#    my $action=pop(@input);
-            #print "action=$action\n";
-        #    $netfun=0x28; #TODO: not right
- 
-            # mapping alert action to number
-        #    my $act_number=8;   
-        #    if ($action eq "on") {$act_number=8;}  
-        #    elsif ($action eq "off") { $act_number=0;}  
-        #    else { return(1,"unsupported alert action $action");}    
-	#    @cmd = (0x12, $channel_number,0x09, 0x01, $act_number+16, 0x11,0x00);
-	#}
-	else {
-		return(1,"configuration of $subcommand is not implemented currently");
-	}
-
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-	}
-	else {
-		if($subcommand eq "garp" or $subcommand =~ m/snmpdest\d+/ or $subcommand eq "alert" or $subcommand =~ /community/) {
-			$code = $returnd[0];
-
-			if($code == 0x00) {
-				$text = "ok";
-			}
-		} 
-
-		if(!$text) {
-			$rc = 1;
-			$text = sprintf("unknown response %02x",$code);
-		}
-	}
-
-	return($rc,$text);
-}
-
-sub getnetinfo {
-	my $subcommand = shift;
-   $subcommand =~ s/=.*//;
-   if ($subcommand eq "thermprofile") {
-       my $code;
-       my @returnd;
-       my $thermdata;
-       my $netfun=0x2e<<2; #currently combined netfun & lun, to be simplified later
-       my @cmd = (0x41,0x4d,0x4f,0x00,0x6f,0xff,0x61,0x00);
-       my @bytes;
-       my $error = docmd($netfun,\@cmd,\@bytes);
-       @bytes=splice @bytes,16;
-       my $validprofiles="";
-       foreach (keys %idpxthermprofiles) {
-           if (sprintf("%02x %02x %02x %02x %02x %02x %02x",@bytes) eq sprintf("%02x %02x %02x %02x %02x %02x %02x",@{$idpxthermprofiles{$_}})) {
-               $validprofiles.="$_,";
-           }
-       }
-       if ($validprofiles) {
-           chop($validprofiles);
-           return (0,"The following thermal profiles are in effect: ".$validprofiles);
-       }
-       return (1,sprintf("Unable to identify current thermal profile: \"%02x %02x %02x %02x %02x %02x %02x\"",@bytes));
-   }
-
-	my $netfun = 0x30;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-	my $format = "%-25s";
-
-	if ($subcommand eq "snmpdest") {
-		$subcommand = "snmpdest1";
-	}
-
-   if ($subcommand eq "alert") {
-      $netfun = 0x10;
-      @cmd = (0x13,9,1,0);
-   }
-	elsif($subcommand eq "garp") {
-		@cmd = (0x02,$channel_number,0x0b,0x00,0x00);
-	}
-	elsif ($subcommand =~ m/^snmpdest(\d+)/ ) {
-		@cmd = (0x02,$channel_number,0x13,$1,0x00);
-	}
-	elsif ($subcommand eq "ip") {
-		@cmd = (0x02,$channel_number,0x03,0x00,0x00);
-	}
-	elsif ($subcommand eq "netmask") {
-		@cmd = (0x02,$channel_number,0x06,0x00,0x00);
-	}
-	elsif ($subcommand eq "gateway") {
-		@cmd = (0x02,$channel_number,0x0C,0x00,0x00);
-	}
-	elsif ($subcommand eq "backupgateway") {
-		@cmd = (0x02,$channel_number,0x0E,0x00,0x00);
-	}
-	elsif ($subcommand eq "community") {
-		@cmd = (0x02,$channel_number,0x10,0x00,0x00);
-	}
-	else {
-		return(1,"unsupported command getnetinfo $subcommand");
-	}
-
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-	}
-	else {
-          # response format:
-          # 4 bytes   (RMCP header)
-          # 1 byte    (auth type)
-          # 4 bytes   (session sequence)
-          # 4 bytes   (session id)
-          # 16 bytes  (message auth code, not present if auth type is 0, $authoffset=16)
-          # 1 byte    (ipmi message length)
-          # 1 byte    (requester's address
-          # 1 byte    (netfun, req lun)
-          # 1 byte    (checksum)
-          # 1 byte    (Responder's slave address)
-          # 1 byte    (Sequence number, generated by the requester)
-          # 1 byte    (command)
-          # 1 byte    (return code)
-          # 1 byte    (param revision)
-          # N bytes   (data)
-          # 1 byte    (checksum)
-		if($subcommand eq "garp") {
-			$code = $returnd[0];
-
-			if($code == 0x00) {
-				$code = $returnd[2] / 2;
-				$text = sprintf("$format %d","Gratuitous ARP seconds:",$code);
-			}
-			else {
-				$rc = 1;
-				$text = $codes{$code};
-			}
-		}
-      elsif($subcommand eq "alert") {
-         if ($returnd[3] & 0x8) { 
-            $text = "SP Alerting: enabled";
-         } else {
-            $text = "SP Alerting: disabled";
-         }
-      }
-		elsif($subcommand =~ m/^snmpdest(\d+)/ ) {
-			$text = sprintf("$format %d.%d.%d.%d",
-				"SP SNMP Destination $1:",
-				$returnd[5],
-				$returnd[6],
-				$returnd[7],
-				$returnd[8]);
-		}
-		elsif($subcommand eq "ip") {
-			$text = sprintf("$format %d.%d.%d.%d",
-				"BMC IP:",
-				$returnd[2],
-				$returnd[3],
-				$returnd[4],
-				$returnd[5]);
-		}
-		elsif($subcommand eq "netmask") {
-			$text = sprintf("$format %d.%d.%d.%d",
-				"BMC Netmask:",
-				$returnd[2],
-				$returnd[3],
-				$returnd[4],
-				$returnd[5]);
-		}
-		elsif($subcommand eq "gateway") {
-			$text = sprintf("$format %d.%d.%d.%d",
-				"BMC Gateway:",
-				$returnd[2],
-				$returnd[3],
-				$returnd[4],
-				$returnd[5]);
-		}
-		elsif($subcommand eq "backupgateway") {
-			$text = sprintf("$format %d.%d.%d.%d",
-				"BMC Backup Gateway:",
-				$returnd[2],
-				$returnd[3],
-				$returnd[4],
-				$returnd[5]);
-		}
-		elsif ($subcommand eq "community") {
-			$text = sprintf("$format ","SP SNMP Community:");
-			my $l = 2;
-			while ($returnd[$l] ne 0) {
-				$l = $l + 1;
-			}
-			my $i=2;
-			while ($i<$l) {
-				$text = $text . sprintf("%c",$returnd[$i]);
-				$i = $i + 1;
-			}
-		}
-
-		if(!$text) {
-			$rc = 1;
-			$text = sprintf("unknown response %02x",$code);
-		}
-	}
-
-	return($rc,$text);
-}
-
-sub sete325cli {
-	my $subcommand = shift;
-
-	my $netfun = 0xc8;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-
-	if($subcommand eq "disable") {
-		@cmd = (0x00);
-	}
-	elsif($subcommand eq "cli") {
-		@cmd = (0x02);
-	}
-	else {
-		return(1,"unsupported command sete325cli $subcommand");
-	}
-
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-	}
-	else {
-		if($code == 0x00) {
-			$rc = 0;
-			$text = "$subcommand";
-		}
-		else {
-			$rc = 1;
-			$text = $codes{$code};
-		}
-
-		if(!$text) {
-			$rc = 1;
-			$text = sprintf("unknown response %02x",$code);
-		}
-	}
-
-	return($rc,$text);
-}
-
-sub setboot {
-    my $subcommand=shift;
-    my $netfun = 0x00;
-    my @cmd = (0x08,0x3,0x8);
-    my @returnd = ();
-    my $error;
-    my $rc = 0;
-    my $text = "";
-    my $code;
-    my $skipset = 0;
-    my %bootchoices = (
-        0 => 'BIOS default',
-        1 => 'Network',
-        2 => 'Hard Drive',
-        5 => 'CD/DVD',
-        6 => 'BIOS Setup',
-        15 => 'Floppy'
-    );
-
-    #This disables the 60 second timer
-    $error = docmd(
-        $netfun,
-        \@cmd,
-        \@returnd
-    );
-    if ($subcommand eq "net") {
-        @cmd=(0x08,0x5,0x80,0x4,0x0,0x0,0x0);
-    }
-    elsif ($subcommand eq "hd" ) {
-        @cmd=(0x08,0x5,0x80,0x8,0x0,0x0,0x0);
-    }
-    elsif ($subcommand eq "cd" ) {
-        @cmd=(0x08,0x5,0x80,0x14,0x0,0x0,0x0);
-    }
-    elsif ($subcommand eq "floppy" ) {
-        @cmd=(0x08,0x5,0x80,0x3c,0x0,0x0,0x0);
-    }
-    elsif ($subcommand =~ m/^def/) {
-        @cmd=(0x08,0x5,0x0,0x0,0x0,0x0,0x0);
-    }
-    elsif ($subcommand eq "setup" ) { #Not supported by BMCs I've checked so far..
-        @cmd=(0x08,0x5,0x18,0x0,0x0,0x0,0x0);
-    }
-    elsif ($subcommand =~ m/^stat/) {
-        $skipset=1;
-    }
-    else {
-        return(1,"unsupported command setboot $subcommand");
-    }
-
-
-    unless ($skipset) {
-        $error = docmd(
-            $netfun,
-            \@cmd,
-            \@cmd,
-            \@returnd
-        );
-        if($error) {
-            return(1,$error);
-        }
-        $code = $returnd[0];
-        unless ($code == 0x00) {
-                    return(1,$codes{$code});
-            }
-    }
-    @cmd=(0x09,0x5,0x0,0x0);
-    $error = docmd(
-                $netfun,
-                \@cmd,
-                \@returnd
-        );
-    if($error) {
-                return(1,$error);
-        }
-    $code = $returnd[0];
-    unless ($code == 0x00) {
-                return(1,$codes{$code});
-        }
-    unless ($returnd[3] & 0x80) {
-        $text = "boot override inactive";
-        return($rc,$text);
-    }
-    my $boot=($returnd[4] & 0x3C) >> 2;
-    $text = $bootchoices{$boot};
-    return($rc,$text);
-}
-
-sub idpxthermprofile {
-    #iDataplex thermal profiles as of 6/10/2008
-    my $subcommand = lc(shift);
-    my @returnd;
-    my $netfun = 0xb8;
-    my @cmd = (0x41,0x4d,0x4f,0x00,0x6f,0xfe,0x60,0,0,0,0,0,0,0,0xff);
-    if ($idpxthermprofiles{$subcommand}) {
-        push @cmd,@{$idpxthermprofiles{$subcommand}};
-    } else {
-        return (1,"Not an understood thermal profile, expected a 2 hex digit value corresponding to chassis label on iDataplex server");
-    }
-    docmd(
-        $netfun,
-        \@cmd,
-        \@returnd
-    );
-    return (0,"OK");
-}
-
-
-sub getrvidparms {
-    my $netfun = 0x3a;
-    my @mcinfo=getdevid();
-    unless ($mcinfo[2] == 2) { #Only implemented for IBM servers
-        return(1,"Remote video is not supported on this system");
-    }
-    #TODO: use get bmc capabilities to see if rvid is actually supported before bothering the client java app
-    my @build_id;
-    my $localerror = docmd(
-        0xe8,
-        [0x50],
-        \@build_id
-    );
-    if ($localerror) {
-        return(1,$localerror);
-    }
-    unless ($build_id[1]==0x59 and $build_id[2]==0x55 and $build_id[3]==0x4f and $build_id[4]==0x4f) { #Only know how to cope with yuoo builds
-        return(1,"Remote video is not supported on this system");
-    }
-    #wvid should be a possiblity, time to do the http...
-    my $browser = LWP::UserAgent->new();
-    my $message = "$userid,$passwd";
-    $browser->cookie_jar({});
-    my $baseurl = "http://".$ipmi_bmcipaddr."/";
-    my $response = $browser->request(POST $baseurl."/session/create",'Content-Type'=>"text/xml",Content=>$message);
-    unless ($response->content eq "ok") {
-        return (1,"Server returned unexpected data");
-    }
-
-    $response = $browser->request(GET $baseurl."/kvm/kvm/jnlp");
-    my $jnlp = $response->content;
-    if ($jnlp =~ /This advanced option requires the purchase and installation/) {
-        return (1,"Node does not have feature key for remote video");
-    }
-    $jnlp =~ s!argument>title=.*Video Viewer</argument>!argument>title=$currnode wvid</argument>!;
-    my @return=("method:imm","jnlp:$jnlp");
-    if (grep /-m/,@cmdargv) {
-        $response = $browser->request(GET $baseurl."/kvm/vm/jnlp");
-        push @return,"mediajnlp:".$response->content;
-    }
-    return (0,@return);
-}
-
-
-sub power {
-	my $subcommand = shift;
-
-	my $netfun = 0x00;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-
-	if($subcommand eq "stat") {
-		@cmd = (0x01);
-	}
-	elsif($subcommand eq "on") {
-		@cmd = (0x02,0x01);
-	}
-	elsif($subcommand eq "softoff") {
-		@cmd = (0x02,0x05);
-	}
-	elsif($subcommand eq "off") {
-		@cmd = (0x02,0x00);
-	}
-	elsif($subcommand eq "reset") {
-		@cmd = (0x02,0x03);
-	}
-	elsif($subcommand eq "nmi") {
-		@cmd = (0x02,0x04);
-	}
-	else {
-		return(1,"unsupported command power $subcommand");
-	}
-
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-	}
-	else {
-		if($subcommand eq "stat") {
-			$code = $returnd[0];
-
-			if($code == 0x00) {
-				$code = $returnd[1];
-
-				if($code & 0b00000001) {
-					$text = "on";
-				}
-				else {
-					$text = "off";
-				}
-			}
-			else {
-				$rc = 1;
-				$text = $codes{$code};
-			}
-		}
-		if($subcommand eq "nmi") {
-			$code = $returnd[0];
-
-			if($code == 0x00) {
-				$text="nmi";
-			}
-			else {
-				$rc = 1;
-				$text = $codes{$code};
-			}
-		}
-		if($subcommand eq "on") {
-			$code = $returnd[0];
-
-			if($code == 0x00) {
-				$text="on";
-			}
-			else {
-				$rc = 1;
-				$text = $codes{$code};
-			}
-		}
-		if($subcommand eq "softoff") {
-			$code = $returnd[0];
-
-			if($code == 0x00) {
-				$text="softoff";
-			}
-			else {
-				$rc = 1;
-				$text = $codes{$code};
-			}
-		}
-		if($subcommand eq "off") {
-			$code = $returnd[0];
-
-			if($code == 0x00) {
-				$text="off";
-			}
-			elsif($code == 0xd5) {
-				$text="off";
-			}
-			else {
-				$rc = 1;
-				$text = $codes{$code};
-			}
-		}
-		if($subcommand eq "reset") {
-			$code = $returnd[0];
-
-			if($code == 0x00) {
-				$text="reset";
-			}
-			elsif($code == 0xd5) {
-				$text="off";
-			}
-			else {
-				$rc = 1;
-				$text = $codes{$code};
-			}
-		}
-
-		if(!$text) {
-			$rc = 1;
-			$text = sprintf("unknown response %02x",$code);
-		}
-	}
-
-	return($rc,$text);
-}
-
-sub generic {
-	my $subcommand = shift;
-	my $netfun;
-	my @args;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-
-	($netfun,@args) = split(/-/,$subcommand);
-
-	$netfun=oct($netfun);
-	printf("netfun:  0x%02x\n",$netfun);
-
-	print "command: ";
-	foreach(@args) {
-		push(@cmd,oct($_));
-		printf("0x%02x ",oct($_));
-	}
-	print "\n\n";
-
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-	}
-
-	$code = $returnd[0];
-
-	if($code == 0x00) {
-	}
-	else {
-		$rc = 1;
-		$text = $codes{$code};
-	}
-
-	printf("return code: 0x%02x\n\n",$code);
-
-	print "return data:\n";
-	my @rdata = @returnd[1..@returnd-2]; 
-	hexadump(\@rdata);
-	print "\n";
-
-	print "full output:\n";
-	hexadump(\@returnd);
-	print "\n";
-
-#	if(!$text) {
-#		$rc = 1;
-#		$text = sprintf("unknown response %02x",$code);
-#	}
-
-	return($rc,$text);
-}
-
-sub beacon {
-	my $subcommand = shift;
-
-	my $netfun = 0x00;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-	if($subcommand eq ""){
-                return(1,"please specify on or off for ipmi nodes");
-        }
-	if($subcommand eq "on") {
-        if ($ipmiv2) {
-		    @cmd = (0x04,0x0,0x01);
-        } else {
-		    @cmd = (0x04,0xFF);
-        }
-	}
-	elsif($subcommand eq "off") {
-        if ($ipmiv2) {
-            @cmd = (0x04,0x0,0x00);
-        } else {
-		    @cmd = (0x04,0x00);
-        }
-	}
-	else {
-		return(1,"unsupported command beacon $subcommand");
-	}
-
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-	}
-	else {
-		if($subcommand eq "on") {
-			$code = $returnd[0];
-
-			if($code == 0x00) {
-				$text="on";
-			}
-			else {
-				$rc = 1;
-				$text = $codes{$code};
-			}
-		}
-		if($subcommand eq "off") {
-			$code = $returnd[0];
-
-			if($code == 0x00) {
-				$text="off";
-			}
-			else {
-				$rc = 1;
-				$text = $codes{$code};
-			}
-		}
-
-		if(!$text) {
-			$rc = 1;
-			$text = sprintf("unknown response %02x",$code);
-		}
-	}
-
-	return($rc,$text);
-}
-
-sub inv {
-	my $subcommand = shift;
-
-	my $rc = 0;
-	my $text;
-	my @output;
-	my @types;
-	my $format = "%-20s %s";
-
-	($rc,$text) = initsdr(); #Look for those precious locator reconds
-	if($rc != 0) {
-		return($rc,$text);
-	}
-	($rc,$text) = initfru();
-	if($rc != 0) {
-		return($rc,$text);
-	}
-
-    unless ($subcommand) {
-        $subcommand = "all";
-    }
-	if($subcommand eq "all") {
-		@types = qw(model serial deviceid mprom guid misc hw asset);
-	}
-	elsif($subcommand eq "asset") {
-		@types = qw(asset);
-	}
-	elsif($subcommand eq "model") {
-		@types = qw(model);
-	}
-	elsif($subcommand eq "serial") {
-		@types = qw(serial);
-	}
-	elsif($subcommand eq "vpd") {
-		@types = qw(model serial deviceid mprom);
-	}
-	elsif($subcommand eq "mprom") {
-		@types = qw(mprom);
-	}
-	elsif($subcommand eq "misc") {
-		@types = qw(misc);
-	}
-	elsif($subcommand eq "deviceid") {
-		@types = qw(deviceid);
-	}
-	elsif($subcommand eq "guid") {
-		@types = qw(guid);
-	}
-	elsif($subcommand eq "uuid") {
-		@types = qw(guid);
-	}
-	else {
-        @types = ($subcommand);
-		#return(1,"unsupported BMC inv argument $subcommand");
-	}
-
-	my $otext;
-	my $key;
-
-	foreach $key (sort keys %fru_hash) {
-		my $fru = $fru_hash{$key};
-        my $type;
-        foreach $type (split /,/,$fru->rec_type) {
-    		if(grep {$_ eq $type} @types) {
-    			$otext = sprintf($format,$fru_hash{$key}->desc . ":",$fru_hash{$key}->value);
-    			#print $otext;
-    			push(@output,$otext);
-                last;
-            }
-        }
-	}
-
-	return($rc,@output);
-}
-
-sub initoemfru {
-	my $mfg_id = shift;
-	my $prod_id = shift;
-	my $device_id = shift;
-
-	my $netfun;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my @output;
-	my $code;
-
-	if($mfg_id == 2 && ($prod_id == 34869 or $prod_id == 31081 or $prod_id==34888)) {
-		$netfun = 0xc8;
-		
-		@cmd=(0x05);
-		$error = docmd(
-			$netfun,
-			\@cmd,
-			\@returnd
-		);
-
-		if($error) {
-			$rc = 1;
-			$text = $error;
-			return($rc,$text);
-		}
-
-		$code = $returnd[0];
-
-		if($code == 0x00) {
-		}
-		else {
-			$rc = 1;
-			$text = $codes{$code};
-		}
-
-		if($rc != 0) {
-			if(!$text) {
-				$text = sprintf("unknown response %02x",$code);
-			}
-			return($rc,$text);
-		}
-
-		my @oem_fru_data = @returnd[1..@returnd-2];
-		my $model_type = getascii(@oem_fru_data[0..3]);
-		my $model_number = getascii(@oem_fru_data[4..6]);
-		my $serial = getascii(@oem_fru_data[7..13]);
-		my $model = "$model_type-$model_number";
-
-		my $fru = FRU->new();
-		$fru->rec_type("serial");
-		$fru->desc("Serial Number");
-		$fru->value($serial);
-		$fru_hash{1} = $fru;
-
-		$fru = FRU->new();
-		$fru->rec_type("model");
-		$fru->desc("Model Number");
-		$fru->value($model);
-		$fru_hash{2} = $fru;
-
-		return(2,"");
-	}
-	if($mfg_id == 2 && $prod_id == 4 && 0) {
-		$netfun = 0x3a;
-		
-		@cmd=(0x0b,0x0,0x0,0x0,0x1,0x8);
-		$error = docmd(
-			$netfun,
-			\@cmd,
-			\@returnd
-		);
-
-		if($error) {
-			$rc = 1;
-			$text = $error;
-			return($rc,$text);
-		}
-
-		$code = $returnd[0];
-
-		if($code == 0x00) {
-		}
-		else {
-			$rc = 1;
-			$text = $codes{$code};
-		}
-
-		if($rc != 0) {
-			if(!$text) {
-				$text = sprintf("unknown response %02x",$code);
-			}
-			return($rc,$text);
-		}
-
-hexadump(\@returnd);
-return(2,"");
-
-		my @oem_fru_data = @returnd[1..@returnd-2];
-		my $model_type = getascii(@oem_fru_data[0..3]);
-		my $model_number = getascii(@oem_fru_data[4..6]);
-		my $serial = getascii(@oem_fru_data[7..13]);
-		my $model = "$model_type-$model_number";
-
-		my $fru = FRU->new();
-		$fru->rec_type("serial");
-		$fru->desc("Serial Number");
-		$fru->value($serial);
-		$fru_hash{1} = $fru;
-
-		$fru = FRU->new();
-		$fru->rec_type("model");
-		$fru->desc("Model Number");
-		$fru->value($model);
-		$fru_hash{2} = $fru;
-
-		return(2,"");
-	}
-	if($mfg_id == 2 && $prod_id == 20) {
-		my $serial = "unknown";
-		my $model = "x3655";
-
-		my $fru = FRU->new();
-		$fru->rec_type("serial");
-		$fru->desc("Serial Number");
-		$fru->value($serial);
-		$fru_hash{1} = $fru;
-
-		$fru = FRU->new();
-		$fru->rec_type("model");
-		$fru->desc("Model Number");
-		$fru->value($model);
-		$fru_hash{2} = $fru;
-
-		return(2,"");
-	}
-	if($mfg_id == 2 && $prod_id == 3) {
-		my $serial = "unknown";
-		my $model = "x346";
-
-		my $fru = FRU->new();
-		$fru->rec_type("serial");
-		$fru->desc("Serial Number");
-		$fru->value($serial);
-		$fru_hash{1} = $fru;
-
-		$fru = FRU->new();
-		$fru->rec_type("model");
-		$fru->desc("Model Number");
-		$fru->value($model);
-		$fru_hash{2} = $fru;
-
-		return(2,"");
-	}
-	if($mfg_id == 2 && $prod_id == 4) {
-		my $serial = "unknown";
-		my $model = "x336";
-
-		my $fru = FRU->new();
-		$fru->rec_type("serial");
-		$fru->desc("Serial Number");
-		$fru->value($serial);
-		$fru_hash{1} = $fru;
-
-		$fru = FRU->new();
-		$fru->rec_type("model");
-		$fru->desc("Model Number");
-		$fru->value($model);
-		$fru_hash{2} = $fru;
-
-		return(2,"");
-	}
-   my $serial = "unkown";
-   my $model = "unkown";
-
-   my $fru = FRU->new();
-	$fru->rec_type("serial");
-	$fru->desc("Serial Number");
-	$fru->value($serial);
-	$fru_hash{1} = $fru;
-
-	$fru = FRU->new();
-	$fru->rec_type("model");
-	$fru->desc("Model Number");
-	$fru->value($model);
-	$fru_hash{2} = $fru;
-
-	return(2,"");
-
-
-	return(1,"No OEM FRU Support");
-}
-
-sub add_textual_fru {
-    my $parsedfru = shift;
-    my $description = shift;
-    my $category = shift;
-    my $subcategory = shift;
-    my $types = shift;
-
-    if ($parsedfru->{$category} and $parsedfru->{$category}->{$subcategory}) {
-        my $fru;
-        my @subfrus;
-
-        if (ref $parsedfru->{$category}->{$subcategory} eq 'ARRAY') {
-            @subfrus = @{$parsedfru->{$category}->{$subcategory}};
-        } else {
-            @subfrus = ($parsedfru->{$category}->{$subcategory})
-        }
-        foreach (@subfrus) {
-            $fru = FRU->new();
-            $fru->rec_type($types);
-            $fru->desc($description);
-            if (not ref $_) {
-                $fru->value($_);
-            } else {
-                if ($_->{encoding} == 3) {
-                    $fru->value($_->{value});
-                } else {
-                    $fru->value(phex($_->{value}));
-                }
-                    
-            }
-            $fru_hash{$frudex++} = $fru;
-        }
-    }
-}
-sub add_textual_frus {
-    my $parsedfru = shift;
-    my $desc = shift;
-    my $categorydesc = shift;
-    my $category = shift;
-    my $type = shift;
-    unless ($type) { $type = 'hw'; }
-    add_textual_fru($parsedfru,$desc." ".$categorydesc."Part Number",$category,"partnumber","hw");
-    add_textual_fru($parsedfru,$desc." ".$categorydesc."Manufacturer",$category,"manufacturer","hw");
-    add_textual_fru($parsedfru,$desc." ".$categorydesc."Serial Number",$category,"serialnumber","hw");
-    add_textual_fru($parsedfru,$desc." ".$categorydesc."",$category,"name","hw");
-    if ($parsedfru->{$category}->{builddate}) {
-        add_textual_fru($parsedfru,$desc." ".$categorydesc."Manufacture Date",$category,"builddate","hw");
-    }
-    if ($parsedfru->{$category}->{buildlocation}) {
-        add_textual_fru($parsedfru,$desc." ".$categorydesc."Manufacture Location",$category,"buildlocation","hw");
-    }
-    if ($parsedfru->{$category}->{model})  {
-        add_textual_fru($parsedfru,$desc." ".$categorydesc."Model",$category,"model","hw");
-    }
-    add_textual_fru($parsedfru,$desc." ".$categorydesc."Additional Info",$category,"extra","hw");
-}
-
-sub initfru {
-	my $netfun = 0x28;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my @output;
-	my $code;
-
-	my $mfg_id;
-	my $prod_id;
-	my $device_id;
-	my $dev_rev;
-	my $fw_rev1;
-	my $fw_rev2;
-	my $mprom;
-	my $fru;
-	my $guid;
-	my @guidcmd;
-
-	($rc,$text,$mfg_id,$prod_id,$device_id,$dev_rev,$fw_rev1,$fw_rev2) = getdevid();
-	if($rc != 0) {
-		return($rc,$text);
-	}
-
-	@guidcmd = (0x18,0x37);
-	if($mfg_id == 2 && $prod_id == 34869) {
-		@guidcmd = (0x18,0x08);
-	}
-	if($mfg_id == 2 && $prod_id == 4) {
-		@guidcmd = (0x18,0x08);
-	}
-	if($mfg_id == 2 && $prod_id == 3) {
-		@guidcmd = (0x18,0x08);
-	}
-
-	($rc,$text,$guid) = getguid(\@guidcmd);
-	if($rc != 0) {
-		return($rc,$text);
-	}
-
-	if($mfg_id == 2 && $prod_id == 34869) {
-		$mprom = sprintf("%x.%x",$fw_rev1,$fw_rev2);
-	}
-	elsif ($mfg_id == 2) {
-		my @lcmd = (0x50);
-		my @lreturnd = ();
-		my $lerror = docmd(
-			0xe8,
-			\@lcmd,
-			\@lreturnd
-		);
-		if ($lerror eq "" && $lreturnd[0] == 0) {
-			my @a = ($fw_rev2);
-			my @b= @lreturnd[1 .. $#lreturnd-1];
-			$mprom = sprintf("%d.%s (%s)",$fw_rev1,decodebcd(\@a),getascii(@b));
-		} else {
-			my @a = ($fw_rev2);
-			$mprom = sprintf("%d.%s",$fw_rev1,decodebcd(\@a));
-		}
-	} else {
-        my @a = ($fw_rev2);
-        $mprom = sprintf("%d.%s",$fw_rev1,decodebcd(\@a));
-    }
-
-	$fru = FRU->new();
-	$fru->rec_type("mprom");
-	$fru->desc("BMC Firmware");
-	$fru->value($mprom);
-	$fru_hash{mprom} = $fru;
-
-	$fru = FRU->new();
-	$fru->rec_type("guid");
-	$fru->desc("GUID");
-	$fru->value($guid);
-	$fru_hash{guid} = $fru;
-
-	$fru = FRU->new();
-	$fru->rec_type("deviceid");
-	$fru->desc("Manufacturer ID");
-	my $value = $mfg_id;
-	if($MFG_ID{$mfg_id}) {
-		$value = "$MFG_ID{$mfg_id} ($mfg_id)";
-	}
-	$fru->value($value);
-	$fru_hash{mfg_id} = $fru;
-
-	$fru = FRU->new();
-	$fru->rec_type("deviceid");
-	$fru->desc("Product ID");
-	$value = $prod_id;
-	my $tmp = "$mfg_id:$prod_id";
-	if($PROD_ID{$tmp}) {
-		$value = "$PROD_ID{$tmp} ($prod_id)";
-	}
-	$fru->value($value);
-	$fru_hash{prod_id} = $fru;
-
-	$fru = FRU->new();
-	$fru->rec_type("deviceid");
-	$fru->desc("Device ID");
-	$fru->value($device_id);
-	$fru_hash{device_id} = $fru;
-
-#	($rc,$text)=initoemfru($mfg_id,$prod_id,$device_id);
-#	if($rc == 1) {
-#		return($rc,$text);
-#	}
-#	if($rc == 2) {
-#		return(0,"");
-#	}
-    $netfun = 0x28; # Storage (0x0A << 2)
-	my @bytes;
-	@cmd=(0x10,0x00);
-    $error = docmd($netfun,\@cmd,\@bytes);
-    if ($error) { return (1,$error); }
-    pop @bytes;
-    unless (defined $bytes[0] and $bytes[0] == 0) {
-        if ($codes{$bytes[0]}) {
-            return (1,"FRU device 0 inaccessible".$codes{$bytes[0]});
-        } else {
-            return (1,"FRU device 0 inaccessible");
-        }
-    }
-    my $frusize=($bytes[2]<<8)+$bytes[1];
-
-	($rc,@bytes) = frudump(0,$frusize,16);
-	if($rc != 0) {
-		return($rc,@bytes);
-	}
-    my $fruhash;
-    ($error,$fruhash) = parsefru(\@bytes);
-    if ($error) {
-		($rc,$text)=initoemfru($mfg_id,$prod_id,$device_id);
-		if($rc == 1) {
-			$text = "FRU format unknown";
-			return($rc,$text);
-		}
-		if($rc == 2) {
-			return(0,"");
-		}
-	}
-    $frudex=0;
-    if (defined $fruhash->{product}->{manufacturer}->{value}) {
-	    $fru = FRU->new();
-    	$fru->rec_type("misc");
-    	$fru->desc("System Manufacturer");
-        if ($fruhash->{product}->{product}->{encoding}==3) {
-        	$fru->value($fruhash->{product}->{manufacturer}->{value});
-        } else {
-        	$fru->value(phex($fruhash->{product}->{manufacturer}->{value}));
-        }
-    	$fru_hash{$frudex++} = $fru;
-    }
-    if (defined $fruhash->{product}->{product}->{value}) {
-	    $fru = FRU->new();
-    	$fru->rec_type("model");
-    	$fru->desc("System Description");
-        if ($fruhash->{product}->{product}->{encoding}==3) {
-        	$fru->value($fruhash->{product}->{product}->{value});
-        } else {
-        	$fru->value(phex($fruhash->{product}->{product}->{value}));
-        }
-    	$fru_hash{$frudex++} = $fru;
-    }
-    if (defined $fruhash->{product}->{model}->{value}) {
-	    $fru = FRU->new();
-    	$fru->rec_type("model");
-    	$fru->desc("System Model/MTM");
-        if ($fruhash->{product}->{model}->{encoding}==3) {
-        	$fru->value($fruhash->{product}->{model}->{value});
-        } else {
-        	$fru->value(phex($fruhash->{product}->{model}->{value}));
-        }
-    	$fru_hash{$frudex++} = $fru;
-    }
-    if (defined $fruhash->{product}->{version}->{value}) {
-	    $fru = FRU->new();
-    	$fru->rec_type("misc");
-    	$fru->desc("System Revision");
-        if ($fruhash->{product}->{version}->{encoding}==3) {
-        	$fru->value($fruhash->{product}->{version}->{value});
-        } else {
-        	$fru->value(phex($fruhash->{product}->{version}->{value}));
-        }
-    	$fru_hash{$frudex++} = $fru;
-    }
-    if (defined $fruhash->{product}->{serialnumber}->{value}) {
-	    $fru = FRU->new();
-    	$fru->rec_type("serial");
-    	$fru->desc("System Serial Number");
-        if ($fruhash->{product}->{serialnumber}->{encoding}==3) {
-        	$fru->value($fruhash->{product}->{serialnumber}->{value});
-        } else {
-        	$fru->value(phex($fruhash->{product}->{serialnumber}->{value}));
-        }
-    	$fru_hash{$frudex++} = $fru;
-    }
-    if (defined $fruhash->{product}->{asset}->{value}) {
-	    $fru = FRU->new();
-    	$fru->rec_type("asset");
-    	$fru->desc("System Asset Number");
-        if ($fruhash->{product}->{asset}->{encoding}==3) {
-        	$fru->value($fruhash->{product}->{asset}->{value});
-        } else {
-        	$fru->value(phex($fruhash->{product}->{asset}->{value}));
-        }
-    	$fru_hash{$frudex++} = $fru;
-    }
-    foreach (@{$fruhash->{product}->{extra}}) {
-        $fru = FRU->new();
-        $fru->rec_type("misc");
-        $fru->desc("Product Extra data");
-        if ($_->{encoding} == 3) {
-            $fru->value($_->{value});
-        } else {
-            #print Dumper($_);
-            #print $_->{encoding};
-            next;
-            $fru->value(phex($_->{value}));
-        }
-        $fru_hash{$frudex++} = $fru;
-    }
-    
-
-    if ($fruhash->{chassis}->{serialnumber}->{value}) {
-	    $fru = FRU->new();
-    	$fru->rec_type("serial");
-    	$fru->desc("Chassis Serial Number");
-        if ($fruhash->{chassis}->{serialnumber}->{encoding}==3) {
-        	$fru->value($fruhash->{chassis}->{serialnumber}->{value});
-        } else {
-        	$fru->value(phex($fruhash->{chassis}->{serialnumber}->{value}));
-        }
-    	$fru_hash{$frudex++} = $fru;
-    }
-
-    if ($fruhash->{chassis}->{partnumber}->{value}) {
-	    $fru = FRU->new();
-    	$fru->rec_type("model");
-    	$fru->desc("Chassis Part Number");
-        if ($fruhash->{chassis}->{partnumber}->{encoding}==3) {
-        	$fru->value($fruhash->{chassis}->{partnumber}->{value});
-        } else {
-        	$fru->value(phex($fruhash->{chassis}->{partnumber}->{value}));
-        }
-    	$fru_hash{$frudex++} = $fru;
-    }
-
-
-    foreach (@{$fruhash->{chassis}->{extra}}) {
-        $fru = FRU->new();
-        $fru->rec_type("misc");
-        $fru->desc("Chassis Extra data");
-        if ($_->{encoding} == 3) {
-            $fru->value($_->{value});
-        } else {
-            next;
-            #print Dumper($_);
-            #print $_->{encoding};
-            $fru->value(phex($_->{value}));
-        }
-        $fru_hash{$frudex++} = $fru;
-    }
-
-    if ($fruhash->{board}->{builddate})  {
-        $fru = FRU->new();
-        $fru->rec_type("misc");
-        $fru->desc("Board manufacture date");
-        $fru->value($fruhash->{board}->{builddate});
-        $fru_hash{$frudex++} = $fru;
-    }
-
-    if ($fruhash->{board}->{manufacturer}->{value}) {
-	    $fru = FRU->new();
-    	$fru->rec_type("misc");
-    	$fru->desc("Board manufacturer");
-        if ($fruhash->{board}->{manufacturer}->{encoding}==3) {
-        	$fru->value($fruhash->{board}->{manufacturer}->{value});
-        } else {
-        	$fru->value(phex($fruhash->{board}->{manufacturer}->{value}));
-        }
-    	$fru_hash{$frudex++} = $fru;
-    }
-    if ($fruhash->{board}->{name}->{value}) {
-	    $fru = FRU->new();
-    	$fru->rec_type("misc");
-    	$fru->desc("Board Description");
-        if ($fruhash->{board}->{name}->{encoding}==3) {
-        	$fru->value($fruhash->{board}->{name}->{value});
-        } else {
-        	$fru->value(phex($fruhash->{board}->{name}->{value}));
-        }
-    	$fru_hash{$frudex++} = $fru;
-    }
-    if ($fruhash->{board}->{serialnumber}->{value}) {
-	    $fru = FRU->new();
-    	$fru->rec_type("misc");
-    	$fru->desc("Board Serial Number");
-        if ($fruhash->{board}->{serialnumber}->{encoding}==3) {
-        	$fru->value($fruhash->{board}->{serialnumber}->{value});
-        } else {
-        	$fru->value(phex($fruhash->{board}->{serialnumber}->{value}));
-        }
-    	$fru_hash{$frudex++} = $fru;
-    }
-    if ($fruhash->{board}->{partnumber}->{value}) {
-	    $fru = FRU->new();
-    	$fru->rec_type("misc");
-    	$fru->desc("Board Model Number");
-        if ($fruhash->{board}->{partnumber}->{encoding}==3) {
-        	$fru->value($fruhash->{board}->{partnumber}->{value});
-        } else {
-        	$fru->value(phex($fruhash->{board}->{partnumber}->{value}));
-        }
-    	$fru_hash{$frudex++} = $fru;
-    }
-    foreach (@{$fruhash->{board}->{extra}}) {
-        $fru = FRU->new();
-        $fru->rec_type("misc");
-        $fru->desc("Board Extra data");
-        if ($_->{encoding} == 3) {
-            $fru->value($_->{value});
-        } else {
-            next;
-            #print Dumper($_);
-            #print $_->{encoding};
-            $fru->value(phex($_->{value}));
-        }
-        $fru_hash{$frudex++} = $fru;
-    }
-    #Ok, done with fru 0, on to the other fru devices from SDR
-    my $key;
-    my $subrc;
-    foreach $key (sort {$sdr_hash{$a}->id_string cmp $sdr_hash{$b}->id_string} keys %sdr_hash) {
-        my $sdr = $sdr_hash{$key};
-        unless ($sdr->rec_type == 0x11 and $sdr->fru_type == 0x10) { #skip non fru sdr stuff and frus I don't understand
-            next;
-        }
-        
-        if ($sdr->fru_type == 0x10) { #supported
-            if ($sdr->fru_subtype == 0x1) { #DIMM
-                $fru = FRU->new();
-                $fru->rec_type("hw,dimm");
-                $fru->desc($sdr->id_string);
-	            ($subrc,@bytes) = frudump(0,get_frusize($sdr->sensor_number),16,$sdr->sensor_number);
-                if ($subrc) {
-                    print $sdr->id_string.":".$bytes[0]."\n";
-                    $fru->value($bytes[0]);
-                    $fru_hash{$frudex++} = $fru;
-                    next;
-                }
-                my $parsedfru = decode_spd(@bytes);
-                add_textual_frus($parsedfru,$sdr->id_string,"",'product','dimm,hw');
-            } elsif ($sdr->fru_subtype == 0 or $sdr->fru_subtype == 2) {
-	            ($subrc,@bytes) = frudump(0,get_frusize($sdr->sensor_number),16,$sdr->sensor_number);
-                if ($subrc) {
-                    $fru = FRU->new();
-                    $fru->value($bytes[0]);
-                    $fru->rec_type("hw");
-                    $fru->desc($sdr->id_string);
-                    $fru_hash{$frudex++} = $fru;
-                    next;
-                }
-                my $parsedfru=parsefru(\@bytes);
-                add_textual_frus($parsedfru,$sdr->id_string,"Board ",'board');
-                add_textual_frus($parsedfru,$sdr->id_string,"Product ",'product');
-                add_textual_frus($parsedfru,$sdr->id_string,"Chassis ",'chassis');
-            }
-        }
-    }
-
-
-
-	return($rc,$text);
-}
-sub get_frusize {
-    my $fruid=shift;
-    my $netfun = 0x28; # Storage (0x0A << 2)
-    my @cmd=(0x10,$fruid);
-	my @bytes;
-    my $error = docmd($netfun,\@cmd,\@bytes);
-    pop @bytes;
-    unless (defined $bytes[0] and $bytes[0] == 0) {
-        if ($codes{$bytes[0]}) {
-            return (0,$codes{$bytes[0]});
-        }
-        return (0,"FRU device $fruid inaccessible");
-    }
-    return ($bytes[2]<<8)+$bytes[1];
-}
-
-sub formfru {
-    my $fruhash = shift;
-    my $frusize = shift;
-    $frusize-=8; #consume 8 bytes for mandatory header
-    my $availindex=1;
-    my @bytes=(1,0,0,0,0,0,0,0); #
-    if ($fruhash->{internal}) { #Allocate the space at header time
-        $bytes[1]=$availindex;
-        $availindex+=ceil((scalar @{$fruhash->{internal}})/8);
-        $frusize-=(scalar @{$fruhash->{internal}}); #consume internal bytes
-        push @bytes,@{$fruhash->{internal}};
-    } 
-    if ($fruhash->{chassis}) {
-        $bytes[2]=$availindex;
-        push @bytes,@{$fruhash->{chassis}->{raw}};
-        $availindex+=ceil((scalar @{$fruhash->{chassis}->{raw}})/8);
-        $frusize -= ceil((scalar @{$fruhash->{chassis}->{raw}})/8)*8;
-    }
-    if ($fruhash->{board}) {
-        $bytes[3]=$availindex;
-        push @bytes,@{$fruhash->{board}->{raw}};
-        $availindex+=ceil((scalar @{$fruhash->{board}->{raw}})/8);
-        $frusize -= ceil((scalar @{$fruhash->{board}->{raw}})/8)*8;
-    }
-    #xCAT will always have a product FRU in this process
-    $bytes[4]=$availindex;
-    unless (defined $fruhash->{product}) { #Make sure there is a data structure
-                        #to latch onto..
-        $fruhash->{product}={};
-    }
-    my @prodbytes = buildprodfru($fruhash->{product});
-    push @bytes,@prodbytes;
-    $availindex+=ceil((scalar @prodbytes)/8);
-    $frusize -= ceil((scalar @prodbytes)/8)*8;;
-    #End of product fru setup
-    if ($fruhash->{extra}) {
-        $bytes[5]=$availindex;
-        push @bytes,@{$fruhash->{extra}};
-        $frusize -= ceil((scalar @{$fruhash->{extra}})/8)*8;
-        #Don't need to track availindex anymore
-    }
-    $bytes[7] = dochksum([@bytes[0..6]]);
-    if ($frusize<0) {
-        return undef;
-    } else {
-        return \@bytes;
-    }
-}
-
-sub transfieldtobytes {
-    my $hashref=shift;
-    unless (defined $hashref) {
-        return (0xC0);
-    }
-    my @data;
-    my $size;
-    if ($hashref->{encoding} ==3) {
-        @data=unpack("C*",$hashref->{value});
-    } else {
-        @data=@{$hashref->{value}};
-    }
-    $size=scalar(@data);
-    if ($size > 64) {
-        die "Field too large for IPMI FRU specification";
-    }
-    unshift(@data,$size|($hashref->{encoding}<<6));
-    return @data;
-}
-sub mergefru {
-    my $phash = shift; #Product hash
-    if ($vpdhash->{$currnode}->[0]->{mtm}) {
-        $phash->{model}->{encoding}=3;
-        $phash->{model}->{value}=$vpdhash->{$currnode}->[0]->{mtm};
-    }
-    if ($vpdhash->{$currnode}->[0]->{serial}) {
-        $phash->{serialnumber}->{encoding}=3;
-        $phash->{serialnumber}->{value}=$vpdhash->{$currnode}->[0]->{serial};
-    }
-    if ($vpdhash->{$currnode}->[0]->{asset}) {
-        $phash->{asset}->{encoding}=3;
-        $phash->{asset}->{value}=$vpdhash->{$currnode}->[0]->{asset};
-    }
-}
-
-sub buildprodfru {
-    my $prod=shift;
-    mergefru($prod);
-    my @bytes=(1,0,0);
-    my @data;
-    my $padsize;
-    push @bytes,transfieldtobytes($prod->{manufacturer});
-    push @bytes,transfieldtobytes($prod->{product});
-    push @bytes,transfieldtobytes($prod->{model});
-    push @bytes,transfieldtobytes($prod->{version});
-    push @bytes,transfieldtobytes($prod->{serialnumber});
-    push @bytes,transfieldtobytes($prod->{asset});
-    push @bytes,transfieldtobytes($prod->{fruid});
-    push @bytes,transfieldtobytes($prod->{fruid});
-    foreach (@{$prod->{extra}}) {
-        my $sig=getascii(transfieldtobytes($_));
-        unless ($sig and $sig =~ /FRU by xCAT/) {
-            push @bytes,transfieldtobytes($_);
-        }
-    }
-    push @bytes,transfieldtobytes({encoding=>3,value=>"$currnode FRU by xCAT ".xCAT::Utils::Version('short')});
-    push @bytes,(0xc1);
-    $bytes[1]=ceil((scalar(@bytes)+1)/8);
-    $padsize=(ceil((scalar(@bytes)+1)/8)*8)-scalar(@bytes)-1;
-    while ($padsize--) {
-        push @bytes,(0x00);
-    }
-    $padsize=dochksum(\@bytes);#reuse padsize for a second to store checksum
-    push @bytes,$padsize;
-
-    return @bytes;
-}
-
-sub fru {
-	my $subcommand = shift;
-	my $netfun = 0x28;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my @output;
-	my $code;
-
-	@cmd=(0x10,0x00);
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-		return($rc,$text);
-	}
-
-	$code = $returnd[0];
-
-	if($code == 0x00) {
-	}
-	else {
-		$rc = 1;
-		$text = $codes{$code};
-	}
-
-	if($rc != 0) {
-		if(!$text) {
-			$text = sprintf("unknown response %02x",$code);
-		}
-		return($rc,$text);
-	}
-
-	my $fru_size_ls = $returnd[1];
-	my $fru_size_ms = $returnd[2];
-	my $fru_size = $fru_size_ms*256 + $fru_size_ls;
-
-	if($subcommand eq "dump") {
-		print "FRU Size: $fru_size\n";
-		my ($rc,@output) = frudump(0,$fru_size,8);
-		if($rc) {
-			return($rc,@output);
-		}
-		hexadump(\@output);
-		return(0,"");
-	}
-	if($subcommand eq "wipe") {
-		my @bytes = ();
-
-		for(my $i = 0;$i < $fru_size;$i++) {
-			push(@bytes,0xff);
-		}
-		my ($rc,$text) = fruwrite(0,\@bytes,8);
-		if($rc) {
-			return($rc,$text);
-		}
-		return(0,"FRU $fru_size bytes wiped");
-	}
-
-	return(0,"");
-}
-
-sub frudump {
-	my $offset = shift;
-	my $length = shift;
-	my $chunk = shift;
-    my $fruid = shift;
-    unless (defined $fruid) { $fruid = 0; }
-    unless ($length) { return (1,$chunk); } #chunk happens to get the error text
-
-	my $netfun = 0x28;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my @output;
-	my $code;
-	my @fru_data=();
-
-	for(my $c=$offset;$c < $length+$offset;$c += $chunk) {
-		my $ms = int($c / 0x100);
-		my $ls = $c - $ms * 0x100;
-        my $reqsize = $chunk;
-        if ($c+$chunk > $length+$offset) {
-            $reqsize = ($length+$offset-$c);
-        }
-
-		@cmd=(0x11,$fruid,$ls,$ms,$reqsize);
-		$error = docmd(
-			$netfun,
-			\@cmd,
-			\@returnd
-		);
-
-		if($error) {
-			$rc = 1;
-			$text = $error;
-			return($rc,$text);
-		}
-
-		$code = $returnd[0];
-
-		if($code == 0x00) {
-		}
-		else {
-			$rc = 1;
-			$text = $codes{$code};
-		}
-
-		if($rc != 0) {
-			if(!$text) {
-				$text = sprintf("unknown response %02x",$code);
-			}
-			return($rc,$text);
-		}
-
-		my $count = $returnd[1];
-		if($count != $reqsize) {
-			$rc = 1;
-			$text = "FRU read error (bytes requested: $reqsize, got: $count)";
-			return($rc,$text);
-		}
-
-		my @data = @returnd[2..@returnd-2];
-		@fru_data = (@fru_data,@data);
-	}
-
-	return(0,@fru_data);
-}
-
-sub parsefru {
-    my $bytes = shift;
-    my $fruhash;
-    my $curridx; #store indexes as needed for convenience
-    my $currsize; #store current size
-    my $subidx;
-    my @currarea;
-    unless ($bytes->[0]==1) {
-        if ($bytes->[0]==0 or $bytes->[0]==0xff) { #not in spec, but probably unitialized, xCAT probably will rewrite fresh
-            return "clear",undef;
-        } else { #some meaning suggested, but not parsable, xCAT shouldn't meddle
-            return "unknown",undef;
-        }
-    }
-    if ($bytes->[1]) { #The FRU spec, unfortunately, gave no easy way to tell the size of internal area
-        #consequently, will find the next defined field and preserve the addressing and size of current FRU 
-        #area until then
-        my $internal_size;
-        if ($bytes->[2]) {
-            $internal_size=$bytes->[2]*8-($bytes->[1]*8);
-        } elsif ($bytes->[3]) {
-            $internal_size=$bytes->[3]*8-($bytes->[1]*8);
-        } elsif ($bytes->[4]) {
-            $internal_size=$bytes->[4]*8-($bytes->[1]*8);
-        } elsif ($bytes->[5]) {
-            $internal_size=$bytes->[5]*8-($bytes->[1]*8);
-        } else { #The FRU area is intact enough to signify xCAT can't safely manipulate contents
-            return "unknown-winternal",undef;
-        }
-        #capture slice of bytes
-        $fruhash->{internal}=[@{$bytes}[($bytes->[1]*8)..($bytes->[1]*8+$internal_size-1)]]; #,$bytes->[1]*8,$internal_size];
-    }
-    if ($bytes->[2]) { #Chassis info area, xCAT will preserve fields, not manipulate them
-        $curridx=$bytes->[2]*8;
-        unless ($bytes->[$curridx]==1) { #definitely unparsable, but the section is preservable
-            return "unknown-COULDGUESS",undef; #be lazy for now, TODO revisit this and add guessing if it ever matters
-        }
-        $currsize=($bytes->[$curridx+1])*8;
-        @currarea=@{$bytes}[$curridx..($curridx+$currsize-1)]; #splice @$bytes,$curridx,$currsize;
-        $fruhash->{chassis} = parsechassis(@currarea);
-    }
-    if ($bytes->[3]) { #Board info area, to be preserved
-        $curridx=$bytes->[3]*8;
-        unless ($bytes->[$curridx]==1) {
-            return "unknown-COULDGUESS",undef;
-        }
-        $currsize=($bytes->[$curridx+1])*8;
-        @currarea=@{$bytes}[$curridx..($curridx+$currsize-1)];
-        $fruhash->{board} = parseboard(@currarea);
-    }
-    if ($bytes->[4]) { #Product info area present, will probably be thoroughly modified
-        $curridx=$bytes->[4]*8;
-        unless ($bytes->[$curridx]==1) {
-            return "unknown-COULDGUESS",undef;
-        }
-        $currsize=($bytes->[$curridx+1])*8;
-        @currarea=@{$bytes}[$curridx..($curridx+$currsize-1)];
-        $fruhash->{product} = parseprod(@currarea);
-    }
-    if ($bytes->[5]) { #Generic multirecord present..
-        $fruhash->{extra}=[];
-        my $last=0;
-        $curridx=$bytes->[5]*8;
-        my $currsize;
-        while (not $last) {
-            if ($bytes->[$curridx+1] & 128) {
-                $last=1;
-            }
-            $currsize=$bytes->[$curridx+2];
-            push @{$fruhash->{extra}},$bytes->[$curridx..$curridx+4+$currsize-1];
-        }
-    }
-    return 0,$fruhash;
-}
-
-sub parseprod {
-    my @area = @_;
-    my %info;
-    my $language=$area[2];
-    my $idx=3;
-    my $currsize;
-    my $currdata;
-    my $encode;
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    unless ($currsize) {
-        return \%info;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $info{manufacturer}->{encoding}=$encode;
-        $info{manufacturer}->{value}=$currdata;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    unless ($currsize) {
-        return \%info;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $info{product}->{encoding}=$encode;
-        $info{product}->{value}=$currdata;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    unless ($currsize) {
-        return \%info;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $info{model}->{encoding}=$encode;
-        $info{model}->{value}=$currdata;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    unless ($currsize) {
-        return \%info;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $info{version}->{encoding}=$encode;
-        $info{version}->{value}=$currdata;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    unless ($currsize) {
-        return \%info;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $info{serialnumber}->{encoding}=$encode;
-        $info{serialnumber}->{value}=$currdata;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    unless ($currsize) {
-        return \%info;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $info{asset}->{encoding}=$encode;
-        $info{asset}->{value}=$currdata;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    unless ($currsize) {
-        return \%info;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $info{fruid}->{encoding}=$encode;
-        $info{fruid}->{value}=$currdata;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    if ($currsize) {
-        $info{extra}=[];
-    }
-    while ($currsize>0) {
-        if ($currsize>1) {
-            push @{$info{extra}},{value=>$currdata,encoding=>$encode};
-        }
-        $idx+=$currsize;
-        ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    }
-    return \%info;
-
-}
-sub parseboard {
-    my @area = @_;
-    my %boardinf;
-    my $idx=6;
-    my $language=$area[2];
-    my $tstamp = ($area[3]+($area[4]<<8)+($area[5]<<16))*60+820472400; #820472400 is meant to be 1/1/1996
-    $boardinf{raw}=[@area]; #store for verbatim replacement
-    unless ($tstamp == 820472400) {
-        $boardinf{builddate}=scalar localtime($tstamp);
-    }
-    my $encode;
-    my $currsize;
-    my $currdata;
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    unless ($currsize) {
-        return \%boardinf;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $boardinf{manufacturer}->{encoding}=$encode;
-        $boardinf{manufacturer}->{value}=$currdata;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    unless ($currsize) {
-        return \%boardinf;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $boardinf{name}->{encoding}=$encode;
-        $boardinf{name}->{value}=$currdata;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    unless ($currsize) {
-        return \%boardinf;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $boardinf{serialnumber}->{encoding}=$encode;
-        $boardinf{serialnumber}->{value}=$currdata;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    unless ($currsize) {
-        return \%boardinf;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $boardinf{partnumber}->{encoding}=$encode;
-        $boardinf{partnumber}->{value}=$currdata;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    unless ($currsize) {
-        return \%boardinf;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $boardinf{fruid}->{encoding}=$encode;
-        $boardinf{fruid}->{value}=$currdata;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    if ($currsize) {
-        $boardinf{extra}=[];
-    }
-    while ($currsize>0) {
-        if ($currsize>1) {
-            push @{$boardinf{extra}},{value=>$currdata,encoding=>$encode};
-        }
-        $idx+=$currsize;
-        ($currsize,$currdata,$encode)=extractfield(\@area,$idx);
-    }
-    return \%boardinf;
-}
-sub parsechassis {
-    my @chassarea=@_;
-    my %chassisinf;
-    my $currsize;
-    my $currdata;
-    my $idx=3;
-    my $encode;
-    $chassisinf{raw}=[@chassarea]; #store for verbatim replacement
-    $chassisinf{type}="unknown";
-    if ($chassis_types{$chassarea[2]}) {
-        $chassisinf{type}=$chassis_types{$chassarea[2]};
-    }
-    if ($chassarea[$idx] == 0xc1) {
-        return \%chassisinf;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@chassarea,$idx);
-    unless ($currsize) {
-        return \%chassisinf;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $chassisinf{partnumber}->{encoding}=$encode;
-        $chassisinf{partnumber}->{value}=$currdata;
-    } 
-    ($currsize,$currdata,$encode)=extractfield(\@chassarea,$idx);
-    unless ($currsize) {
-        return \%chassisinf;
-    }
-    $idx+=$currsize;
-    if ($currsize>1) {
-        $chassisinf{serialnumber}->{encoding}=$encode;
-        $chassisinf{serialnumber}->{value}=$currdata;
-    }
-    ($currsize,$currdata,$encode)=extractfield(\@chassarea,$idx);
-    if ($currsize) {
-        $chassisinf{extra}=[];
-    }
-    while ($currsize>0) {
-        if ($currsize>1) {
-            push @{$chassisinf{extra}},{value=>$currdata,encoding=>$encode};
-        }
-        $idx+=$currsize;
-        ($currsize,$currdata,$encode)=extractfield(\@chassarea,$idx);
-    }
-    return \%chassisinf;
-}
-
-sub extractfield { #idx is location of the type/length byte, returns something appropriate
-    my $area = shift;
-    my $idx = shift;
-    my $language=shift;
-    my $data;
-    my $size = $area->[$idx] & 0b00111111;
-    my $encoding = ($area->[$idx] & 0b11000000)>>6;
-    unless ($size) {
-        return 1,undef,undef;
-    }
-    if ($size==1 && $encoding==3) { 
-        return 0,'','';
-    }
-    if ($encoding==3) {
-        $data=getascii(@$area[$idx+1..$size+$idx]);
-    } else {
-        $data = [@$area[$idx+1..$size+$idx]];
-    }
-    return $size+1,$data,$encoding;
-}
-
-
-
-
-
-
-sub writefru {
-    my $netfun = 0x28; # Storage (0x0A << 2)
-    my @cmd=(0x10,0);
-	my @bytes;
-    my $error = docmd($netfun,\@cmd,\@bytes);
-    pop @bytes;
-    unless (defined $bytes[0] and $bytes[0] == 0) {
-        return (1,"FRU device 0 inaccessible");
-    }
-    my $frusize=($bytes[2]<<8)+$bytes[1];
-    ($error,@bytes) = frudump(0,$frusize,16);
-    if ($error) {
-        return (1,"Error retrieving FRU: ".$error);
-    }
-    my $fruhash; 
-    ($error,$fruhash) = parsefru(\@bytes);
-    my $newfru=formfru($fruhash,$frusize);
-    unless ($newfru) {
-        return (1,"FRU data will not fit in BMC FRU space, fields too long");
-    }
-    my $rc=1;
-    my $writeattempts=0;
-    my $text;
-    while ($rc and $writeattempts<15) {
-        if ($writeattempts) {
-            sleep 1;
-        }
-    	($rc,$text) = fruwrite(0,$newfru,8);
-        if ($text =~ /rotected/) {
-            last;
-        }
-        $writeattempts++;
-    }
-	if($rc) {
-		return($rc,$text);
-	}
-	return(0,"FRU Updated");
-}
-
-sub fruwrite {
-	my $offset = shift;
-	my $bytes = shift;
-	my $chunk = shift;
-	my $length = @$bytes;
-
-	my $netfun = 0x28;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my @output;
-	my $code;
-	my @fru_data=();
-
-	for(my $c=$offset;$c < $length+$offset;$c += $chunk) {
-		my $ms = int($c / 0x100);
-		my $ls = $c - $ms * 0x100;
-
-		@cmd=(0x12,0x00,$ls,$ms,@$bytes[$c-$offset..$c-$offset+$chunk-1]);
-		$error = docmd(
-			$netfun,
-			\@cmd,
-			\@returnd
-		);
-
-		if($error) {
-			$rc = 1;
-			$text = $error;
-			return($rc,$text);
-		}
-
-		$code = $returnd[0];
-
-		if($code == 0x00) {
-		}
-		else {
-			$rc = 1;
-			$text = $codes{$code};
-		}
-
-		if($rc != 0) {
-            if ($code == 0x80) {
-                $text = "Write protected FRU";
-            }
-			if(!$text) {
-				$text = sprintf("unknown response %02x",$code);
-			}
-			return($rc,$text);
-		}
-
-		my $count = $returnd[1];
-		if($count != $chunk) {
-			$rc = 1;
-			$text = "FRU write error (bytes requested: $chunk, wrote: $count)";
-			return($rc,$text);
-		}
-	}
-
-	return(0);
-}
-
-sub decodealert {
-  my $trap = shift;
-  my $skip_sdrinit=0;
-  if ($trap =~ /xCAT_plugin::ipmi/) {
-    $trap=shift;
-    $skip_sdrinit=1;
-  }
-	my $node = shift;
-	my @pet = @_;
-	my $rc;
-	my $text;
-    
-    if (!$skip_sdrinit) { 
-	($rc,$text) = initsdr();
-	if($rc != 0) {
-		return($rc,$text);
-	}
-    }
-
-	my $type;
-	my $desc;
-	#my $ipmisensoreventtab = "$ENV{XCATROOT}/lib/GUMI/ipmisensorevent.tab";
-	#my $ipmigenericeventtab = "$ENV{XCATROOT}/lib/GUMI/ipmigenericevent.tab";
-
-	my $offsetmask     = 0b00000000000000000000000000001111;
-	my $offsetrmask    = 0b00000000000000000000000001110000;
-	my $assertionmask  = 0b00000000000000000000000010000000;
-	my $eventtypemask  = 0b00000000000000001111111100000000;
-	my $sensortypemask = 0b00000000111111110000000000000000;
-	my $reservedmask   = 0b11111111000000000000000000000000;
-
-	my $offset      = $trap & $offsetmask;
-	my $offsetr     = $trap & $offsetrmask;
-	my $event_dir   = $trap & $assertionmask;
-	my $event_type  = ($trap & $eventtypemask) >> 8;
-	my $sensor_type = ($trap & $sensortypemask) >> 16;
-	my $reserved    = ($trap & $reservedmask) >> 24;
-
-	if($debug >= 2) {
-		printf("offset:     %02xh\n",$offset);
-		printf("offsetr:    %02xh\n",$offsetr);
-		printf("assertion:  %02xh\n",$event_dir);
-		printf("eventtype:  %02xh\n",$event_type);
-		printf("sensortype: %02xh\n",$sensor_type);
-		printf("reserved:   %02xh\n",$reserved);
-	}
-
-	my @hex = (0,@pet);
-	my $pad = $hex[0];
-	my @uuid = @hex[1..16];
-	my @seqnum = @hex[17,18];
-	my @timestamp = @hex[19,20,21,22];
-	my @utcoffset = @hex[23,24];
-	my $trap_source_type = $hex[25];
-	my $event_source_type = $hex[26];
-	my $sev = $hex[27];
-	my $sensor_device = $hex[28];
-	my $sensor_num = $hex[29];
-	my $entity_id = $hex[30];
-	my $entity_instance = $hex[31];
-	my $event_data_1 = $hex[32];
-	my $event_data_2 = $hex[33];
-	my $event_data_3 = $hex[34];
-	my @event_data = @hex[35..39];
-	my $langcode = $hex[40];
-	my $mfg_id = $hex[41] + $hex[42] * 0x100 + $hex[43] * 0x10000 + $hex[44] * 0x1000000;
-	my $prod_id = $hex[45] + $hex[46] * 0x100;
-	my @oem = $hex[47..@hex-1];
-
-	if($sev == 0x00) {
-		$sev = "LOG";
-	}
-	elsif($sev == 0x01) {
-		$sev = "MONITOR";
-	}
-	elsif($sev == 0x02) {
-		$sev = "INFORMATION";
-	}
-	elsif($sev == 0x04) {
-		$sev = "OK";
-	}
-	elsif($sev == 0x08) {
-		$sev = "WARNING";
-	}
-	elsif($sev == 0x10) {
-		$sev = "CRITICAL";
-	}
-	elsif($sev == 0x20) {
-		$sev = "NON-RECOVERABLE";
-	}
-	else {
-		$sev = "UNKNOWN-SEVERITY:$sev";
-	}
-	$text = "$sev:";
-
-	($rc,$type,$desc) = getsensorevent($sensor_type,$offset,"ipmisensorevents");
-	if($rc == 1) {
-		$type = "Unknown Type $sensor_type";
-		$desc = "Unknown Event $offset";
-		$rc = 0;
-	}
-
-	if($event_type <= 0x0c) {
-		my $gtype;
-		my $gdesc;
-		($rc,$gtype,$gdesc) = getsensorevent($event_type,$offset,"ipmigenericevents");
-		if($rc == 1) {
-			$gtype = "Unknown Type $gtype";
-			$gdesc = "Unknown Event $offset";
-			$rc = 0;
-		}
-
-		$desc = $gdesc;
-	}
-
-	if($type eq "" || $type eq "-") {
-		$type = "OEM Sensor Type $sensor_type"
-	}
-	if($desc eq "" || $desc eq "-") {
-		$desc = "OEM Sensor Event $offset"
-	}
-
-	if($type eq $desc) {
-		$desc = "";
-	}
-
-	my $extra_info = getaddsensorevent($sensor_type,$offset,$event_data_1,$event_data_2,$event_data_3);
-	if($extra_info) {
-		if($desc) {
-			$desc = "$desc $extra_info";
-		}
-		else {
-			$desc = "$extra_info";
-		}
-	}
-
-	$text = "$text $type,";
-	$text = "$text $desc";
-
-	my $key;
-	my $sensor_desc = sprintf("Sensor 0x%02x",$sensor_num);
-	foreach $key (keys %sdr_hash) {
-		my $sdr = $sdr_hash{$key};
-		if($sdr->sensor_number == $sensor_num) {
-			$sensor_desc = $sdr_hash{$key}->id_string;
-			if($sdr->rec_type == 0x01) {
-				last;
-			}
-		}
-	}
-
-	$text = "$text ($sensor_desc)";
-
-	if($event_dir) {
-		$text = "$text - Recovered";
-	}
-
-	return(0,$text);
-}
-
-sub readauxentry {
-    my $netfn=0x2e<<2;
-    my $entrynum = shift;
-    my $entryls = ($entrynum&0xff);
-    my $entryms = ($entrynum>>8);
-    my @cmd = (0x93,0x4d,0x4f,0x00,$entryls,$entryms,0,0,0xff,0x5); #Get log size andup to 1275 bytes of data, keeping it under 1500 to accomodate mixed-mtu circumstances
-    my @data;
-    my $error = docmd(
-        $netfn,
-        \@cmd,
-        \@data
-        );
-    if ($error) { return $error; }
-    if ($data[0]) { return $data[0]; }
-    my $text;
-    unless ($data[1] == 0x4d and $data[2] == 0x4f and $data[3] == 0) { return "Unrecognized response format" }
-    $entrynum=$data[6]+($data[7]<<8);
-    if (($data[10]&1) == 1) {
-        $text="POSSIBLY INCOMPLETE DATA FOLLOWS:\n";
-    }
-    my $addtext="";
-    if ($data[5] > 5) {
-        $addtext="\nTODO:SUPPORT MORE DATA THAT WAS SEEN HERE";
-    }
-    @data = splice @data,11;
-    pop @data;
-    while(scalar(@data)) {
-        my @subdata = splice @data,0,30;
-        my $numbytes = scalar(@subdata);
-        my $formatstring="%02x"x$numbytes;
-        $formatstring =~ s/%02x%02x/%02x%02x /g;
-        $text.=sprintf($formatstring."\n",@subdata);
-    }
-    $text.=$addtext;
-    return (0,$entrynum,$text);
-
-
-}
-
-
-
-sub eventlog {
-	my $subcommand = shift;
-
-	my $netfun = 0x28;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-	my @output;
-	my $num;
-	my $entry;
-    my $skiptail=0;
-	my @sel;
-	#my $ipmisensoreventtab = "$ENV{XCATROOT}/lib/GUMI/ipmisensorevent.tab";
-	#my $ipmigenericeventtab = "$ENV{XCATROOT}/lib/GUMI/ipmigenericevent.tab";
-	my $mfg_id;
-	my $prod_id;
-	my $device_id;
-
-	($rc,$text,$mfg_id,$prod_id,$device_id) = getdevid();
-	$rc=0;
-   unless (defined($subcommand)) {
-      $subcommand = 'all';
-   }
-	if($subcommand eq "all") {
-        $skiptail=1;
-
-		$num = 0x100 * 0x100;
-	}
-	elsif($subcommand eq "clear") {
-	}
-	elsif($subcommand =~ /^\d+$/) {
-		$num = $subcommand;
-	}
-	else {
-		return(1,"unsupported command eventlog $subcommand");
-	}
-
-   #Here we set tfactor based on the delta between the BMC reported time and our
-   #time.  The IPMI spec says the BMC should return seconds since 1970 in local
-   #time, but the reality is the firmware pushing to the BMC has no context
-   #to know, so here we guess and adjust all timestamps based on delta between
-   #our now and the BMC's now
-   $error = docmd(
-      $netfun,
-      [0x48],
-      \@returnd
-   );
-   $tfactor = $returnd[4]<<24 | $returnd[3]<<16 | $returnd[2]<<8 | $returnd[1];
-   if ($tfactor > 0x20000000) {
-      $tfactor -= time(); 
-   } else {
-      $tfactor = 0;
-   }
-      
-	@cmd=(0x40);
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-		return($rc,$text);
-	}
-
-	$code = $returnd[0];
-
-	if($code == 0x00) {
-	}
-	elsif($code == 0x81) {
-		$rc = 1;
-		$text = "cannot execute command, SEL erase in progress";
-	}
-	else {
-		$rc = 1;
-		$text = $codes{$code};
-	}
-
-	if($rc != 0) {
-		if(!$text) {
-			$text = sprintf("unknown response %02x",$code);
-		}
-		return($rc,$text);
-	}
-
-	my $sel_version = $returnd[1];
-	if($sel_version != 0x51) {
-		$rc = 1;
-		$text = sprintf("SEL version 51h support only, version reported: %x",$sel_version);
-		return($rc,$text);
-	}
-
-	my $num_entries = $returnd[3]*256 + $returnd[2];
-	if($num_entries <= 0) {
-		$rc = 1;
-		$text = "no SEL entries";
-		return($rc,$text);
-	}
-
-	my $canres = $returnd[14] & 0b00000010;
-	if(!$canres) {
-		$rc = 1;
-		$text = "SEL reservation not supported";
-		return($rc,$text);
-	}
-
-    my $res_id_ls=0;
-    my $res_id_ms=0;
-    my %auxloginfo;
-    if ($subcommand =~ /clear/) { #Don't bother with a reservation unless a clear is involved
-        #atomic SEL retrieval need not require it, so an event during retrieval will not kill reventlog effort off
-    	@cmd=(0x42);
-    	$error = docmd(
-    		$netfun,
-    		\@cmd,
-    		\@returnd
-    	);
-    
-    	if($error) {
-    		$rc = 1;
-    		$text = $error;
-    		return($rc,$text);
-    	}
-        
-    	$code = $returnd[0];
-    
-    	if($code == 0x00) {
-    	}
-    	elsif($code == 0x81) {
-    		$rc = 1;
-    		$text = "cannot execute command, SEL erase in progress";
-    	}
-    	else {
-    		$rc = 1;
-    		$text = $codes{$code};
-    	}
-    
-    	if($rc != 0) {
-    		if(!$text) {
-    			$text = sprintf("unknown response %02x",$code);
-    		}
-    		return($rc,$text);
-    	}
-
-	    $res_id_ls = $returnd[1];
-    	$res_id_ms = $returnd[2];
-    } elsif ($mfg_id == 2) {
-        #For requests other than clear, we check for IBM extended auxillary log data
-        my @auxdata;
-        my $netfn = 0xa << 2;
-        my @auxlogcmd = (0x5a,1);
-        $error = docmd(
-            $netfn,
-            \@auxlogcmd,
-            \@auxdata);
-        #print Dumper(\@auxdata);
-        unless ($error or $auxdata[0] or $auxdata[5] != 0x4d or $auxdata[6] != 0x4f or $auxdata[7] !=0x0 ) { #Don't bother if support cannot be confirmed by service processor
-            $netfn=0x2e<<2; #switch netfunctions to read
-            my $numauxlogs = $auxdata[8]+($auxdata[9]<<8);
-            my $auxidx=1;
-            my $rc;
-            my $entry;
-            my $extdata;
-            while ($auxidx<=$numauxlogs) {
-                ($rc,$entry,$extdata) = readauxentry($auxidx++);
-                unless ($rc) {
-                    if ($auxloginfo{$entry}) {
-                        $auxloginfo{$entry}.="!".$extdata;
-                    } else {
-                        $auxloginfo{$entry}=$extdata;
-                    }
-                }
-            }
-            if ($auxloginfo{0}) {
-                if ($skiptail) {
-                    foreach (split /!/,$auxloginfo{0}) {
-                        sendoutput(0,":Unassociated auxillary data detected:");
-                        foreach (split /\n/,$_) {
-                            sendoutput(0,$_);
-                        }
-                    }
-                }
-            }
-            #print Dumper(\%auxloginfo);
-        }
-    }
-
-
-	if($subcommand eq "clear") {
-		@cmd=(0x47,$res_id_ls,$res_id_ms,0x43,0x4c,0x52,0xaa);
-		$error = docmd(
-			$netfun,
-			\@cmd,
-			\@returnd
-		);
-
-		if($error) {
-			$rc = 1;
-			$text = $error;
-			return($rc,$text);
-		}
-
-		$code = $returnd[0];
-
-		if($code == 0x00) {
-		}
-		else {
-			$rc = 1;
-			$text = $codes{$code};
-		}
-
-		if($rc != 0) {
-			if(!$text) {
-				$text = sprintf("unknown response %02x",$code);
-			}
-			return($rc,$text);
-		}
-
-		my $erase_status = $returnd[1] & 0b00000001;
-
-#skip test for now, need to get new res id for some machines
-		while($erase_status == 0 && 0) {
-			sleep(1);
-			@cmd=(0x47,$res_id_ls,$res_id_ms,0x43,0x4c,0x52,0x00);
-			$error = docmd(
-				$netfun,
-				\@cmd,
-				\@returnd
-			);
-
-			if($error) {
-				$rc = 1;
-				$text = $error;
-				return($rc,$text);
-			}
-
-			$code = $returnd[0];
-
-			if($code == 0x00) {
-			}
-			else {
-				$rc = 1;
-				$text = $codes{$code};
-			}
-
-			if($rc != 0) {
-				if(!$text) {
-					$text = sprintf("unknown response %02x",$code);
-				}
-				return($rc,$text);
-			}
-
-			$erase_status = $returnd[1] & 0b00000001;
-		}
-
-		$text = "SEL cleared";
-		return($rc,$text);
-	}
-
-	($rc,$text) = initsdr();
-	if($rc != 0) {
-		return($rc,$text);
-	}
-
-	@cmd=(0x43,$res_id_ls,$res_id_ms,0x00,0x00,0x00,0xFF);
-	while(1) {
-		$error = docmd(
-			$netfun,
-			\@cmd,
-			\@returnd
-		);
-
-		if($error) {
-			$rc = 1;
-			$text = $error;
-            if ($skiptail) {
-                sendoutput($rc,$text);
-                return;
-            }
-            push(@output,$text);
-			return($rc,@output);
-		}
-
-		$code = $returnd[0];
-
-		if($code == 0x00) {
-		}
-		elsif($code == 0x81) {
-			$rc = 1;
-			$text = "cannot execute command, SEL erase in progress";
-		}
-		else {
-			$rc = 1;
-			$text = $codes{$code};
-		}
-
-		if($rc != 0) {
-			if(!$text) {
-				$text = sprintf("unknown response %02x",$code);
-			}
-            if ($skiptail) {
-                sendoutput($rc,$text);
-                return;
-            }
-            push(@output,$text);
-			return($rc,@output);
-		}
-
-		my $next_rec_ls = $returnd[1];
-		my $next_rec_ms = $returnd[2];
-		my @sel_data = @returnd[3..19];
-		@cmd=(0x43,$res_id_ls,$res_id_ms,$next_rec_ls,$next_rec_ms,0x00,0xFF);
-
-		$entry++;
-        if ($debug) {
-			print "$entry: ";
-			hexdump(\@sel_data);
-        }
-
-		my $record_id = $sel_data[0] + $sel_data[1]*256;
-		my $record_type = $sel_data[2];
-
-		if($record_type == 0x02) {
-		}
-		else {
-			$text=getoemevent($record_type,$mfg_id,\@sel_data);
-            if ($auxloginfo{$entry}) { 
-                $text.=" With additional data:\n".$auxloginfo{$entry};
-            }
-            if ($skiptail) {
-                sendoutput($rc,$text);
-            } else {
-			    push(@output,$text);
-            }
-			if($next_rec_ms == 0xFF && $next_rec_ls == 0xFF) {
-				last;
-			}
-			next;
-		}
-
-		my $timestamp = ($sel_data[3] | $sel_data[4]<<8 | $sel_data[5]<<16 | $sel_data[6]<<24);
-      unless ($timestamp < 0x20000000) { #IPMI Spec says below this is effectively BMC uptime, not correctable
-         $timestamp -= $tfactor; #apply correction factor based on how off the current BMC clock is from management server
-      }
-		my ($seldate,$seltime) = timestamp2datetime($timestamp);
-#		$text = "$entry: $seldate $seltime";
-		$text = ":$seldate $seltime";
-
-#		my $gen_id_slave_addr = ($sel_data[7] & 0b11111110) >> 1;
-#		my $gen_id_slave_addr_hs = ($sel_data[7] & 0b00000001);
-#		my $gen_id_ch_num = ($sel_data[8] & 0b11110000) >> 4;
-#		my $gen_id_ipmb = ($sel_data[8] & 0b00000011);
-
-		my $sensor_owner_id = $sel_data[7];
-		my $sensor_owner_lun = $sel_data[8];
-
-		my $sensor_type = $sel_data[10];
-		my $sensor_num = $sel_data[11];
-		my $event_dir = $sel_data[12] & 0b10000000;
-		my $event_type = $sel_data[12] & 0b01111111;
-		my $offset = $sel_data[13] & 0b00001111;
-		my $event_data_1 = $sel_data[13];
-		my $event_data_2 = $sel_data[14];
-		my $event_data_3 = $sel_data[15];
-		my $sev = 0;
-		$sev = ($sel_data[14] & 0b11110000) >> 4;
-#		if($event_type != 1) {
-#			$sev = ($sel_data[14] & 0b11110000) >> 4;
-#		}
-#		$text = "$text $sev:";
-
-		my $type;
-		my $desc;
-		($rc,$type,$desc) = getsensorevent($sensor_type,$offset,"ipmisensorevents");
-		if($rc == 1) {
-			$type = "Unknown Type $sensor_type";
-			$desc = "Unknown Event $offset";
-			$rc = 0;
-		}
-
-		if($event_type <= 0x0c) {
-			my $gtype;
-			my $gdesc;
-			($rc,$gtype,$gdesc) = getsensorevent($event_type,$offset,"ipmigenericevents");
-			if($rc == 1) {
-				$gtype = "Unknown Type $gtype";
-				$gdesc = "Unknown Event $offset";
-				$rc = 0;
-			}
-
-			$desc = $gdesc;
-		}
-
-		if($type eq "" || $type eq "-") {
-			$type = "OEM Sensor Type $sensor_type"
-		}
-		if($desc eq "" || $desc eq "-") {
-			$desc = "OEM Sensor Event $offset"
-		}
-
-		if($type eq $desc) {
-			$desc = "";
-		}
-
-		my $extra_info = getaddsensorevent($sensor_type,$offset,$event_data_1,$event_data_2,$event_data_3);
-		if($extra_info) {
-			if($desc) {
-				$desc = "$desc $extra_info";
-			}
-			else {
-				$desc = "$extra_info";
-			}
-		}
-
-		$text = "$text $type,";
-		$text = "$text $desc";
-
-#		my $key;
-		my $key = $sensor_owner_id . "." . $sensor_owner_lun . "." . $sensor_num;
-		my $sensor_desc = sprintf("Sensor 0x%02x",$sensor_num);
-#		foreach $key (keys %sdr_hash) {
-#			my $sdr = $sdr_hash{$key};
-#			if($sdr->sensor_number == $sensor_num) {
-#				$sensor_desc = $sdr_hash{$key}->id_string;
-#				last;
-#			}
-#		}
-		if(defined $sdr_hash{$key}) {
-			$sensor_desc = $sdr_hash{$key}->id_string;
-         if ($sdr_hash{$key}->event_type_code == 1) {
-            if (($event_data_1 & 0b11000000) == 0b01000000) {
-               $sensor_desc .= " reading ".translate_sensor($event_data_2,$sdr_hash{$key});
-               if (($event_data_1 & 0b00110000) == 0b00010000) {
-                  $sensor_desc .= " with threshold " . translate_sensor($event_data_3,$sdr_hash{$key});
-               }
-            }
-         }
-		}
-
-		$text = "$text ($sensor_desc)";
-
-		if($event_dir) {
-			$text = "$text - Recovered";
-		}
-
-        if ($auxloginfo{$entry}) {
-             $text.=" with additional data:";
-             if ($skiptail) {
-                sendoutput($rc,$text);
-                foreach (split /\n/,$auxloginfo{$entry}) {
-                    sendoutput(0,$_);
-                }
-             } else {
-        		push(@output,$text);
-                push @output,split /\n/,$auxloginfo{$entry};
-             } 
-
-        } else {
-            if ($skiptail) {
-                sendoutput($rc,$text);
-            } else {
-        		push(@output,$text);
-            }
-        }
-
-		if($next_rec_ms == 0xFF && $next_rec_ls == 0xFF) {
-			last;
-		}
-	}
-
-	my @routput = reverse(@output);
-	my @noutput;
-	my $c;
-	foreach(@routput) {
-		$c++;
-		if($c > $num) {
-			last;
-		}
-		push(@noutput,$_);
-	}
-	@output = reverse(@noutput);
-
-	return($rc,@output);
-}
-sub getoemevent {
-	my $record_type = shift;
-	my $mfg_id = shift;
-	my $sel_data = shift;
-	my $text=":";
-	if ($record_type < 0xE0 && $record_type > 0x2F) { #Should be timestampped, whatever it is
-		my $timestamp =  (@$sel_data[3] | @$sel_data[4]<<8 | @$sel_data[5]<<16 | @$sel_data[6]<<24);
-      unless ($timestamp < 0x20000000) {
-         $timestamp -= $tfactor;
-      }
-		my ($seldate,$seltime) = timestamp2datetime($timestamp);
-		my @rest = @$sel_data[7..15];
-		if ($mfg_id==2) {
-			$text.="$seldate $seltime IBM OEM Event-";
-			if ($rest[3]==0 && $rest[4]==0 && $rest[7]==0) {
-				$text=$text."PCI Event/Error, details in next event"
-			} elsif ($rest[3]==1 && $rest[4]==0 && $rest[7]==0) {
-				$text=$text."Processor Event/Error occurred, details in next event"
-			} elsif ($rest[3]==2 && $rest[4]==0 && $rest[7]==0) {
-				$text=$text."Memory Event/Error occurred, details in next event"
-			} elsif ($rest[3]==3 && $rest[4]==0 && $rest[7]==0) {
-				$text=$text."Scalability Event/Error occurred, details in next event"
-			} elsif ($rest[3]==4 && $rest[4]==0 && $rest[7]==0) {
-				$text=$text."PCI bus Event/Error occurred, details in next event"
-			} elsif ($rest[3]==5 && $rest[4]==0 && $rest[7]==0) {
-				$text=$text."Chipset Event/Error occurred, details in next event"
-			} elsif ($rest[3]==6 && $rest[4]==1 && $rest[7]==0) {
-				$text=$text."BIOS/BMC Power Executive mismatch (BIOS $rest[5], BMC $rest[6])"
-			} elsif ($rest[3]==6 && $rest[4]==2 && $rest[7]==0) {
-				$text=$text."Boot denied due to power limitations"
-			} else {
-				$text=$text."Unknown event ". phex(\@rest);
-			}
-		} else {
-		     $text .= "$seldate $seltime " . sprintf("Unknown OEM SEL Type %02x:",$record_type) . phex(\@rest);
-		}
-	} else { #Non-timestamped
-		my %memerrors = (
-			0x00 => "DIMM enabled",
-			0x01 => "DIMM disabled, failed ECC test",
-			0x02 => "POST/BIOS memory test failed, DIMM disabled",
-			0x03 => "DIMM disabled, non-supported memory device",
-			0x04 => "DIMM disabled, non-matching or missing DIMM(s)",
-		);
-		my %pcierrors = (
-			0x00 => "Device OK",
-			0x01 => "Required ROM space not available",
-			0x02 => "Required I/O Space not available",
-			0x03 => "Required memory not available",
-			0x04 => "Required memory below 1MB not available",
-			0x05 => "ROM checksum failed",
-			0x06 => "BIST failed",
-			0x07 => "Planar device missing or disabled by user",
-			0x08 => "PCI device has an invalid PCI configuration space header",
-			0x09 => "FRU information for added PCI device",
-			0x0a => "FRU information for removed PCI device",
-			0x0b => "A PCI device was added, PCI FRU information is stored in next log entry",
-			0x0c => "A PCI device was removed, PCI FRU information is stored in next log entry",
-			0x0d => "Requested resources not available",
-			0x0e => "Required I/O Space Not Available",
-			0x0f => "Required I/O Space Not Available",
-			0x10 => "Required I/O Space Not Available",
-			0x11 => "Required I/O Space Not Available",
-			0x12 => "Required I/O Space Not Available",
-			0x13 => "Planar video disabled due to add in video card",
-			0x14 => "FRU information for PCI device partially disabled ",
-			0x15 => "A PCI device was partially disabled, PCI FRU information is stored in next log entry",
-			0x16 => "A 33Mhz device is installed on a 66Mhz bus, PCI device information is stored in next log entry",
-			0x17 => "FRU information, 33Mhz device installed on 66Mhz bus",
-			0x18 => "Merge cable missing",
-			0x19 => "Node 1 to Node 2 cable missing",
-			0x1a => "Node 1 to Node 3 cable missing",
-			0x1b => "Node 2 to Node 3 cable missing",
-			0x1c => "Nodes could not merge",
-			0x1d => "No 8 way SMP cable",
-			0x1e => "Primary North Bridge to PCI Host Bridge IB Link has failed",
-			0x1f => "Redundant PCI Host Bridge IB Link has failed",
-		);
-		my %procerrors = (
-			0x00 => "Processor has failed BIST",
-			0x01 => "Unable to apply processor microcode update",
-			0x02 => "POST does not support current stepping level of processor",
-			0x03 => "CPU mismatch detected",
-		);
-		my @rest = @$sel_data[3..15];
-		if ($record_type == 0xE0 && $rest[0]==2 && $mfg_id==2 && $rest[1]==0 && $rest[12]==1) { #Rev 1 POST memory event
-			$text="IBM Memory POST Event-";
-			my $msuffix=sprintf(", chassis %d, card %d, dimm %d",$rest[3],$rest[4],$rest[5]);
-			#the next bit is a basic lookup table, should implement as a table ala ibmleds.tab, or a hash... yeah, a hash...
-			$text=$text.$memerrors{$rest[2]}.$msuffix;
-		} elsif ($record_type == 0xE0 && $rest[0]==1 && $mfg_id==2 && $rest[12]==0) { #A processor error or event, rev 0 only known in the spec I looked at
-			$text=$text.$procerrors{$rest[1]};
-		} elsif ($record_type == 0xE0 && $rest[0]==0 && $mfg_id==2) { #A PCI error or event, rev 1 or 2, the revs differe in endianness
-			my $msuffix;
-			if ($rest[12]==0) {
-				$msuffix=sprintf("chassis %d, slot %d, bus %s, device %02x%02x:%02x%02x",$rest[2],$rest[3],$rest[4],$rest[5],$rest[6],$rest[7],$rest[8]);
-			} elsif ($rest[12]==1) {
-				$msuffix=sprintf("chassis %d, slot %d, bus %s, device %02x%02x:%02x%02x",$rest[2],$rest[3],$rest[4],$rest[5],$rest[6],$rest[7],$rest[8]);
-			} else {
-				return ("Unknown IBM PCI event/error format");
-			}
-			$text=$text.$pcierrors{$rest[1]}.$msuffix;
-		} else {
-			#Some event we can't define that is OEM or some otherwise unknown event
-			$text = sprintf("SEL Type %02x:",$record_type) . phex(\@rest);
-		}
-	} #End timestampped intepretation
-	return ($text);
-}
-
-sub getsensorevent
-{
-	my $sensortype = sprintf("%02Xh",shift);
-	my $sensoroffset = sprintf("%02Xh",shift);
-	my $file = shift;
-
-	my @line;
-	my $type;
-	my $code;
-	my $desc;
-	my $offset;
-	my $rc = 1;
-
-    if ($file eq "ipmigenericevents") {
-      if ($xCAT::data::ipmigenericevents::ipmigenericevents{"$sensortype,$sensoroffset"}) {
-        ($type,$desc) = split (/,/,$xCAT::data::ipmigenericevents::ipmigenericevents{"$sensortype,$sensoroffset"},2);
-	    return(0,$type,$desc);
-      }
-      if ($xCAT::data::ipmigenericevents::ipmigenericevents{"$sensortype,-"}) {
-        ($type,$desc) = split (/,/,$xCAT::data::ipmigenericevents::ipmigenericevents{"$sensortype,-"},2);
-	    return(0,$type,$desc);
-       }
-    }
-    if ($file eq "ipmisensorevents") {
-      if ($xCAT::data::ipmisensorevents::ipmisensorevents{"$sensortype,$sensoroffset"}) {
-        ($type,$desc) = split (/,/,$xCAT::data::ipmisensorevents::ipmisensorevents{"$sensortype,$sensoroffset"},2);
-	    return(0,$type,$desc);
-      }
-      if ($xCAT::data::ipmisensorevents::ipmisensorevents{"$sensortype,-"}) {
-        ($type,$desc) = split (/,/,$xCAT::data::ipmisensorevents::ipmisensorevents{"$sensortype,-"},2);
-	    return(0,$type,$desc);
-       }
-    }
-    return (0,"No Mappings found ($sensortype)","No Mappings found ($sensoroffset)");
-}
-
-sub getaddsensorevent {
-	my $sensor_type = shift;
-	my $offset = shift;
-	my $event_data_1 = shift;
-	my $event_data_2 = shift;
-	my $event_data_3 = shift;
-	my $text = "";
-
-    if ($sensor_type == 0x08 && $offset == 6) {
-        my %extra = (
-            0x0 => "Vendor mismatch",
-            0x1 => "Revision mismatch",
-            0x2 => "Processor missing",
-            );
-        if ($extra{$event_data_3}) {
-            $text = $extra{$event_data_3};
-        }
-    }
-    if ($sensor_type == 0x0C) {
-        $text = sprintf ("Memory module %d",$event_data_3);
-    }
-
-	if($sensor_type == 0x0f) {
-		if($offset == 0x00) {
-			my %extra = (
-				0x00 => "Unspecified",
-				0x01 => "No system memory installed",
-				0x02 => "No usable system memory",
-				0x03 => "Unrecoverable hard disk failure",
-				0x04 => "Unrecoverable system board failure",
-				0x05 => "Unrecoverable diskette failure",
-				0x06 => "Unrecoverable hard disk controller failure",
-				0x07 => "Unrecoverable keyboard failure",
-				0x08 => "Removable boot media not found",
-				0x09 => "Unrecoverable video controller failure",
-				0x0a => "No video device detected",
-				0x0b => "Firmware (BIOS) ROM corruption detected",
-				0x0c => "CPU voltage mismatch",
-				0x0d => "CPU speed matching failure",
-			);
-			$text = $extra{$event_data_2};
-		}
-		if($offset == 0x02) {
-			my %extra = (
-				0x00 => "Unspecified",
-				0x01 => "Memory initialization",
-				0x02 => "Hard-disk initialization",
-				0x03 => "Secondary processor(s) initialization",
-				0x04 => "User authentication",
-				0x05 => "User-initiated system setup",
-				0x06 => "USB resource configuration",
-				0x07 => "PCI resource configuration",
-				0x08 => "Option ROM initialization",
-				0x09 => "Video initialization",
-				0x0a => "Cache initialization",
-				0x0b => "SM Bus initialization",
-				0x0c => "Keyboard controller initialization",
-				0x0d => "Embedded controller/management controller initialization",
-				0x0e => "Docking station attachement",
-				0x0f => "Enabling docking station",
-				0x10 => "Docking staion ejection",
-				0x11 => "Disable docking station",
-				0x12 => "Calling operation system wake-up vector",
-				0x13 => "Starting operation system boot process, call init 19h",
-				0x14 => "Baseboard or motherboard initialization",
-				0x16 => "Floppy initialization",
-				0x17 => "Keyboard test",
-				0x18 => "Pointing device test",
-				0x19 => "Primary processor initialization",
-			);
-			$text = $extra{$event_data_2};
-		}
-	}
-    if ($sensor_type == 0x10) {
-        if ($offset == 0x0) {
-            $text = sprintf("Memory module %d",$event_data_2);
-        } elsif ($offset == 0x01) {
-            $text = "Disabled for ";
-            unless ($event_data_3 & 0x20) {
-                if ($event_data_3 & 0x10) {
-                    $text .= "assertions of";
-                } else {
-                    $text .= "deassertions of";
-                } 
-            }
-            $text .= sprintf ("type %02xh/offset %02xh",$event_data_2,$event_data_3&0x0F);
-        } elsif ($offset == 0x05) {
-            $text = "$event_data_3% full";
-        }
-    }
-            
-	if($sensor_type == 0x12) {
-		if($offset == 0x03) {
-		}
-		if($offset == 0x04) {
-			if($event_data_2 & 0b00100000) {
-				$text = "$text, NMI";
-			}
-			if($event_data_2 & 0b00010000) {
-				$text = "$text, OEM action";
-			}
-			if($event_data_2 & 0b00001000) {
-				$text = "$text, power cycle";
-			}
-			if($event_data_2 & 0b00000100) {
-				$text = "$text, reset";
-			}
-			if($event_data_2 & 0b00000010) {
-				$text = "$text, power off";
-			}
-			if($event_data_2 & 0b00000001) {
-				$text = "$text, Alert";
-			}
-			$text =~ s/^, //;
-		}
-	}
-    if ($sensor_type == 0x1d && $offset == 0x07) {
-        my %causes = (
-            0 => "Unknown",
-            1 => "Chassis reset via User command to BMC",
-            2 => "Reset button",
-            3 => "Power button",
-            4 => "Watchdog action",
-            5 => "OEM",
-            6 => "AC Power apply force on",
-            7 => "Restore previous power state on AC",
-            8 => "PEF initiated reset",
-            9 => "PEF initiated power cycle",
-            10 => "Soft reboot",
-            11 => "RTC Wake",
-        );
-        if ($causes{$event_data_2 & 0xf}) {
-            $text = $causes{$event_data_2};
-        } else {
-            $text = "Unrecognized cause ".$event_data_2 & 0xf;
-        }
-        $text .= "via channel $event_data_3";
-    }
-    if ($sensor_type == 0x21) {
-        my %extra = (
-            0 => "PCI slot",
-            1 => "Drive array",
-            2 => "External connector",
-            3 => "Docking port",
-            4 => "Other slot",
-            5 => "Sensor ID",
-            6 => "AdvncedTCA",
-            7 => "Memory slot",
-            8 => "FAN",
-            9 => "PCIe",
-            10 => "SCSI",
-            11 => "SATA/SAS",
-         );
-
-        $text=$extra{$event_data_2 & 127};
-        unless ($text) {
-            $text = "Unknown slot/conn type ".$event_data_2&127;
-        }
-        $text .= " $event_data_3";
-    }
-    if ($sensor_type == 0x23) {
-        my %extra = (
-            0x10 => "SMI",
-            0x20 => "NMI",
-            0x30 => "Messaging Interrupt",
-            0xF0 => "Unspecified",
-            0x01 => "BIOS FRB2",
-            0x02 => "BIOS/POST",
-            0x03 => "OS Load",
-            0x04 => "SMS/OS",
-            0x05 => "OEM",
-            0x0F => "Unspecified"
-        );
-        if ($extra{$event_data_2 & 0xF0}) {
-            $text = $extra{$event_data_2 & 0xF0};
-        }
-        if ($extra{$event_data_2 & 0x0F}) {
-            $text .= ", ".$extra{$event_data_2 & 0x0F};
-        }
-        $text =~ s/^, //;
-    }
-    if ($sensor_type == 0x28) {
-        if ($offset == 0x4) {
-            $text = "Sensor $event_data_2";
-        } elsif ($offset == 0x5) {
-            $text = "";
-            my $logicalfru=0;
-            if ($event_data_2 & 128) {
-                $logicalfru=1;
-            }
-            my $intelligent=1;
-            if ($event_data_2 & 24) {
-                $text .= "LUN ".($event_data_2&24)>>3;
-            } else {
-                $intelligent=0;
-            }
-            if ($event_data_2 & 7) {
-                $text .= "Bus ID ".($event_data_2&7);
-            }
-            if ($logicalfru) {
-                $text .= "FRU ID ".$event_data_3;
-            } elsif (not $intelligent) {
-                $text .= "I2C addr ".$event_data_3>>1;
-            }
-        }
-    }
-
-    if ($sensor_type == 0x2a) {
-        $text = sprintf("Channel %d, User %d",$event_data_3&0x0f,$event_data_2&0x3f);
-        if ($offset == 1) {
-            if (($event_data_3 & 207) == 1) {
-                $text .= " at user request";
-            } elsif (($event_data_3 & 207) == 2) {
-                $text .= " timed out";
-            } elsif (($event_data_3 & 207) == 3) {
-                $text .= " configuration change";
-            }
-        }
-    }
-    if ($sensor_type == 0x2b) {
-        my %extra = (
-            0x0 => "Unspecified",
-            0x1 => "BMC device ID",
-            0x2 => "BMC Firmware",
-            0x3 => "BMC Hardware",
-            0x4 => "BMC manufacturer",
-            0x5 => "IPMI Version",
-            0x6 => "BMC aux firmware ID",
-            0x7 => "BMC boot block",
-            0x8 => "Other BMC Firmware",
-            0x09 => "BIOS/EFI change",
-            0x0a => "SMBIOS change",
-            0x0b => "OS change",
-            0x0c => "OS Loader change",
-            0x0d => "Diagnostics change",
-            0x0e => "Management agent change",
-            0x0f => "Management software change",
-            0x10 => "Management middleware change",
-            0x11 => "FPGA/CPLD/PSoC change",
-            0x12 => "FRU change",
-            0x13 => "device addition/removal",
-            0x14 => "Equivalent replacement",
-            0x15 => "Newer replacement",
-            0x16 => "Older replacement",
-            0x17 => "DIP/Jumper change",
-        );
-        if ($extra{$event_data_2}) {
-            $text = $extra{$event_data_2};
-        } else {
-            $text = "Unknown version change type $event_data_2";
-        }
-    }
-    if ($sensor_type == 0x2c) {
-        my %extra = (
-            0 => "",
-            1 => "Software dictated",
-            2 => "Latch operated",
-            3 => "Hotswap buton pressed",
-            4 => "automatic operation",
-            5 => "Communication lost",
-            6 => "Communication lost locally",
-            7 => "Unexpected removal",
-            8 => "Operator intervention",
-            9 => "Unknwon IPMB address",
-            10 => "Unexpected deactivation",
-            0xf => "unknown",
-            );
-        if ($extra{$event_data_2>>4}) {
-              $text = $extra{$event_data_2>>4};
-          } else {
-              $text = "Unrecognized cause ".$event_data_2>>4;
-          }
-          my $prev_state=$event_data_2 & 0xf;
-          unless ($prev_state == $offset) {
-              my %oldstates = ( 
-                0 => "Not Installed",
-                1 => "Inactive",
-                2 => "Activation requested",
-                3 => "Activating",
-                4 => "Active",
-                5 => "Deactivation requested",
-                6 => "Deactivating",
-                7 => "Communication lost",
-            );
-            if ($oldstates{$prev_state}) {
-                $text .= "(was ".$oldstates{$prev_state}.")";
-            } else {
-                $text .= "(was in unrecognized state $prev_state)";
-            }
-          }
-    }
-
-
-
-	return($text);
-}
-
-sub initiem {
-    my $iem = IBM::EnergyManager->new();
-    my @payload = $iem->get_next_payload();
-    my $netfun = shift @payload;
-    my @returnd;
-	my $error = docmd(
-			$netfun<<2,
-			\@payload,
-			\@returnd
-		);
-    $iem->handle_next_payload(@returnd);
-    return $iem;
-}
-
-sub readenergy {
-    unless ($iem_support) { 
-        return (1,"IBM::EnergyManager package required for this value");
-    }
-    my @entries;
-    my $iem = initiem();
-    my $entry;
-    $iem->prep_get_ac_energy();
-    $entry = process_data_from_iem($iem);
-    $iem->prep_get_precision();
-    execute_iem_commands($iem); #this gets all precision data initialized
-    $entry .= sprintf(" +/-%.1f%%",$iem->energy_ac_precision()*0.1); #note while \x{B1} would be cool, it's non-trivial to support
-    push @entries,$entry;
-    $iem->prep_get_dc_energy();
-    $entry = process_data_from_iem($iem);
-    $entry .= sprintf(" +/-%.1f%%",$iem->energy_dc_precision()*0.1);
-    push @entries,$entry;
-    return (0,@entries);
-
-}
-
-sub execute_iem_commands {
-    my $iem = shift;
-    my @payload = $iem->get_next_payload();
-    my @returnd;
-    while (scalar @payload) {
-        my $netfun = shift @payload;
-        my $error = docmd($netfun<<2,\@payload,\@returnd);
-        if ($error) { return $error; }
-        $iem->handle_next_payload(@returnd);
-        @payload = $iem->get_next_payload();
-    }
-    return 0;
-}
-
-sub process_data_from_iem {
-    my $iem = shift;
-    my @returnd;
-    my @iemdata;
-    if (!execute_iem_commands($iem)) {
-        @iemdata = $iem->extract_data;
-    }
-    my $label = shift @iemdata;
-    my $units = shift @iemdata;
-    my $value=0;
-    my $shift=0;
-    while (scalar @iemdata) { #stuff the 64-bits of data into an int, would break in 32 bit
-        $value+=pop(@iemdata)<<$shift;
-        #$value.=sprintf("%02x ",shift @iemdata);
-        $shift+=8;
-    }
-    if ($units eq "mJ") {
-        $units = "kWh";
-        $value = $value / 3600000000;
-        return sprintf("$label: %.4f $units",$value);
-    } elsif ($units eq "mW") {
-        $units = "W";
-        $value = $value / 1000.0;
-        return sprintf("$label: %.1f $units",$value);
-    }
-}
-
-sub checkleds {
-	my $netfun = 0xe8; #really 0x3a
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $led_id_ms;
-	my $led_id_ls;
-	my $rc = 0;
-	my @output =();
-	my $text="";
-	my $key;
-	my $mfg_id;
-	my $prod_id;
-	($rc,$text,$mfg_id,$prod_id) = getdevid();
-	if ($mfg_id != 2) {
-		return (0,"LED status not supported on this system");
-	}
-	
-	($rc,$text) = initsdr();
-	if($rc != 0) {
-		return($rc,$text);
-	}
-	foreach $key (sort {$sdr_hash{$a}->id_string cmp $sdr_hash{$b}->id_string} keys %sdr_hash) {
-		my $sdr = $sdr_hash{$key};
-		if($sdr->rec_type == 0xC0 && $sdr->sensor_type == 0xED) {
-			#this stuff is to help me build the file from spec paste
-			#my $tehstr=sprintf("grep 0x%04X /opt/xcat/lib/x3755led.tab",$sdr->led_id);
-			#my $tehstr=`$tehstr`;
-			#$tehstr =~ s/^0x....//;
-			
-			#printf("%X.%X.0x%04x",$mfg_id,$prod_id,$sdr->led_id);
-			#print $tehstr;
-		
-			#We are inconsistant in our spec, first try a best guess
-			#at endianness, assume the smaller value is MSB
-			if (($sdr->led_id&0xff) > ($sdr->led_id>>8)) {
-				$led_id_ls=$sdr->led_id&0xff;
-				$led_id_ms=$sdr->led_id>>8;
-			} else {	
-				$led_id_ls=$sdr->led_id>>8;
-				$led_id_ms=$sdr->led_id&0xff;
-			}
-				
-			@cmd=(0xc0,$led_id_ms,$led_id_ls);
-			$error = docmd(
-				$netfun,
-				\@cmd,
-				\@returnd
-			);
-			if($error) {
-				$rc = 1;
-				$text = $error;
-				return($rc,$text);
-			}
-			if ($returnd[0] == 0xc9) {
-				my $tmp;
-				#we probably guessed endianness wrong.
-				$tmp=$led_id_ls;
-				$led_id_ls=$led_id_ms;
-				$led_id_ms=$tmp;
-				@cmd=(0xc0,$led_id_ms,$led_id_ls);
-				$error = docmd(
-                                	$netfun,
-					\@cmd,
-					\@returnd
-                       		);
-				if($error) {
-					$rc = 1;
-					$text = $error;
-					return($rc,$text);
-				}
-			}
-
-			if ($returnd[2]) { # != 0) {
-				#It's on...
-				if ($returnd[6] == 4) {
-					push(@output,sprintf("BIOS or admininstrator has %s lit",getsensorname($mfg_id,$prod_id,$sdr->led_id,"ibmleds")));
-				}
-				elsif ($returnd[6] == 3) {
-					push(@output,sprintf("A user has manually requested LED 0x%04x (%s) be active",$sdr->led_id,getsensorname($mfg_id,$prod_id,$sdr->led_id,"ibmleds")));
-				}
-				elsif ($returnd[6] == 1 && $sdr->led_id !=0) {
-					push(@output,sprintf("LED 0x%02x%02x (%s) active to indicate LED 0x%02x%02x (%s) is active",$led_id_ms,$led_id_ls,getsensorname($mfg_id,$prod_id,$sdr->led_id,"ibmleds"),$returnd[4],$returnd[5],getsensorname($mfg_id,$prod_id,($returnd[4]<<8)+$returnd[5],"ibmleds")));
-				}
-				elsif ($sdr->led_id ==0) {
-					push(@output,sprintf("LED 0x0000 (%s) active to indicate system error condition.",getsensorname($mfg_id,$prod_id,$sdr->led_id,"ibmleds")));
-				}
-				elsif ($returnd[6] == 2) {
-					my $sensor_desc;
-					#Ok, LED is tied to a sensor..
-					my $sensor_num=$returnd[5];
-				        foreach $key (keys %sdr_hash) {
-						my $osdr = $sdr_hash{$key};
-				                if($osdr->sensor_number == $sensor_num) {
-				                        $sensor_desc = $sdr_hash{$key}->id_string;
-				                        if($osdr->rec_type == 0x01) {
-			                                	last;
-							}
-			                        }
-			                }
-					$rc=0;
-					#push(@output,sprintf("Sensor 0x%02x (%s) has activated LED 0x%04x",$sensor_num,$sensor_desc,$sdr->led_id));
-					push(@output,sprintf("LED 0x%02x%02x active to indicate Sensor 0x%02x (%s) error.",$led_id_ms,$led_id_ls,$sensor_num,$sensor_desc));
-			        }
-			} 
-					
-		}
-	}
-	if ($#output==-1) {
-		push(@output,"No active error LEDs detected");
-	}
-	return($rc,@output);
-}
-	
-sub renergy {
-    my @subcommands = shift;
-    my @output;
-    my @settable_keys = qw/savingstatus cappingstatus cappingwatt/;
-    unless ($iem_support) {
-        return (1,"Command unsupported without IBM::EnergyManager installed");
-    }
-    my $iem = initiem();
-    my @directives=();
-    foreach (@subcommands) {
-        push @directives,split /,/,$_;
-    }
-    my $directive;
-    my $value;
-    my $key;
-    foreach $directive (@directives) {
-        $value=undef;
-        $key=undef;
-        if ($directive =~ /(.*)=(.*)\z/) { #todo: assigment
-            $key = $1;
-            $value = $2;
-            unless (grep /$key/,@settable_keys and $value) {
-                return (1,"Malformed argument $directive");
-            }
-            if ($key eq "cappingwatt") {
-                $value = $value*1000; #convert to milliwatts
-                $iem->prep_set_cap($value);
-                execute_iem_commands($iem); #this gets all precision data initialized
-            }
-            if ($key eq "cappingstatus") {
-                if (grep /$value/,qw/enable on 1/) {
-                    $value = 1;
-                } else {
-                    $value = 0;
-                }
-                $iem->prep_set_capenable($value);
-                execute_iem_commands($iem); #this gets all precision data initialized
-            }
-
-        }
-        if ($directive =~ /cappingmaxmin/) {
-            my $entry;
-            $iem->prep_get_mincap();
-            $entry = process_data_from_iem($iem);
-            push @output,$entry;
-            $iem->prep_get_maxcap();
-            $entry = process_data_from_iem($iem);
-            push @output,$entry;
-        }
-        if ($directive =~ /cappingvalue/) {
-            my $entry;
-            $iem->prep_get_cap();
-            push @output,process_data_from_iem($iem);
-        }
-        if ($directive =~ /cappingstatus/) {
-            my $entry;
-            $iem->prep_get_powerstatus();
-            execute_iem_commands($iem);
-            my $capenabled = $iem->capping_enabled();
-            push @output,"cappingstatus: ".($capenabled ? "on" : "off");
-        }
-        if ($directive =~ /relhistogram/) {
-            my $entry;
-            $iem->prep_retrieve_histogram();
-            execute_iem_commands($iem);
-            my @histdata = $iem->extract_relative_histogram;
-            foreach (sort { $a <=> $b } keys %{$histdata[0]}) {
-                push @output,"$_: ".$histdata[0]->{$_};
-            }
-        }
-    }
-    return (0,@output);
-}
-sub vitals {
-	my $subcommand = shift;
-    my @textfilters = split /,/,$subcommand;
-    unless (scalar @textfilters) { @textfilters = ("all"); }
-
-	my $rc = 0;
-	my $text;
-	my $key;
-	my %sensor_filters=();
-	my @output;
-	my $reading;
-	my $unitdesc;
-	my $value;
-	my $extext;
-	my $format = "%-30s%8s %-20s";
-	my $per = " ";
-   my $doall;
-   $doall=0;
-	$rc=0;
-    #filters: defined in sensor type codes and data table
-    # 1 == temp, 2 == voltage 3== current (we lump in wattage here for lack of a better spot), 4 == fan
-
-	if(grep { $_ eq "all"} @textfilters) {
-	  $sensor_filters{1}=1; #,0x02,0x03,0x04); rather than filtering, unfiltered results
-      $sensor_filters{energy}=1;
-      $doall=1;
-	}
-	if(grep /temp/,@textfilters) {
-		$sensor_filters{0x01}=1;
-	}
-	if(grep /volt/,@textfilters) {
-		$sensor_filters{0x02}=1;
-	}
-    if(grep /watt/,@textfilters) {
-        $sensor_filters{0x03}=1;
-    }
-	if(grep /fan/,@textfilters) {
-		$sensor_filters{0x04}=1;
-	}
-	if(grep /power/,@textfilters) {  #power does not really include energy, but most people use 'power' to mean both
-        $sensor_filters{0x03}=1;
-        $sensor_filters{powerstate}=1;
-        $sensor_filters{energy}=1;
-	}
-	if(grep /energy/,@textfilters) { 
-        $sensor_filters{energy}=1;
-	}
-	if(grep /led/,@textfilters) {
-        $sensor_filters{leds}=1;
-	}
-	unless (keys %sensor_filters) {
-		return(1,"unsupported command vitals $subcommand");
-	}
-
-	($rc,$text) = initsdr();
-	if($rc != 0) {
-		return($rc,$text);
-	}
-
-	foreach(keys %sensor_filters) {
-		my $filter = $_;
-        if ($filter eq "energy" or $filter eq "leds") { next; }
-
-		foreach $key (sort {$sdr_hash{$a}->id_string cmp $sdr_hash{$b}->id_string} keys %sdr_hash) {
-			my $sdr = $sdr_hash{$key};
-			if(($doall and not $sdr->rec_type == 0x11 and not $sdr->sensor_type==0xed) or ($sdr->rec_type == 0x01 and $sdr->sensor_type == $filter)) {
-				my $lformat = $format;
-
-				($rc,$reading,$extext) = readsensor($sdr);
-				$unitdesc = "";
-				if($rc == 0) {
-					$unitdesc = $units{$sdr->sensor_units_2};
-
-                    $value = $reading;
-                    if ($sdr->rec_type==1) {
-    					$value = (($sdr->M * $reading) + ($sdr->B * (10**$sdr->B_exp))) * (10**$sdr->R_exp);
-                    }
-					if($sdr->rec_type != 1 or $sdr->linearization == 0) {
-						$reading = $value;
-						if($value == int($value)) {
-							$lformat = "%-30s%8d%s";
-						}
-						else {
-							$lformat = "%-30s%8.3f%s";
-						}
-					}
-					elsif($sdr->linearization == 7) {
-						if($value > 0) {
-							$reading = 1/$value;
-						}
-						else {
-							$reading = 0;
-						}
-						$lformat = "%-30s%8d %s";
-					}
-					else {
-						$reading = "RAW(".$sdr->linearization.") $reading";
-					}
-	
-					if($sdr->sensor_units_1 & 1) {
-						$per = "% ";
-					} else {
-                  $per = " ";
-               }
-               my $numformat = ($sdr->sensor_units_1 & 0b11000000) >> 6;
-               if ($numformat) {
-                  if ($numformat eq 0b11)  {
-                     #Not sure what to do here..
-                  } else {
-                     if ($reading & 0b10000000) {
-                        if ($numformat eq 0b01) {
-                           $reading = 0-((~($reading&0b01111111))&0b1111111);
-                        } elsif ($numformat eq 0b10) {
-                           $reading = 0-(((~($reading&0b01111111))&0b1111111)+1);
-                        }
-                     }
-                  }
-               }
-	
-                    if($unitdesc eq "Watts") {
-                        my $f = ($reading * 3.413);
-                        $unitdesc = "Watts (".int($f+.5)." BTUs/hr)";
-                    }
-					if($unitdesc eq "C") {
-						my $f = ($reading * 9/5) + 32;
-						$unitdesc = "C (" . int($f + .5) . " F)";
-					}
-					if($unitdesc eq "F") {
-						my $c = ($reading - 32) * 5/9;
-						$unitdesc = "F (" . int($c + .5) . " C)";
-					}
-				}
-            #$unitdesc.= sprintf(" %x",$sdr->sensor_type);
-				$text = sprintf($lformat,$sdr->id_string . ":",$reading,$per.$unitdesc);
-				if ($extext) {
-					$text="$text ($extext)";
-				}
-				push(@output,$text);
-			}
-#			else {
-#				printf("%x %s %d\n",$sdr->sensor_number,$sdr->id_string,$sdr->sensor_type);
-#			}
-		}
-	}
-
-	if($sensor_filters{leds}) {
-		my @cleds;
-		($rc,@cleds) = checkleds();
-        push @output,@cleds;
-    }
-    if ($sensor_filters{powerstate}) {
-		($rc,$text) = power("stat");
-		$text = sprintf($format,"Power Status:",$text,"");
-		push(@output,$text);
-    }
-    if ($sensor_filters{energy}) {
-        my @energies;
-        ($rc,@energies)=readenergy();
-        push @output,@energies;
-	}
-
-	return($rc,@output);
-}
-
-sub readsensor {
-    my $sdr = shift;
-	my $sensor = $sdr->sensor_number;
-	my $netfun = 0x10;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-
-	@cmd = (0x2d,$sensor);
-
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-		return($rc,$text);
-	}
-
-	$code = $returnd[0];
-	if($code != 0x00) {
-		$rc = 1;
-		$text = $codes{$code};
-
-		if(!$text) {
-			$text = sprintf("unknown response %02x",$code);
-		}
-		chomp $text;
-
-		return($rc,$text);
-	}
-	
-	if ($returnd[2] & 0x20) {
-		$rc = 1;
-		$text = "N/A";
-		return($rc,$text);
-	}
-	$text = $returnd[1];
-    my $exdata1 = $returnd[3];
-    my $exdata2 = $returnd[3];
-    my $extext;
-    my @exparts;
-    if ($sdr->event_type_code == 0x1) {
-        if ($exdata1 & 1<<5) {
-            $extext = "At or above upper non-recoverable threshold";
-        } elsif ($exdata1 & 1<<4)  {
-            $extext = "At or above upper critical threshold";
-        } elsif ($exdata1 & 1<<3) {
-            $extext = "At or above upper non-critical threshold";
-        } 
-        if ($exdata1 & 1<<2) {
-            $extext = "At or below lower non-critical threshold";
-        } elsif ($exdata1 & 1<<1) {
-            $extext = "At or below lower critical threshold";
-        } elsif ($exdata1 & 1) {
-            $extext = "At or below lower non-recoverable threshold";
-        }
-    } elsif ($sdr->event_type_code == 0x6f) {
-        if ($sdr->sensor_type == 0x10) {
-	    @exparts=();
-            if ($exdata1 & 1<<4) {
-                push @exparts,"SEL full";
-            } elsif ($exdata1 & 1<<5) {
-                push @exparts,"SEL almost full";
-            }
-	    if ($exdata1 & 1) {
-	       push @exparts,"Correctable Memory Error Logging Disabled";
-	    } 
-	    if ($exdata1 & 1<<3) {
-	       push @exparts,"All logging disabled";
-	    } elsif ($exdata1 & 1<<1) {
-	       push @exparts,"Some logging disabled";
-	    }
-	    if (@exparts) {
-	       $extext = join(",",@exparts);
-	    }
-        } elsif ($sdr->sensor_type == 0x7) {
-	   @exparts=();
-	   if ($exdata1 & 1) {
-	      push @exparts,"IERR";
-	   }
-	   if ($exdata1 & 1<<1) {
-	      push @exparts,"Thermal trip";
-	   }
-	   if ($exdata1 & 1<<2) {
-	      push @exparts,"FRB1/BIST failure";
-	   }
-	   if ($exdata1 & 1<<3) {
-	      push @exparts,"FRB2/Hang in POST due to processor";
-	   }
-	   if ($exdata1 & 1<<4) {
-	      push @exparts,"FRB3/Processor Initialization failure";
-	   }
-	   if ($exdata1 & 1<<5) {
-	      push @exparts,"Configuration error";
-	   }
-	   if ($exdata1 & 1<<6) {
-	      push @exparts,"Uncorrectable CPU-complex error";
-	   }
-	   if ($exdata1 & 1<<7) {
-	      push @exparts,"Present";
-	   }
-	   if ($exdata1 & 1<<8) {
-	      push @exparts,"Processor disabled";
-	   }
-	   if ($exdata1 & 1<<9) {
-	      push @exparts,"Terminator present";
-	   }
-	   if ($exdata1 & 1<<10) {
-	      push @exparts,"Hardware throttled";
-	   }
-        } elsif ($sdr->sensor_type == 0x8) {
-	   @exparts=();
-	   if ($exdata1 & 1) {
-	        push @exparts,"Present";
-	   }
-	   if ($exdata1 & 1<<1) {
-	        push @exparts,"Failed";
-	   }
-	   if ($exdata1 & 1<<2) {
-	        push @exparts,"Failure predicted";
-	   }
-	   if ($exdata1 & 1<<3) {
-	        push @exparts,"AC Lost";
-	   }
-	   if ($exdata1 & 1<<4) {
-	        push @exparts,"AC input lost or out of range";
-	   }
-	   if ($exdata1 & 1<<5) {
-	        push @exparts,"AC input out of range";
-	   }
-	   if ($exdata1 & 1<<6) {
-	        push @exparts,"Configuration error";
-	   }
-	   if (@exparts) {
-	      $extext = join(",",@exparts);
-	   }
-        } elsif ($sdr->sensor_type == 0x13) {
-            @exparts=();
-            if ($exdata1 & 1) {
-                push @exparts,"Front panel NMI/Diagnostic";
-            }
-            if ($exdata1 & 1<<1) {
-                push @exparts,"Bus timeout";
-            }
-            if ($exdata1 & 1<<2) {
-                push @exparts,"I/O channel check NMI";
-            }
-            if ($exdata1 & 1<<3) {
-                push @exparts,"Software NMI";
-            }
-            if ($exdata1 & 1<<4) {
-                push @exparts,"PCI PERR";
-            }
-            if ($exdata1 & 1<<5) {
-                push @exparts,"PCI SERR";
-            }
-            if ($exdata1 & 1<<6) {
-                push @exparts,"EISA failsafe timeout";
-            }
-            if ($exdata1 & 1<<7) {
-                push @exparts,"Bus correctable .rror";
-            }
-            if ($exdata1 & 1<<8) {
-                push @exparts,"Bus uncorrectable error";
-            }
-            if ($exdata1 & 1<<9) {
-                push @exparts,"Fatal NMI";
-            }
-            if ($exdata1 & 1<<10) {
-                push @exparts,"Bus fatal error";
-            }
-            if (@exparts) {
-                $extext = join(",",@exparts);
-            }
-        } elsif ($sdr->sensor_type == 0xc) {
-            @exparts=();
-            if ($exdata1 & 1) {
-                push @exparts,"Correctable error(s)";
-            } 
-            if ($exdata1 & 1<<1) {
-                push @exparts,"Uncorrectable error(s)";
-            }
-            if ($exdata1 & 1<<2) {
-                push @exparts,"Parity";
-            }
-            if ($exdata1 & 1<<3) {
-                push @exparts,"Memory scrub failure";
-            }
-            if ($exdata1 & 1<<4) {
-                push @exparts,"DIMM disabled";
-            }
-            if ($exdata1 & 1<<5) {
-                push @exparts,"Correctable error limit reached";
-            }
-            if ($exdata1 & 1<<6) {
-                push @exparts,"Present";
-            }
-            if ($exdata1 & 1<<7) {
-                push @exparts,"Configuration error";
-            }
-            if ($exdata1 & 1<<8) {
-                push @exparts,"Spare";
-            }
-            if (@exparts) {
-                $extext = join(",",@exparts);
-            }
-        } elsif ($sdr->sensor_type == 0x21) {
-            @exparts=();
-            if ($exdata1 & 1) {
-                push @exparts,"Fault";
-            }
-            if ($exdata1 & 1<<1) {
-                push @exparts,"Identify";
-            }
-            if ($exdata1 & 1<<2) {
-                push @exparts,"Installed/attached";
-            }
-            if ($exdata1 & 1<<3) {
-                push @exparts,"Ready for install";
-            }
-            if ($exdata1 & 1<<4) {
-                push @exparts,"Ready for removal";
-            }
-            if ($exdata1 & 1<<5) {
-                push @exparts,"Powered off";
-            }
-            if ($exdata1 & 1<<6) {
-                push @exparts,"Removal requested";
-            }
-            if ($exdata1 & 1<<7) {
-                push @exparts,"Interlocked";
-            }
-            if ($exdata1 & 1<<8) {
-                push @exparts,"Disabled";
-            }
-            if ($exdata1 & 1<<9) {
-                push @exparts,"Spare";
-            }
-        } elsif ($sdr->sensor_type == 0xf) {
-            @exparts=();
-            if ($exdata1 & 1) {
-                push @exparts,"POST error";
-            }
-            if ($exdata1 & 1<<1) {
-                push @exparts,"Firmware hang";
-            }
-            if ($exdata1 & 1<<2) {
-                push @exparts,"Firmware progress";
-            }
-            if (@exparts) {
-                $extext = join(",",@exparts);
-            }
-        } elsif ($sdr->sensor_type == 0x9) {
-	   @exparts=();
-	   if ($exdata1 & 1) {
-	      push @exparts,"Power off";
-	   }
-	   if ($exdata1 & 1<<1) {
-	      push @exparts,"Power off";
-	   }
-	   if ($exdata1 & 1<<2) {
-	      push @exparts,"240VA Power Down";
-	   }
-	   if ($exdata1 & 1<<3) {
-	      push @exparts,"Interlock Power Down";
-	   }
-	   if ($exdata1 & 1<<4) {
-	      push @exparts,"AC lost";
-	   }
-	   if ($exdata1 & 1<<5) {
-	      push @exparts,"Soft power control failure";
-	   }
-	   if ($exdata1 & 1<<6) {
-	      push @exparts,"Power unit failure";
-	   }
-	   if ($exdata1 & 1<<7) {
-	      push @exparts,"Power unit failure predicted";
-	   }
-	   if (@exparts) {
-	      $extext = join(",",@exparts);
-	   }
-        } else {
-            $extext = "xCAT needs to add support for ".$sdr->sensor_type;
-        }
-    }
-
-	return($rc,$text,$extext);
-}
-
-sub initsdr {
-	my $netfun;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-
-	my $sdr_rep_info = SDR_rep_info->new();
-
-	my $resv_id_ls;
-	my $resv_id_ms;
-	my $nrid_ls = 0;
-	my $nrid_ms = 0;
-	my $rid_ls = 0;
-	my $rid_ms = 0;
-	my $sdr_ver;
-	my $sdr_type;
-	my $sdr_offset;
-	my $sdr_len;
-	my @sdr_data = ();
-	my $offset;
-	my $len;
-	my $i;
-#	my $numbytes = 27;
-	my $numbytes = 22;
-	my $override_string;
-	my $ipmisensortab = "$ENV{XCATROOT}/lib/GUMI/ipmisensor.tab";
-	my $byte_format;
-	my $cache_file;
-
-	my $mfg_id;
-	my $prod_id;
-	my $device_id;
-	my $dev_rev;
-	my $fw_rev1;
-	my $fw_rev2;
-
-	($rc,$text,$mfg_id,$prod_id,$device_id,$dev_rev,$fw_rev1,$fw_rev2) = getdevid();
-	if($rc != 0) {
-		return($rc,$text);
-	}
-
-	$cache_file = "$cache_dir/sdr_$mfg_id.$prod_id.$device_id.$dev_rev.$fw_rev1.$fw_rev2.$cache_version";
-	if($enable_cache eq "yes") {
-		$rc = loadsdrcache($cache_file);
-		if($rc == 0) {
-			return($rc);
-		}
-		$rc = 0;
-	}
-
-	($rc,$text) = get_sdr_rep_info($sdr_rep_info);
-	if($rc != 0) {
-		return($rc,$text);
-	}
-
-	if($sdr_rep_info->version != 0x51) {
-		$rc = 1;
-		$text = "SDR version 51h support only.";
-		return($rc,$text);
-	}
-
-	if($sdr_rep_info->resv_sdr != 1) {
-		$rc = 1;
-		$text = "SDR reservation unsupported.";
-		return($rc,$text);
-	}
-
-	($rc,$text,$resv_id_ls,$resv_id_ms) = resv_sdr_repo();
-	if($rc != 0) {
-		return($rc,$text);
-	}
-
-	if($debug) {
-		print "mfg,prod,dev: $mfg_id, $prod_id, $device_id\n";
-		printf("SDR info: %02x %d %d\n",$sdr_rep_info->version,$sdr_rep_info->rec_count,$sdr_rep_info->resv_sdr);
-		print "resv_id: $resv_id_ls $resv_id_ms\n";
-	}
-
-	foreach(1..$sdr_rep_info->rec_count) {
-		$netfun = 0x28;
-		@cmd = (0x23,$resv_id_ls,$resv_id_ms,$nrid_ls,$nrid_ms,0,5);
-		$error = docmd(
-			$netfun,
-			\@cmd,
-			\@returnd
-		);
-
-		if($error) {
-			$rc = 1;
-			$text = $error;
-			return($rc,$text);
-		}
-
-		$code = $returnd[0];
-		if($code != 0x00) {
-			$rc = 1;
-			$text = $codes{$code};
-			if(!$text) {
-				$rc = 1;
-				$text = sprintf("unknown response %02x",$code);
-			}
-			return($rc,$text);
-		}
-###x336 hack
-		$rid_ls = $nrid_ls;
-		$rid_ms = $nrid_ms;
-###
-		$nrid_ls = $returnd[1];
-		$nrid_ms = $returnd[2];
-### correct IPMI code
-#		$rid_ls = $returnd[3];
-#		$rid_ms = $returnd[4];
-###
-		$sdr_ver = $returnd[5];
-		$sdr_type = $returnd[6];
-		$sdr_len = $returnd[7] + 5;
-
-		if($sdr_type == 0x01) {
-			$sdr_offset = 0;
-		}
-		elsif($sdr_type == 0x02) {
-			$sdr_offset = 16;
-		}
-		elsif($sdr_type == 0xC0) {
-			#LED descriptor, maybe
-		}
-		elsif($sdr_type == 0x11) { #FRU locator
-		}
-		elsif($sdr_type == 0x12) {
-			next;
-		}
-		else {
-			next;
-		}
-
-		@sdr_data = (0,0,0,$sdr_ver,$sdr_type,$sdr_len);
-		$offset = 5;
-		for($i=5;$i<$sdr_len;$i+=$numbytes) {
-			$len = $numbytes;
-			if($offset+$len > $sdr_len) {
-				$len = $sdr_len - $offset;
-			}
-
-			@cmd = (0x23,$resv_id_ls,$resv_id_ms,$rid_ls,$rid_ms,$offset,$len);
-			$error = docmd(
-				$netfun,
-				\@cmd,
-				\@returnd
-			);
-
-			if($error) {
-				$rc = 1;
-				$text = $error;
-				return($rc,$text);
-			}
-
-			$code = $returnd[0];
-			if($code != 0x00) {
-				$rc = 1;
-				$text = $codes{$code};
-				if(!$text) {
-					$rc = 1;
-					$text = sprintf("unknown response %02x",$code);
-				}
-				return($rc,$text);
-			}
-
-			@sdr_data = (@sdr_data,@returnd[3..@returnd-2]);
-
-			$offset += $len;
-		}
-		if($sdr_type == 0x11) { #FRU locator
-            my $sdr = decode_fru_locator(@sdr_data);
-            if ($sdr) {
-		        $sdr_hash{$sdr->sensor_owner_id . "." . $sdr->sensor_owner_lun . "." . $sdr->sensor_number} = $sdr;
-            }
-            next;
-        }
-
-		if($debug) {
-			hexadump(\@sdr_data);
-		}
-		if($sdr_type == 0x12) {
-			hexadump(\@sdr_data);
-			next;
-		}
-
-		my $sdr = SDR->new();
-
-		if ($mfg_id == 2 && $sdr_type==0xC0 && $sdr_data[9] == 0xED) {
-			#printf("%02x%02x\n",$sdr_data[13],$sdr_data[12]);
-			$sdr->rec_type($sdr_type);
-			$sdr->sensor_type($sdr_data[9]);
-			#Using an impossible sensor number to not conflict with decodealert
-			$sdr->sensor_owner_id(260);
-			$sdr->sensor_owner_lun(260);
-            $sdr->id_string("LED");
-			if ($sdr_data[12] > $sdr_data[13]) {
-				$sdr->led_id(($sdr_data[13]<<8)+$sdr_data[12]);
-			} else {
-				$sdr->led_id(($sdr_data[12]<<8)+$sdr_data[13]);
-			}
-			#$sdr->led_id_ms($sdr_data[13]);
-			#$sdr->led_id_ls($sdr_data[12]);
-			$sdr->sensor_number(sprintf("%04x",$sdr->led_id));
-			#printf("%02x,%02x,%04x\n",$mfg_id,$prod_id,$sdr->led_id);	
-			#Was going to have a human readable name, but specs
-			#seem to not to match reality...
-			#$override_string = getsensorname($mfg_id,$prod_id,$sdr->sensor_number,$ipmiledtab);
-			#I'm hacking in owner and lun of 260 for LEDs....
-			$sdr_hash{"260.260.".$sdr->led_id} = $sdr;
-			next;
-		}
-
-
-		$sdr->rec_type($sdr_type);
-		$sdr->sensor_owner_id($sdr_data[6]);
-		$sdr->sensor_owner_lun($sdr_data[7]);
-		$sdr->sensor_number($sdr_data[8]);
-		$sdr->entity_id($sdr_data[9]);
-		$sdr->entity_instance($sdr_data[10]);
-		$sdr->sensor_type($sdr_data[13]);
-		$sdr->event_type_code($sdr_data[14]);
-		$sdr->sensor_units_2($sdr_data[22]);
-		$sdr->sensor_units_3($sdr_data[23]);
-
-		if($sdr_type == 0x01) {
-		   $sdr->sensor_units_1($sdr_data[21]);
-			$sdr->linearization($sdr_data[24] & 0b01111111);
-			$sdr->M(comp2int(10,(($sdr_data[26] & 0b11000000) << 2) + $sdr_data[25]));
-			$sdr->B(comp2int(10,(($sdr_data[28] & 0b11000000) << 2) + $sdr_data[27]));
-			$sdr->R_exp(comp2int(4,($sdr_data[30] & 0b11110000) >> 4));
-			$sdr->B_exp(comp2int(4,$sdr_data[30] & 0b00001111));
-		} elsif ($sdr_type == 0x02) {
-		   $sdr->sensor_units_1($sdr_data[21]);
-        }
-
-		$sdr->id_string_type($sdr_data[48-$sdr_offset]);
-
-		$override_string = getsensorname($mfg_id,$prod_id,$sdr->sensor_number,$ipmisensortab);
-
-		if($override_string ne "") {
-			$sdr->id_string($override_string);
-		}
-		else {
-            unless (defined $sdr->id_string_type) { next; }
-			$byte_format = ($sdr->id_string_type & 0b11000000) >> 6;
-			if($byte_format == 0b11) {
-				my $len = ($sdr->id_string_type & 0b00011111) - 1;
-				if($len > 1) {
-					$sdr->id_string(pack("C*",@sdr_data[49-$sdr_offset..49-$sdr_offset+$len]));
-				}
-				else {
-					$sdr->id_string("no description");
-				}
-			}
-			elsif($byte_format == 0b10) {
-				$sdr->id_string("ASCII packed unsupported");
-			}
-			elsif($byte_format == 0b01) {
-				$sdr->id_string("BCD unsupported");
-			}
-			elsif($byte_format == 0b00) {
-                my $len = ($sdr->id_string_type & 0b00011111) - 1;
-                if ($len > 1) { #It should be something, but need sample to code
-				    $sdr->id_string("unicode unsupported");
-                } else {
-                    next;
-                }
-			}
-		}
-
-		$sdr_hash{$sdr->sensor_owner_id . "." . $sdr->sensor_owner_lun . "." . $sdr->sensor_number} = $sdr;
-	}
-
-	if($debug) {
-		my $key;
-#		foreach $key (sort {$sdr_hash{$a}->sensor_number <=> $sdr_hash{$b}->sensor_number} keys %sdr_hash) {
-		foreach $key (sort {$sdr_hash{$a}->id_string cmp $sdr_hash{$b}->id_string} keys %sdr_hash) {
-			my $sdr = $sdr_hash{$key};
-#			printf("%d %x %s\n",$sdr->rec_type,$sdr->sensor_number,$sdr->id_string);
-#			printf("%x %x %x %s\n",$sdr->sensor_owner_id,$sdr->sensor_owner_lun,$sdr->sensor_number,$sdr->id_string);
-			printf("%x %x %x %s %d\n",$sdr->sensor_owner_id,$sdr->sensor_owner_lun,$sdr->sensor_number,$sdr->id_string,$sdr->linearization);
-		}
-#		printf("\n%x %s\n",$sdr_hash{0x70}->sensor_number,$sdr_hash{0x70}->id_string);
-	}
-
-	if($enable_cache eq "yes") {
-		storsdrcache($cache_file);
-	}
-
-	return($rc,$text);
-}
-
-sub getsensorname
-{
-	my $mfgid = shift;
-	my $prodid = shift;
-	my $sensor = shift;
-	my $file = shift;
-
-	my $mfg;
-	my $prod;
-	my $type;
-	my $num;
-	my $desc;
-	my $name="";
-
-    if ($file eq "ibmleds") {
-            if ($xCAT::data::ibmleds::leds{"$mfgid,$prodid"}->{$sensor}) {
-              return $xCAT::data::ibmleds::leds{"$mfgid,$prodid"}->{$sensor}. " LED";
-            } elsif ($ndebug) {
-              return "Unknown $sensor/$mfgid/$prodid";
-            } else {
-              return sprintf ("LED 0x%x",$sensor);
-            }
-    } else {
-      return "";
-    }
-}
-
-sub getchassiscap {
-	my $netfun = 0x00;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-
-	@cmd = (0x00);
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-		return($rc,$text);
-	}
-
-	$code = $returnd[0];
-	if($code == 0x00) {
-		$text = "";
-	}
-	else {
-		$rc = 1;
-		$text = $codes{$code};
-		if(!$text) {
-			$rc = 1;
-			$text = sprintf("unknown response %02x",$code);
-		}
-		return($rc,$text);
-	}
-
-	return($rc,@returnd[1..@returnd-2]);
-}
-
-sub getdevid {
-	my $netfun = 0x18;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-
-	@cmd = (0x01);
-
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-		return($rc,$text);
-	}
-	else {
-		$code = $returnd[0];
-
-		if($code == 0x00) {
-			$text = "";
-		}
-		else {
-			$rc = 1;
-			$text = $codes{$code};
-			if(!$text) {
-				$rc = 1;
-				$text = sprintf("unknown response %02x",$code);
-			}
-			return($rc,$text);
-		}
-	}
-
-	my $device_id = $returnd[1];
-	my $device_rev = $returnd[2] & 0b00001111;
-	my $firmware_rev1 = $returnd[3] & 0b01111111;
-	my $firmware_rev2 = $returnd[4];
-	my $ipmi_ver = $returnd[5];
-	my $dev_support = $returnd[6];
-	my $sensor_device = 0;
-	my $SDR = 0;
-	my $SEL = 0;
-	my $FRU = 0;
-	my $IPMB_ER = 0;
-	my $IPMB_EG = 0;
-	my $BD = 0;
-	my $CD = 0;
-	if($dev_support & 0b00000001) {
-		$sensor_device = 1;
-	}
-	if($dev_support & 0b00000010) {
-		$SDR = 1;
-	}
-	if($dev_support & 0b00000100) {
-		$SEL = 1;
-	}
-	if($dev_support & 0b00001000) {
-		$FRU = 1;
-	}
-	if($dev_support & 0b00010000) {
-		$IPMB_ER = 1;
-	}
-	if($dev_support & 0b00100000) {
-		$IPMB_EG = 1;
-	}
-	if($dev_support & 0b01000000) {
-		$BD = 1;
-	}
-	if($dev_support & 0b10000000) {
-		$CD = 1;
-	}
-	my $mfg_id = $returnd[7] + $returnd[8]*0x100 +  $returnd[9]*0x10000;
-	my $prod_id = $returnd[10] + $returnd[11]*0x100;
-	my @data = @returnd[12..@returnd-2];
-
-	return($rc,$text,$mfg_id,$prod_id,$device_id,$device_rev,$firmware_rev1,$firmware_rev2);
-}
-
-sub getguid {
-	my $guidcmd = shift;
-	my $netfun = @$guidcmd[0] || 0x18;
-	my @cmd = @$guidcmd[1] || 0x37;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-		return($rc,$text);
-	}
-	else {
-		$code = $returnd[0];
-
-		if($code == 0x00) {
-			$text = "";
-		}
-		else {
-			$rc = 1;
-			$text = $codes{$code};
-			if(!$text) {
-				$rc = 1;
-				$text = sprintf("unknown response %02x",$code);
-			}
-			return($rc,$text);
-		}
-	}
-
-	my @guid = @returnd[1..16];
-	my $guidtext = sprintf("%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",@guid);
-	$guidtext =~ tr/[a-z]/[A-Z]/;
-
-	return($rc,$text,$guidtext);
-}
-
-sub get_sdr_rep_info {
-	my $sdr_rep_info = shift;
-
-	my $netfun = 0x28;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-
-	@cmd = (0x20);
-
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-		return($rc,$text);
-	}
-	else {
-		$code = $returnd[0];
-
-		if($code == 0x00) {
-			$text = "";
-		}
-		else {
-			$rc = 1;
-			$text = $codes{$code};
-			if(!$text) {
-				$rc = 1;
-				$text = sprintf("unknown response %02x",$code);
-			}
-			return($rc,$text);
-		}
-	}
-
-	$sdr_rep_info->version($returnd[1]);
-	$sdr_rep_info->rec_count($returnd[2] + $returnd[3]*0x100);
-	$sdr_rep_info->resv_sdr(($returnd[14] & 0b00000010) ? 1 : 0);
-
-	return($rc,$text);
-}
-
-sub resv_sdr_repo {
-	my $netfun = 0x28;
-	my @cmd;
-	my @returnd = ();
-	my $error;
-	my $rc = 0;
-	my $text;
-	my $code;
-
-	@cmd = (0x22);
-
-	$error = docmd(
-		$netfun,
-		\@cmd,
-		\@returnd
-	);
-
-	if($error) {
-		$rc = 1;
-		$text = $error;
-		return($rc,$text);
-	}
-	else {
-		$code = $returnd[0];
-
-		if($code == 0x00) {
-			$text = "";
-		}
-		else {
-			$rc = 1;
-			$text = $codes{$code};
-			if(!$text) {
-				$rc = 1;
-				$text = sprintf("unknown response %02x",$code);
-			}
-			return($rc,$text);
-		}
-	}
-
-	my $resv_id_ls = $returnd[1];
-	my $resv_id_ms = $returnd[2];
-
-	return($rc,$text,$resv_id_ls,$resv_id_ms);
-}
-
-sub docmd {
-	my $netfun = shift;
-	my $cmd = shift;
-	my $response = shift;
-
-	my @rn;
-	my $length;
-
-	my @msg;
-	my @message;
-	my $error = "";
-	my @response;
-	my @data;
-
-	incseqlun();
-
-	@data = ($rqsa,$seqlun,@$cmd);
-	@rn = ($rssa,$netfun);
-	$length = (scalar @data)+4;
-	@message = ($rssa,$netfun,dochksum(\@rn),@data,dochksum(\@data));
-
-	incseqnum();
-
-	@msg = (
-		@rmcp,
-		$auth,
-		@seqnum,
-		@session_id,
-		authcode(2,\@message),
-		$length,
-		@message
-	);
-
-	($error,@$response) = domsg($sock,\@msg,$timeout,1);
-    splice @$response,0,36-$authoffset;
-
-	return($error);
-}
-
-sub getchanauthcap {
-    my $sessdata = shift;
-	$auth = 0x00;
-	my $netfun = 0x18;
-	my @data;
-	my @rn;
-	my $length;
-
-	my @msg;
-	my $error = "";
-	my @response;
-	my $code;
-
-	@data = ($rqsa,$seqlun,0x38,0x8e,0x04);
-	@rn = ($rssa,$netfun);
-	$length = (scalar @data)+4;
-	
-	@msg = (
-		@rmcp,
-		$auth,
-		@seqnum,
-		@session_id,
-		$length,
-		$rssa,
-		$netfun,
-		dochksum(\@rn),
-		@data,
-		dochksum(\@data)
-	);
-
-	($error,@response) = domsg($sock,\@msg,$timeout,0);
-
-	if($error) {
-		return($error);
-	}
-
-	$code = $response[20];
-    if ($code == 0xcc) {
-        #Despite the fact that the IPMI 1.5 spec declared the high bits to be
-        #reserved, some 1.5 BMCs checked the value anyway (erroneously)
-        #This retries with the IPMI 2.0 bit cleared
-    	@data = ($rqsa,$seqlun,0x38,0x0e,0x04);
-    	@rn = ($rssa,$netfun);
-    	$length = (scalar @data)+4;
-    	
-    	@msg = (
-    		@rmcp,
-    		$auth,
-    		@seqnum,
-    		@session_id,
-    		$length,
-    		$rssa,
-    		$netfun,
-    		dochksum(\@rn),
-    		@data,
-    		dochksum(\@data)
-    	);
-
-    	($error,@response) = domsg($sock,\@msg,$timeout,0);
-    
-    	if($error) {
-    		return($error);
-    	}
-    	$code = $response[20];
-    }
-	if($code != 0x00) {
-		$error = $codes{$code};
-		if(!$error) {
-			$error = "Unknown get channel authentication capabilities error $code"
-		}
-		return($error);
-	}
-
-	$channel_number=$response[21];
-
-	if($response[22] & 0b10000000 and $response[24] & 0b00000010) {
-		$ipmiv2=1;
-        $sessdata->{ipmi_version} = '2.0'; #currently could be a number, but it could devolve
-	}
-	if($response[22] & 0b00000100) {
-		$auth=0x02;
-	}
-	elsif($response[22] & 0b00010000) {
-		$auth=0x04;
-	}
-	else {
-		$error = "unsupported Authentication Type Support";
-	}
-
-	return($error);
-}
-
-sub getsessionchallenge {
-	my $tauth = 0x00;
-	my $netfun = 0x18;
-	my @data;
-	my @rn;
-	my $length;
-
-	my @msg;
-	my $error = "";
-	my @response;
-	my $code;
-
-	incseqlun();
-
-	@data = ($rqsa,$seqlun,0x39,$auth,@user);
-	@rn = ($rssa,$netfun);
-	$length = (scalar @data)+4;
-	
-	@msg = (
-		@rmcp,
-		$tauth,
-		@seqnum,
-		@session_id,
-		$length,
-		$rssa,
-		$netfun,
-		dochksum(\@rn),
-		@data,
-		dochksum(\@data)
-	);
-
-	($error,@response) = domsg($sock,\@msg,$timeout,0);
-
-	if(!$error) {
-		$code = $response[20];
-		if($code != 0x00) {
-			$error = $codes{$code};
-			if(!$error) {
-				$error = "Unknown get session challenge error $code"
-			}
-		}
-
-		if($code == 0x81) {
-			$error = "Invalid user name";
-		}
-		elsif($code == 0x82) {
-			$error = "null user name not enabled";
-		}
-
-		@session_id = @response[21,22,23,24];
-
-    	for (my $i=0;$i<16;$i++){
-			$challenge[$i] = $response[25+$i];
-    	}
-	}
-
-	return($error);
-}
-
-sub activatesession {
-	my $netfun = 0x18;
-	my @data;
-	my @rn;
-	my $length;
-
-	my @msg;
-	my @message;
-	my $error = "";
-	my @response;
-	my $code;
-
-	incseqlun();
-
-	@data = ($rqsa,$seqlun,0x3A,$auth,0x04,@challenge,0x01,0x00,0x00,0x00);
-	@rn = ($rssa,$netfun);
-	$length = (scalar @data)+4;
-	@message = ($rssa,$netfun,dochksum(\@rn),@data,dochksum(\@data));
-
-	@msg = (
-		@rmcp,
-		$auth,
-		@seqnum,
-		@session_id,
-		authcode(2,\@message),
-		$length,
-		@message
-	);
-
-	($error,@response) = domsg($sock,\@msg,$timeout,0);
-
-	if(!$error) {
-		$code = $response[36];
-		if($code != 0x00) {
-			$error = $codes{$code};
-			if(!$error) {
-				$error = "Unknown activate session error $code"
-			}
-		}
-
-		if($code == 0x81) {
-			$error = "No session slot available";
-		}
-		elsif($code == 0x82) {
-			$error = "No slot available for given user";
-		}
-		elsif($code == 0x83) {
-			$error = "No slot available to support user due to maximum privilege capability";
-		}
-		elsif($code == 0x84) {
-			$error = "Session sequence number out-of-range";
-		}
-		elsif($code == 0x85) {
-			$error = "Invalid session ID in request";
-		}
-		elsif($code == 0x86) {
-			$error = "Requested maximum privilege level exceeds user and/of channel privilege limit";
-		}
-
-        unless ($error) {
-    		$auth = $response[37];
-    		if($auth == 0x00) {
-    			$authoffset=16;
-    		}
-    		elsif($auth == 0x02) {
-    		}
-    		elsif($auth == 0x04) {
-    		}
-    		else {
-    			$error = "activate session requested unsupported Authentication Type Support";
-    		}
-        }
-
-###check
-		@session_id = @response[38,39,40,41];
-		@seqnum = @response[42,43,44,45];
-	}
-
-	return($error);
-}
-
-sub setprivlevel()
-{
-	my $netfun = 0x18;
-	my @data;
-	my @rn;
-	my $length;
-
-	my @msg;
-	my @message;
-	my $error = "";
-	my @response;
-	my $code;
-
-	incseqlun();
-
-	@data = ($rqsa,$seqlun,0x3B,0x04);
-	@rn = ($rssa,$netfun);
-	$length = (scalar @data)+4;
-	@message = ($rssa,$netfun,dochksum(\@rn),@data,dochksum(\@data));
-
-	@msg = (
-		@rmcp,
-		$auth,
-		@seqnum,
-		@session_id,
-		authcode(2,\@message),
-		$length,
-		@message
-	);
-
-	($error,@response) = domsg($sock,\@msg,$timeout,1);
-
-	if(!$error) {
-		$code = $response[36-$authoffset];
-		if($code != 0x00) {
-			$error = $codes{$code};
-			if(!$error) {
-				$error = "Unknown set session privilege level error $code"
-			}
-		}
-
-		if($code == 0x80) {
-			$error = "Requested level not available for this user";
-		}
-		elsif($code == 0x81) {
-			$error = "Requested level exceeds channel and/or user privilege limit";
-		}
-		elsif($code == 0x82) {
-			$error = "Cannot disable user level authentication";
-		}
-	}
-
-	return($error);
-}
-
-sub closesession()
-{
-	incseqnum();
-
-	my $netfun = 0x18;
-	my @data;
-	my @rn;
-	my $length;
-
-	my @msg;
-	my @message;
-	my $error = "";
-	my @response;
-	my $code;
-
-	incseqlun();
-
-	@data = ($rqsa,$seqlun,0x3C,@session_id);
-	@rn = ($rssa,$netfun);
-	$length = (scalar @data)+4;
-	@message = ($rssa,$netfun,dochksum(\@rn),@data,dochksum(\@data));
-
-	@msg = (
-		@rmcp,
-		$auth,
-		@seqnum,
-		@session_id,
-		authcode(2,\@message),
-		$length,
-		@message
-	);
-
-	($error,@response) = domsg($sock,\@msg,$timeout,1);
-
-	if(!$error) {
-		$code = $response[36-$authoffset];
-		if($code != 0x00) {
-			$error = $codes{$code};
-			if(!$error) {
-				$error = "Unknown close session error $code"
-			}
-		}
-
-		if($code == 0x87) {
-			$error = "Invalid session ID in request";
-		}
-	}
-
-	return($error);
-}
-
-sub domsg {
-	my $sock = shift;
-	my $msg = shift;
-	my $timeout = shift;
-	my $seq = shift || 0;
-	my $debug = $localdebug;
-	my $trys = $localtrys;
-	my $send;
-	my $quit = 0;
-	my $error="";
-	my $recv;
-	my @response;
-	my $timedout;
-	my @foo;
-	my @message;
-
-	$send = pack('C*',@$msg);
-
-	while($trys > 0) {
-		$trys--;
-		$error = "";
-		$timedout = 0;
-
-		if($debug) {
-			print "try: $trys, timeout: $timeout\n";
-		}
-
-		if(!$sock->send($send)) {
-			$error = $!;
-			sleep(1);
-			next;
-		}
-		my $s = IO::Select->new($sock);
-		#local $SIG{ALRM} = sub { $timedout = 1 and die };
-		#alarm($timeout);
-		my $received = $s->can_read($timeout);
-		if($received and $received > 0) {
-			if ($sock->recv($recv,1300)) {
-				if($recv) {
-					@response = unpack("C*",$recv);
-					last;
-				}
-			} else {
-				$error = $!;
-			}
-		}
-		else {
-			$error = "timeout";
-		}
-
-###ugly updated hack to support md5.
-		if($seq) {
-			incseqnum();
-
-			@$msg[5..8] = @seqnum[0..3];
-			@message = @$msg[30..@$msg-1];
-			if($auth != 0x00) {
-				@$msg[13..28] = authcode(2,\@message);
-			}
-
-			$send = pack('C*',@$msg);
-		}
-	}
-
-	if($timedout == 1) {
-		if($error) {
-			$error = "timeout $error"
-		}
-		else {
-			$error = "timeout"
-		}
-	}
-
-	return($error,@response);
-}
-
-sub dochksum()
-{
-	my $data = shift;
-	my $sum = 0;
-
-	foreach(@$data) {
-		$sum += $_;
-	}
-
-	$sum = ~$sum + 1;
-	return($sum & 0xFF);
-}
-
-sub dopad16 {
-	my @pad16 = unpack("C*",shift);	
-
-	for(my $i=@pad16;$i<16;$i++) {
-		$pad16[$i] = 0;
-	}
-
-	return(@pad16);
-}
-
-sub hexdump {
-	my $data = shift;
-
-	foreach(@$data) {
-		printf("%02x ",$_);
-	}
-	print "\n";
-}
-
-sub getascii {
-        my @alpha;
-        my $text ="";
-        my $c = 0;
-
-        foreach(@_) {
-                if (defined $_ and $_ < 128 and $_ > 0x20) {
-                    $alpha[$c] = sprintf("%c",$_);
-                } else {
-                    $alpha[$c]=" ";
-                }
-                if($alpha[$c] !~ /[\/\w\-:\[\.\]]/) {
-        			if ($alpha[($c-1)] !~ /\s/) {
-                    	    $alpha[$c] = " ";
-	          		} else {
-			        	$c--;
-			        }
-                }
-                $c++;
-        }
-        foreach(@alpha) {
-                $text=$text.$_;
-        }
-	$text =~ s/^\s+|\s+$//;
-	return $text;
-}
-sub phex {
-        my $data = shift;
-        my @alpha;
-        my $text ="";
-        my $c = 0;
-
-        foreach(@$data) {
-                $text = $text . sprintf("%02x ",$_);
-                $alpha[$c] = sprintf("%c",$_);
-                if($alpha[$c] !~ /\w/) {
-                        $alpha[$c] = " ";
-                }
-                $c++;
-        }
-        $text = $text . "(";
-        foreach(@alpha) {
-                $text=$text.$_;
-        }
-        $text = $text . ")";
-        return $text;
-}
-
-sub hexadump {
-	my $data = shift;
-	my @alpha;
-	my $c = 0;
-
-	foreach(@$data) {
-		printf("%02x ",$_);
-		$alpha[$c] = sprintf("%c",$_);
-		if($alpha[$c] !~ /\w/) {
-			$alpha[$c] = ".";
-		}
-		$c++;
-		if($c == 16) {
-			print "   ";
-			foreach(@alpha) {
-				print $_;
-			}
-			print "\n";
-			@alpha=();
-			$c=0;
-		}
-	}
-	foreach($c..16) {
-		print "   ";
-	}
-	foreach(@alpha) {
-		print $_;
-	}
-	print "\n";
-}
-
-sub incseqnum {
-	my $i;
-
-	for($i = 0;$i < 4;$i++) {
-		if($seqnum[$i] < 0xFF) {
-			$seqnum[$i]++;
-			last;
-		}
-		$seqnum[$i] = 0;
-	}
-
-	if($seqnum[3] > 0xFF) {
-		@seqnum = (0,0,0,0);
-	}
-}
-
-sub incseqlun {
-	$seqlun += 4;
-
-	if($seqlun > 0xFF) {
-		$seqlun = 0;
-	}
-}
-
-sub authcode {
-	my $type = shift;
-	my $message = shift;
-	my @authcode;
-
-	if($auth == 0x02) {
-		if($type == 1) {
-			@authcode = unpack("C*",md5(pack("C*",@pass,@session_id,@challenge,@pass)));
-		}
-		elsif($type == 2) {
-			@authcode = unpack("C*",md5(pack("C*",@pass,@session_id,@$message,@seqnum,@pass)));
-		}
-	}
-	elsif($auth == 0x04) {
-		@authcode = @pass;
-	}
-	elsif($auth == 0x00) {
-		@authcode = ();
-	}
-
-	return(@authcode);
-}
-
-sub comp2int {
-	my $length = shift;
-	my $bits = shift;
-	my $neg = 0;
-
-	if($bits & 2**($length - 1)) {
-		$neg = 1;
-	}
-
-	$bits &= (2**($length - 1) - 1);
-
-	if($neg) {
-		$bits -= 2**($length - 1);
-	}
-
-	return($bits);
-}
-
-sub timestamp2datetime {
-	my $ts = shift;
-   if ($ts < 0x20000000) {
-      return "BMC Uptime",sprintf("%6d s",$ts);
-   }
-	my @t = localtime($ts);
-	my $time = strftime("%H:%M:%S",@t);
-	my $date = strftime("%m/%d/%Y",@t);
-
-	return($date,$time);
-}
-
-sub decodebcd {
-	my $numbers = shift;
-	my @bcd;
-	my $text;
-	my $ms;
-	my $ls;
-
-	foreach(@$numbers) {
-		$ms = ($_ & 0b11110000) >> 4;
-		$ls = ($_ & 0b00001111);
-		push(@bcd,$ms);
-		push(@bcd,$ls);
-	}
-
-	foreach(@bcd) {
-		if($_ < 0x0a) {
-			$text .= $_;
-		}
-		elsif($_ == 0x0a) {
-			$text .= " ";
-		}
-		elsif($_ == 0x0b) {
-			$text .= "-";
-		}
-		elsif($_ == 0x0c) {
-			$text .= ".";
-		}
-	}
-
-	return($text);
-}
-
-sub storsdrcache {
-	my $file = shift;
-	my $key;
-	my $fh;
-
-	system("mkdir -p $cache_dir");
-	if(!open($fh,">$file")) {
-		return(1);
-	}
-
-	flock($fh,LOCK_EX) || return(1);
-
-	foreach $key (keys %sdr_hash) {
-		my $r = $sdr_hash{$key};
-		store_fd($r,$fh);
-	}
-
-	close($fh);
-
-	return(0);
-}
-
-sub loadsdrcache {
-	my $file = shift;
-	my $r;
-	my $c=0;
-	my $fh;
-
-	if(!open($fh,"<$file")) {
-		return(1);
-	}
-
-	flock($fh,LOCK_SH) || return(1);
-
-	while() {
-		eval {
-			$r = retrieve_fd($fh);
-		} || last;
-
-		$sdr_hash{$r->sensor_owner_id . "." . $r->sensor_owner_lun . "." . $r->sensor_number} = $r;
-	}
-
-	close($fh);
-
-	return(0);
-}
-
-
-sub preprocess_request { 
-  my $request = shift;
-  if ($request->{_xcatpreprocessed}->[0] == 1) { return [$request]; }
-  #exit if preprocessed
-  my $callback=shift;
-  my @requests;
-
-  my $noderange = $request->{node}; #Should be arrayref
-  my $command = $request->{command}->[0];
-  my $extrargs = $request->{arg};
-  my @exargs=($request->{arg});
-  if (ref($extrargs)) {
-    @exargs=@$extrargs;
-  }
-
-  my $usage_string=xCAT::Usage->parseCommand($command, @exargs);
-  if ($usage_string) {
-    $callback->({data=>$usage_string});
-    $request = {};
-    return;
-  }
-
-  if ($command eq "rpower") {
-      my $subcmd=$exargs[0];
-			if($subcmd eq ''){
-	  		$callback->({data=>["Please enter an action (eg: boot,off,on, etc)",  $usage_string]});
-	  		$request = {};
-				return 0;
-
-			}
-      if ( ($subcmd ne 'stat') && ($subcmd ne 'state') && ($subcmd ne 'status') && ($subcmd ne 'on') && ($subcmd ne 'off') && ($subcmd ne 'softoff') && ($subcmd ne 'nmi')&& ($subcmd ne 'cycle') && ($subcmd ne 'reset') && ($subcmd ne 'boot')) {
-	  $callback->({data=>["Unsupported command: $command $subcmd", $usage_string]});
-	  $request = {};
-	  return;
-      }
-  }
-
-
-  if (!$noderange) {
-    $usage_string=xCAT::Usage->getUsage($command);
-    $callback->({data=>$usage_string});
-    $request = {};
-    return;
-  }   
-  
-  #print "noderange=@$noderange\n";
-
-  # find service nodes for requested nodes
-  # build an individual request for each service node
-  my $service  = "xcat";
-  my $sn = xCAT::Utils->get_ServiceNode($noderange, $service, "MN");
-
-  # build each request for each service node
-
-  foreach my $snkey (keys %$sn)
-  {
-    #print "snkey=$snkey\n";
-    my $reqcopy = {%$request};
-    $reqcopy->{node} = $sn->{$snkey};
-    $reqcopy->{'_xcatdest'} = $snkey;
-    $reqcopy->{_xcatpreprocessed}->[0] = 1;
-    push @requests, $reqcopy;
-  }
-  return \@requests;
-}
-    
-     
-sub getipmicons {
-    my $argr=shift;
-    #$argr is [$node,$nodeip,$nodeuser,$nodepass];
-    my $cb = shift;
-    my $ipmicons={node=>[{name=>[$argr->[0]]}]};
-    $ipmicons->{node}->[0]->{bmcaddr}->[0]=$argr->[1];
-    $ipmicons->{node}->[0]->{bmcuser}->[0]=$argr->[2];
-    $ipmicons->{node}->[0]->{bmcpass}->[0]=$argr->[3];
-    $cb->($ipmicons);
-}
-
-
-
-   
-sub process_request {
-  my $request = shift;
-  my $callback = shift;
-  my $noderange = $request->{node}; #Should be arrayref
-  my $command = $request->{command}->[0];
-  my $extrargs = $request->{arg};
-  my @exargs=($request->{arg});
-  if (ref($extrargs)) {
-    @exargs=@$extrargs;
-  }
-	my $ipmiuser = 'USERID';
-	my $ipmipass = 'PASSW0RD';
-	my $ipmitrys = 3;
-	my $ipmitimeout = 2;
-	my $ipmimaxp = 64;
-	my $sitetab = xCAT::Table->new('site');
-	my $ipmitab = xCAT::Table->new('ipmi');
-	my $tmp;
-	if ($sitetab) {
-		($tmp)=$sitetab->getAttribs({'key'=>'ipmimaxp'},'value');
-		if (defined($tmp)) { $ipmimaxp=$tmp->{value}; }
-		($tmp)=$sitetab->getAttribs({'key'=>'ipmitimeout'},'value');
-		if (defined($tmp)) { $ipmitimeout=$tmp->{value}; }
-		($tmp)=$sitetab->getAttribs({'key'=>'ipmiretries'},'value');
-		if (defined($tmp)) { $ipmitrys=$tmp->{value}; }
-		($tmp)=$sitetab->getAttribs({'key'=>'ipmisdrcache'},'value');
-		if (defined($tmp)) { $enable_cache=$tmp->{value}; }
-	}
-	my $passtab = xCAT::Table->new('passwd');
-	if ($passtab) {
-		($tmp)=$passtab->getAttribs({'key'=>'ipmi'},'username','password');
-		if (defined($tmp)) { 
-			$ipmiuser = $tmp->{username};
-			$ipmipass = $tmp->{password};
-		}
-	}
-
-    #my @threads;
-    my @donargs=();
-    if ($request->{command}->[0] =~ /fru/) {
-        my $vpdtab = xCAT::Table->new('vpd');
-        $vpdhash = $vpdtab->getNodesAttribs($noderange,[qw(serial mtm asset)]);
-    }
-	my $ipmihash = $ipmitab->getNodesAttribs($noderange,['bmc','username','password']) ;
-	foreach(@$noderange) {
-		my $node=$_;
-		my $nodeuser=$ipmiuser;
-		my $nodepass=$ipmipass;
-		my $nodeip = $node;
-		my $ent;
-		if (defined($ipmitab)) {
-			$ent=$ipmihash->{$node}->[0];
-			if (ref($ent) and defined $ent->{bmc}) { $nodeip = $ent->{bmc}; }
-			if (ref($ent) and defined $ent->{username}) { $nodeuser = $ent->{username}; }
-			if (ref($ent) and defined $ent->{password}) { $nodepass = $ent->{password}; }
-		}
-        push @donargs,[$node,$nodeip,$nodeuser,$nodepass];
-    }
-    if ($request->{command}->[0] eq "getipmicons") {
-        foreach (@donargs) {
-            getipmicons($_,$callback);
-        }
-        return;
-    }
-
-  #get new node status
-  my %oldnodestatus=(); #saves the old node status
-  my @allerrornodes=();
-  my $check=0;
-  my $global_check=1;
-  if ($sitetab) {
-    (my $ref) = $sitetab->getAttribs({key => 'nodestatus'}, 'value');
-    if ($ref) {
-       if ($ref->{value} =~ /0|n|N/) { $global_check=0; }
-    }
-  }
-
-
-  if ($command eq 'rpower') {
-    if (($global_check) && ($extrargs->[0] ne 'stat') && ($extrargs->[0] ne 'status') && ($extrargs->[0] ne 'state')) { 
-      $check=1; 
-      my @allnodes=();
-      foreach (@donargs) { push(@allnodes, $_->[0]); }
-
-      #save the old status
-      my $nodelisttab = xCAT::Table->new('nodelist');
-      if ($nodelisttab) {
-        my $tabdata     = $nodelisttab->getNodesAttribs(\@allnodes, ['node', 'status']);
-        foreach my $node (@allnodes)
-        {
-            my $tmp1 = $tabdata->{$node}->[0];
-            if ($tmp1) { 
-		if ($tmp1->{status}) { $oldnodestatus{$node}=$tmp1->{status}; }
-		else { $oldnodestatus{$node}=""; }
-	    }
-	}
-      }
-      #print "oldstatus:" . Dumper(\%oldnodestatus);
-      
-      #set the new status to the nodelist.status
-      my %newnodestatus=(); 
-      my $newstat;
-      if (($extrargs->[0] eq 'off') || ($extrargs->[0] eq 'softoff')) { 
-	  my $newstat=$::STATUS_POWERING_OFF; 
-	  $newnodestatus{$newstat}=\@allnodes;
-      } else {
-        #get the current nodeset stat
-        if (@allnodes>0) {
-	  my $nsh={};
-          my ($ret, $msg)=xCAT::SvrUtils->getNodesetStates(\@allnodes, $nsh);
-          if (!$ret) { 
-            foreach (keys %$nsh) {
-		my $newstat=xCAT_monitoring::monitorctrl->getNodeStatusFromNodesetState($_, "rpower");
-		$newnodestatus{$newstat}=$nsh->{$_};
-	    }
-	  } else {
-	      $callback->({data=>$msg});
-	  }
-        }
-      }
-      #print "newstatus" . Dumper(\%newnodestatus);
-      xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%newnodestatus, 1);
-    }
-  }
-
-    my $children = 0;
-    $SIG{INT} = $SIG{TERM} = sub { #prepare to process job termination and propogate it down
-         foreach (keys %bmc_comm_pids) {
-            kill 2, $_;
-         }
-         exit 0;
-    };
-    $SIG{CHLD} = sub {my $kpid; do { $kpid = waitpid(-1, WNOHANG); if ($bmc_comm_pids{$kpid}) { delete $bmc_comm_pids{$kpid}; $children--; } } while $kpid > 0; };
-    my $sub_fds = new IO::Select;
-    foreach (@donargs) {
-      while ($children > $ipmimaxp) { 
-        my $handlednodes={};
-        forward_data($callback,$sub_fds,$handlednodes);
-        #update the node status to the nodelist.status table
-        if ($check) {
-          updateNodeStatus($handlednodes, \@allerrornodes);
-        }
-      }
-      $children++;
-      my $cfd;
-      my $pfd;
-      socketpair($pfd, $cfd,AF_UNIX,SOCK_STREAM,PF_UNSPEC) or die "socketpair: $!";
-      $cfd->autoflush(1);
-      $pfd->autoflush(1);
-      binmode($cfd,':utf8');
-      binmode($pfd,':utf8');
-      my $child = xCAT::Utils->xfork();
-      unless (defined $child) { die "Fork failed" };
-	if ($child == 0) { 
-        close($cfd);
-        my $rrc=donode($pfd,$_->[0],$_->[1],$_->[2],$_->[3],$ipmitimeout,$ipmitrys,$command,-args=>\@exargs);
-        close($pfd);
-	exit(0);
-      }
-      $bmc_comm_pids{$child}=1;
-      close ($pfd);
-      $sub_fds->add($cfd)
-	}
-    while ($sub_fds->count > 0 and $children > 0) {
-      my $handlednodes={};
-      forward_data($callback,$sub_fds,$handlednodes);
-      #update the node status to the nodelist.status table
-      if ($check) {
-        updateNodeStatus($handlednodes, \@allerrornodes);
-      }
-    }
-    
-    #Make sure they get drained, this probably is overkill but shouldn't hurt
-    my $rc=1;
-    while ( $rc>0 ) {
-      my $handlednodes={};
-      $rc=forward_data($callback,$sub_fds,$handlednodes);
-      #update the node status to the nodelist.status table
-      if ($check) {
-        updateNodeStatus($handlednodes, \@allerrornodes);
-      }
-    } 
-
-    if ($check) {
-        #print "allerrornodes=@allerrornodes\n";
-        #revert the status back for there is no-op for the nodes
-        my %old=(); 
-        foreach my $node (@allerrornodes) {
-	    my $stat=$oldnodestatus{$node};
-	    if (exists($old{$stat})) {
-		my $pa=$old{$stat};
-		push(@$pa, $node);
-	    }
-	    else {
-		$old{$stat}=[$node];
-	    }
-        } 
-        xCAT_monitoring::monitorctrl::setNodeStatusAttributes(\%old, 1);
-    }  
-}
-
-sub updateNodeStatus {
-  my $handlednodes=shift;
-  my $allerrornodes=shift;
-  foreach my $node (keys(%$handlednodes)) {
-    if ($handlednodes->{$node} == -1) { push(@$allerrornodes, $node); }  
-  }
-}
-
-
-
-sub forward_data { #unserialize data from pipe, chunk at a time, use magic to determine end of data structure
-  my $callback = shift;
-  my $fds = shift;
-  my $errornodes=shift;
-
-  my @ready_fds = $fds->can_read(1);
-  my $rfh;
-  my $rc = @ready_fds;
-  foreach $rfh (@ready_fds) {
-    my $data;
-    if ($data = <$rfh>) {
-      while ($data !~ /ENDOFFREEZE6sK4ci/) {
-        $data .= <$rfh>;
-      }
-      eval { print $rfh "ACK\n"; };  # Ignore ack loss to child that has given up and exited
-      my $responses=thaw($data);
-      foreach (@$responses) {
-        #save the nodes that has errors and the ones that has no-op for use by the node status monitoring
-        my $no_op=0;
-        if (exists($_->{node}->[0]->{errorcode})) { $no_op=1; }
-        else { 
-          my $text=$_->{node}->[0]->{data}->[0]->{contents}->[0];
-          #print "data:$text\n";
-          if (($text) && ($text =~ /$status_noop/)) {
-	    $no_op=1;
-            #remove the symbols that meant for use by node status
-            $_->{node}->[0]->{data}->[0]->{contents}->[0] =~ s/ $status_noop//; 
-          }
-        }  
-	#print "data:". $_->{node}->[0]->{data}->[0]->{contents}->[0] . "\n";
-        if ($no_op) {
-          if ($errornodes) { $errornodes->{$_->{node}->[0]->{name}->[0]}=-1; } 
-        } else {
-          if ($errornodes) { $errornodes->{$_->{node}->[0]->{name}->[0]}=1; } 
-        }
-        $callback->($_);
-      }
-    } else {
-      $fds->remove($rfh);
-      close($rfh);
-    }
-  }
-  yield; #Avoid useless loop iterations by giving children a chance to fill pipes
-  return $rc;
-}
-
-sub donode {
-  $outfd = shift;
-  my $node = shift;
-  $currnode=$node;
-  my $bmcip = shift;
-  my $user = shift;
-  my $pass = shift;
-  my $timeout = shift;
-  my $retries = shift;
-  my $command = shift;
-  $sessiondata{$node} = {
-      node => $node, #this seems redundant, but some code will not be privy to what the key was
-      bmc => $bmcip,
-      user => $user,
-      pass => $pass,
-  };
-  my %namedargs=@_;
-  my $transid = $namedargs{-transid};
-  my $extra=$namedargs{-args};
-  my @exargs=@$extra;
-  my ($rc,@output) = ipmicmd($bmcip,623,$user,$pass,$timeout,$retries,0,$sessiondata{$node},$command,@exargs);
-  my @outhashes;
-  sendoutput($rc,@output);
-  yield;
-  #my $msgtoparent=freeze(\@outhashes);
- # print $outfd $msgtoparent;
-  return $rc;
-}
-
-sub sendoutput {
-    my $rc=shift;
-    foreach (@_) {
-        my %output;
-        (my $desc,my $text) = split(/:/,$_,2);
-        unless ($text) {
-          $text=$desc;
-        } else {
-          $desc =~ s/^\s+//;
-          $desc =~ s/\s+$//;
-          if ($desc) {
-             $output{node}->[0]->{data}->[0]->{desc}->[0]=$desc;
-          }
-        }
-        $text =~ s/^\s+//;
-        $text =~ s/\s+$//;
-        $output{node}->[0]->{name}->[0]=$currnode;
-        if ($rc) {
-          $output{node}->[0]->{errorcode}=[$rc];
-            $output{node}->[0]->{error}->[0]=$text;
-        } else {
-            $output{node}->[0]->{data}->[0]->{contents}->[0]=$text;
-        }
-        #push @outhashes,\%output; #Save everything for the end, don't know how to be slicker with Storable and a pipe
-        print $outfd freeze([\%output]);
-        print $outfd "\nENDOFFREEZE6sK4ci\n";
-        yield;
-        waitforack($outfd);
-    }
-}
-
-1;