hothd: Implement Activation interface for Software

Bmcweb is expecting all software to have activation interface
implemented to determine the Status of the software.

If hothd is up and running and can communicate with the Hoth chip,
then Activation status should be active. Since if there is communication
error, hothd will exit and not register any dbus object, hence the
activation will always be Active for both version of the software.

Tested:
```
root@jkbs2-nfd01:~# busctl introspect xyz.openbmc_project.Control.Hoth /xyz/openbmc_project/software/hoth_ro
NAME                                    TYPE      SIGNATURE RESULT/VALUE                             FLAGS
org.freedesktop.DBus.Introspectable     interface -         -                                        -
.Introspect                             method    -         s                                        -
org.freedesktop.DBus.Peer               interface -         -                                        -
.GetMachineId                           method    -         s                                        -
.Ping                                   method    -         -                                        -
org.freedesktop.DBus.Properties         interface -         -                                        -
.Get                                    method    ss        v                                        -
.GetAll                                 method    s         a{sv}                                    -
.Set                                    method    ssv       -                                        -
.PropertiesChanged                      signal    sa{sv}as  -                                        -
xyz.openbmc_project.Software.Activation interface -         -                                        -
.Activation                             property  s         "xyz.openbmc_project.Software.Activatio… emits-change writable
.RequestedActivation                    property  s         "xyz.openbmc_project.Software.Activatio… emits-change writable
xyz.openbmc_project.Software.Version    interface -         -                                        -
.Purpose                                property  s         "xyz.openbmc_project.Software.Version.V… emits-change writable
.Version                                property  s         "0.0.343/36e0ecd5 ok"                    emits-change writable
<.Control.Hoth /xyz/openbmc_project/software/hoth_ro xyz.openbmc_project.Software.Activation Activation
s "xyz.openbmc_project.Software.Activation.Activations.Active"

root@jkbs2-nfd01:~# curl localhost/redfish/v1/UpdateService/FirmwareInventory/hoth_ro
{
  "@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/hoth_ro",
  "@odata.type": "#SoftwareInventory.v1_3_0.SoftwareInventory",
  "Description": "Unknown image",
  "Id": "hoth_ro",
  "Name": "Software Inventory",
  "Status": {
    "Health": "OK",
    "HealthRollup": "OK",
    "State": "Enabled"
  },
  "Updateable": false,
  "Version": "0.0.343/36e0ecd5 ok"
}
root@jkbs2-nfd01:~# curl localhost/redfish/v1/UpdateService/FirmwareInventory/hoth_rw
{
  "@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/hoth_rw",
  "@odata.type": "#SoftwareInventory.v1_3_0.SoftwareInventory",
  "Description": "Unknown image",
  "Id": "hoth_rw",
  "Name": "Software Inventory",
  "Status": {
    "Health": "OK",
    "HealthRollup": "OK",
    "State": "Enabled"
  },
  "Updateable": false,
  "Version": "0.5.2024071810/bmc_mobo_hoth"
}
root@jkbs2-nfd01:~# systemctl stop hothd
root@jkbs2-nfd01:~# systemctl status hothd
○ hothd.service - Hoth control daemon
     Loaded: loaded (/usr/lib/systemd/system/hothd.service; enabled; preset: enabled)
     Active: inactive (dead) since Thu 2024-12-26 19:33:42 PST; 20s ago
   Duration: 2month 2w 4d 14h 50min 12.757s
 Invocation: e28b5252bed5483e84b3f03f0ad0b4b1
    Process: 423 ExecStart=/usr/libexec/hothd -b (code=killed, signal=TERM)
   Main PID: 423 (code=killed, signal=TERM)
        CPU: 54.681s
root@jkbs2-nfd01:~# curl localhost/redfish/v1/UpdateService/FirmwareInventory/
{
  "@odata.id": "/redfish/v1/UpdateService/FirmwareInventory",
  "@odata.type": "#SoftwareInventoryCollection.SoftwareInventoryCollection",
  "Members": [
    {
      "@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/bios_active"
    },
    {
      "@odata.id": "/redfish/v1/UpdateService/FirmwareInventory/de149a25"
    }
  ],
  "Members@odata.count": 2,
  "Name": "Software Inventory Collection"
root@jkbs2-nfd01:~# busctl introspect xyz.openbmc_project.Control.Hoth /xyz/openbmc_project/software/hoth_ro
Failed to introspect object /xyz/openbmc_project/software/hoth_ro of service xyz.openbmc_project.Control.Hoth: The name is not activatable
```

Google-Bug-Id: 384444534
Change-Id: I95167df8d971c5ed862c29a5212aa0933f9ab32d
Signed-off-by: Munawar Hussain <munawarhussain@google.com>
diff --git a/activation.hpp b/activation.hpp
new file mode 100644
index 0000000..c166d89
--- /dev/null
+++ b/activation.hpp
@@ -0,0 +1,48 @@
+// Copyright 2024 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#pragma once
+
+#include <sdbusplus/bus.hpp>
+#include <xyz/openbmc_project/Software/Activation/server.hpp>
+
+namespace google
+{
+namespace hoth
+{
+
+template <typename... T>
+using ServerObject = typename sdbusplus::server::object::object<T...>;
+using ActivationInterface =
+    sdbusplus::xyz::openbmc_project::Software::server::Activation;
+using ActivationObject = ServerObject<ActivationInterface>;
+
+/** @class SwActivation
+ *  @brief Software Activation interface implementation for all Versions.
+ *  @details A concrete implementation for
+ * xyz.openbmc_project.Software.Activation DBus API.
+ */
+class SwActivation : public ActivationObject
+{
+  public:
+    SwActivation(sdbusplus::bus::bus& bus, const char* objPath) :
+        ActivationObject(bus, objPath)
+    {
+      activation(Activations::Active);
+    }
+};
+
+} // namespace hoth
+
+}  // namespace google
diff --git a/main.cpp b/main.cpp
index 4aa70e3..0f95323 100644
--- a/main.cpp
+++ b/main.cpp
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+#include "activation.hpp"
 #include "asset.hpp"
 #include "ec_util.hpp"
 #include "firmware_mtd_updater.hpp"
@@ -201,6 +202,8 @@
     std::unique_ptr<google::hoth::HothState> hoth_state;
     std::unique_ptr<google::hoth::RoVersion> swVerRo;
     std::unique_ptr<google::hoth::RwVersion> swVerRw;
+    std::unique_ptr<google::hoth::SwActivation> swActivationRo;
+    std::unique_ptr<google::hoth::SwActivation> swActivationRw;
     std::unique_ptr<google::hoth::Asset> asset;
     std::unique_ptr<google::hoth::internal::FirmwareUpdater> firmwareUpdater;
 
@@ -318,14 +321,18 @@
             *systemBus, ro_obj.c_str(), hostCmd.get());
         swVerRw = std::make_unique<google::hoth::RwVersion>(
             *systemBus, rw_obj.c_str(), hostCmd.get());
+        swActivationRo = std::make_unique<google::hoth::SwActivation>(
+            *systemBus, ro_obj.c_str());
+        swActivationRw = std::make_unique<google::hoth::SwActivation>(
+            *systemBus, rw_obj.c_str());
     }
     catch (const std::exception& e)
     {
-        stdplus::print(
-            stderr,
-            "Error registering Software Version objects with D-Bus: {}\n",
-            e.what());
-        exit(EXIT_FAILURE);
+      stdplus::print(stderr,
+                     "Error registering Software Version or Activation objects "
+                     "with D-Bus: {}\n",
+                     e.what());
+      exit(EXIT_FAILURE);
     }
     sd_notify(0, "READY=1");