boot policy: Correct the logic of setting the boot policy

Resolves openbmc/openbmc#2355

Change-Id: Ic7b0efb35887c987a1626e5d88f8a9513d22004f
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/chassishandler.cpp b/chassishandler.cpp
index 1e9d3df..5c0c8c1 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -1230,6 +1230,8 @@
         using namespace chassis::internal::cache;
         auto oneTimeEnabled = false;
         constexpr auto enabledIntf = "xyz.openbmc_project.Object.Enable";
+        constexpr auto oneTimePath =
+                "/xyz/openbmc_project/control/host0/boot/one_time";
 
         try
         {
@@ -1237,18 +1239,44 @@
                 (reqptr->data[0] & SET_PARM_BOOT_FLAGS_PERMANENT) ==
                 SET_PARM_BOOT_FLAGS_PERMANENT;
 
+            auto bootSetting =
+                settings::boot::setting(objects, bootSourceIntf);
+
+            oneTimeEnabled =
+                std::get<settings::boot::OneTimeEnabled>(bootSetting);
+
+            /*
+             * Check if the current boot setting is onetime or permanent, if the
+             * request in the command is otherwise, then set the "Enabled"
+             * property in one_time object path to 'True' to indicate onetime
+             * and 'False' to indicate permanent.
+             *
+             * Once the onetime/permanent setting is applied, then the bootMode
+             * and bootSource is updated for the corresponding object.
+             */
+            if ((permanent && oneTimeEnabled) ||
+                (!permanent && !oneTimeEnabled))
+            {
+                auto service = ipmi::getService(dbus, enabledIntf, oneTimePath);
+
+                ipmi::setDbusProperty(dbus,
+                                      service,
+                                      oneTimePath,
+                                      enabledIntf,
+                                      "Enabled",
+                                      !permanent);
+            }
+
             auto modeItr = modeIpmiToDbus.find(bootOption);
             auto sourceItr = sourceIpmiToDbus.find(bootOption);
             if (sourceIpmiToDbus.end() != sourceItr)
             {
                 sdbusplus::message::variant<std::string> property =
                     convertForMessage(sourceItr->second);
-                    auto bootSetting =
-                        settings::boot::setting(objects, bootSourceIntf);
+                auto bootSetting = settings::boot::setting(objects,
+                                                           bootSourceIntf);
                 const auto& bootSourceSetting =
                     std::get<settings::Path>(bootSetting);
-                oneTimeEnabled =
-                    std::get<settings::boot::OneTimeEnabled>(bootSetting);
                 auto method =
                     dbus.new_method_call(
                          objects.service(bootSourceSetting, bootSourceIntf).
@@ -1266,39 +1294,15 @@
                     return IPMI_CC_UNSPECIFIED_ERROR;
                 }
 
-                if (permanent && oneTimeEnabled)
-                {
-                    sdbusplus::message::variant<bool> enabled = false;
-                    method =
-                        objects.bus.new_method_call(
-                            objects.service(bootSourceSetting,
-                                            bootSourceIntf).c_str(),
-                            bootSourceSetting.c_str(),
-                            ipmi::PROP_INTF,
-                            "Set");
-                    method.append(enabledIntf, "Enabled", enabled);
-                    auto reply = objects.bus.call(method);
-                    if (reply.is_method_error())
-                    {
-                        log<level::ERR>("Error in setting enabled property",
-                                        entry("OBJECT=%s",
-                                              bootSourceSetting.c_str()));
-                        report<InternalFailure>();
-                        *data_len = 0;
-                        return IPMI_CC_UNSPECIFIED_ERROR;
-                    }
-                }
             }
             if (modeIpmiToDbus.end() != modeItr)
             {
                 sdbusplus::message::variant<std::string> property =
                     convertForMessage(modeItr->second);
-                auto bootSetting =
-                    settings::boot::setting(objects, bootModeIntf);
+                auto bootSetting = settings::boot::setting(objects,
+                                                           bootModeIntf);
                 const auto& bootModeSetting =
                     std::get<settings::Path>(bootSetting);
-                oneTimeEnabled =
-                    std::get<settings::boot::OneTimeEnabled>(bootSetting);
                 auto method =
                     dbus.new_method_call(
                          objects.service(bootModeSetting, bootModeIntf).c_str(),
@@ -1314,29 +1318,6 @@
                     *data_len = 0;
                     return IPMI_CC_UNSPECIFIED_ERROR;
                 }
-
-                if (permanent && oneTimeEnabled)
-                {
-                    sdbusplus::message::variant<bool> enabled = false;
-                    method =
-                        objects.bus.new_method_call(
-                            objects.service(bootModeSetting, bootModeIntf).
-                                c_str(),
-                            bootModeSetting.c_str(),
-                            ipmi::PROP_INTF,
-                            "Set");
-                    method.append(enabledIntf, "Enabled", enabled);
-                    auto reply = objects.bus.call(method);
-                    if (reply.is_method_error())
-                    {
-                        log<level::ERR>("Error in setting enabled property",
-                                        entry("OBJECT=%s",
-                                              bootModeSetting.c_str()));
-                        report<InternalFailure>();
-                        *data_len = 0;
-                        return IPMI_CC_UNSPECIFIED_ERROR;
-                    }
-                }
             }
         }
         catch (InternalFailure& e)