Add MFG Set FITc Layout command

FITc layout is used as the ROM ID for incremental PCH
image updates to enforce image layout compatibility.
The update image also contains this value and is compared
upon receipt of the update image.

Tested: set the layout:
        - enter MFG mode
	- ipmitool raw 0x30 0xa3 W X Y Z
	- inspect fitc layout file on BMC

Change-Id: I72930407a230b55340f6d12cef48e0e8d273ed6e
Signed-off-by: Vernon Mauery <vernon.mauery@linux.intel.com>
diff --git a/src/manufacturingcommands.cpp b/src/manufacturingcommands.cpp
index c92dd00..7d5a058 100644
--- a/src/manufacturingcommands.cpp
+++ b/src/manufacturingcommands.cpp
@@ -793,6 +793,8 @@
                         ipmi::intel::general::cmdSetManufacturingData):
         case makeCmdKey(ipmi::netFnOemOne,
                         ipmi::intel::general::cmdGetManufacturingData):
+        case makeCmdKey(ipmi::intel::netFnGeneral,
+                        ipmi::intel::general::cmdSetFITcLayout):
         case makeCmdKey(ipmi::netFnStorage, ipmi::storage::cmdWriteFruData):
         case makeCmdKey(ipmi::netFnOemTwo, ipmi::intel::platform::cmdClearCMOS):
 
@@ -979,6 +981,34 @@
     ipmi::Cc retI2C = ipmi::i2cWriteRead(i2cBus, slaveAddr, writeData, readBuf);
     return ipmi::response(retI2C);
 }
+
+ipmi::RspType<> setFITcLayout(uint32_t layout)
+{
+    static constexpr const char* factoryFITcLayout =
+        "/var/sofs/factory-settings/layout/fitc";
+    std::filesystem::path fitcDir =
+        std::filesystem::path(factoryFITcLayout).parent_path();
+    std::error_code ec;
+    std::filesystem::create_directories(fitcDir, ec);
+    if (ec)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+    try
+    {
+        std::ofstream file(factoryFITcLayout);
+        file << layout;
+        file.flush();
+        file.close();
+    }
+    catch (const std::exception& e)
+    {
+        return ipmi::responseUnspecifiedError();
+    }
+
+    return ipmi::responseSuccess();
+}
+
 } // namespace ipmi
 
 void register_mtm_commands() __attribute__((constructor));
@@ -1005,6 +1035,10 @@
                           ipmi::intel::general::cmdGetManufacturingData,
                           ipmi::Privilege::Admin, ipmi::getManufacturingData);
 
+    ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnGeneral,
+                          ipmi::intel::general::cmdSetFITcLayout,
+                          ipmi::Privilege::Admin, ipmi::setFITcLayout);
+
     ipmi::registerHandler(ipmi::prioOemBase, ipmi::intel::netFnApp,
                           ipmi::intel::general::cmdSlotI2CMasterWriteRead,
                           ipmi::Privilege::Admin,