1#! /usr/bin/perl
2use strict;
3use warnings;
4
5use mrw::Targets;
6use mrw::Inventory;
7use Getopt::Long; # For parsing command line arguments
8use YAML::XS 'LoadFile'; # For loading and reading of YAML file
9
10# Globals
11my $serverwizFile  = "";
12my $debug           = 0;
13my $outputFile     = "";
14my $metaDataFile   = "";
15
16# Command line argument parsing
17GetOptions(
18"i=s" => \$serverwizFile,    # string
19"m=s" => \$metaDataFile,     # string
20"o=s" => \$outputFile,       # string
21"d"   => \$debug,
22)
23or printUsage();
24
25if (($serverwizFile eq "") or ($outputFile eq "") or ($metaDataFile eq ""))
26{
27    printUsage();
28}
29
30my $targetObj = Targets->new;
31$targetObj->loadXML($serverwizFile);
32
33#open the mrw xml and the metaData file for the fru.
34#Fetch the FRU id,type,object path from the mrw.
35#Get the metadata for that fru from the metadata file.
36#Merge the data into the outputfile
37
38open(my $fh, '>', $outputFile) or die "Could not open file '$outputFile' $!";
39my $fruTypeConfig = LoadFile($metaDataFile);
40
41my @interestedTypes = keys %{$fruTypeConfig};
42my %types;
43@types{@interestedTypes} = ();
44
45my @inventory = Inventory::getInventory($targetObj);
46for my $item (@inventory) {
47    my $isFru = 0, my $fruID = 0, my $fruType = "";
48    #Fetch the FRUID.
49    if (!$targetObj->isBadAttribute($item->{TARGET}, "FRU_ID")) {
50        $fruID = $targetObj->getAttribute($item->{TARGET}, "FRU_ID");
51        $isFru = 1;
52    }
53    #Fetch the FRU Type.
54    if (!$targetObj->isBadAttribute($item->{TARGET}, "TYPE")) {
55        $fruType = $targetObj->getAttribute($item->{TARGET}, "TYPE");
56    }
57
58    #Skip if we're not interested
59    next if (not $isFru or not exists $types{$fruType});
60
61    printDebug ("FRUID => $fruID, FRUType => $fruType, ObjectPath => $item->{OBMC_NAME}");
62
63    print $fh $fruID.":";
64    print $fh "\n";
65
66    writeToFile($fruType,$item->{OBMC_NAME},$fruTypeConfig,$fh);
67
68    # Fetch all the children for this inventory target,It might happen the child is fru or non fru
69    # Following condition to be true for fetching the associated non fru devices.
70    # -it should be non fru.
71    # -type of the fru is in the interested types.
72    # - the parent of the child should be same as inventory target.
73
74    foreach my $child ($targetObj->getAllTargetChildren($item->{TARGET})) {
75        $fruType = $targetObj->getAttribute($child, "TYPE");
76
77        if (!$targetObj->isBadAttribute($child, "FRU_ID")) {
78            #i.e this child is a fru,we are interrested in non fru devices
79            next;
80        }
81
82        #Fetch the Fru Type
83        if (!$targetObj->isBadAttribute($child, "TYPE")) {
84            $fruType = $targetObj->getAttribute($child, "TYPE");
85        }
86
87        # check whether this fru type is in interested fru types.
88        if (not exists $types{$fruType}) {
89            next;
90        }
91
92        # find the parent fru of this child.
93        my $parent = $targetObj->getTargetParent($child);
94        while ($parent ne ($item->{TARGET})) {
95            $parent = $targetObj->getTargetParent($parent);
96            if (!$targetObj->isBadAttribute($parent, "FRU_ID")) {
97                last;
98            }
99
100        }
101        #if parent of the child is not equal to the item->target
102        #i.e some other fru is parent of this child.
103        if ( $parent ne ($item->{TARGET}) ){
104            next;
105        }
106
107        printDebug("     ".$child);
108        printDebug("     Type:".$fruType );
109        my $childObmcName = getObmcName(\@inventory, $child);
110        writeToFile($fruType, $childObmcName, $fruTypeConfig, $fh);
111    }
112}
113close $fh;
114
115#------------------------------------END OF MAIN-----------------------
116
117# Map an MRW name to corresponding OBMC name
118sub getObmcName
119{
120    my $inventory = $_[0]; # Inventory items
121    my $target = $_[1]; # MRW Target name
122    for my $item (@inventory)
123    {
124        if($item->{TARGET} eq $target)
125        {
126            return $item->{OBMC_NAME};
127        }
128    }
129    return undef;
130}
131
132
133#Get the metdata for the incoming frutype from the loaded config file.
134#Write the FRU data into the output file
135
136sub writeToFile
137{
138    my $fruType = $_[0];#fru type
139    my $instancePath = $_[1];#instance Path
140    my $fruTypeConfig = $_[2];#loaded config file (frutypes)
141    my $fh = $_[3];#file Handle
142    #walk over all the fru types and match for the incoming type
143    print $fh "  ".$instancePath.":";
144    print $fh "\n";
145    my $interfaces = $fruTypeConfig->{$fruType};
146    #Walk over all the interfaces as it needs to be written
147    while ( my ($interface,$properties) = each %{$interfaces}) {
148        print $fh "    ".$interface.":";
149        print $fh "\n";
150        #walk over all the properties as it needs to be written
151        while ( my ($dbusProperty,$metadata) = each %{$properties}) {
152                    #will write property named "Property" first then
153                    #other properties.
154            print $fh "      ".$dbusProperty.":";
155            print $fh "\n";
156            for my $key (sort keys %{$metadata}) {
157                print $fh "        $key: "."$metadata->{$key}";
158                print $fh "\n";
159            }
160        }
161    }
162}
163
164# Usage
165sub printUsage
166{
167    print "
168    $0 -i [MRW filename] -m [MetaData filename] -o [Output filename] [OPTIONS]
169Options:
170    -d = debug mode
171        \n";
172    exit(1);
173}
174
175# Helper function to put debug statements.
176sub printDebug
177{
178    my $str = shift;
179    print "DEBUG: ", $str, "\n" if $debug;
180}
181