xref: /openbmc/phosphor-bmc-code-mgmt/test/common/exampledevice/example_device.cpp (revision 994a77ff25aeb28b2cce7142d081af767f9eb542)
1 #include "example_device.hpp"
2 
3 #include "common/include/device.hpp"
4 #include "common/include/software_config.hpp"
5 #include "common/include/software_manager.hpp"
6 
7 #include <phosphor-logging/lg2.hpp>
8 #include <sdbusplus/asio/connection.hpp>
9 #include <sdbusplus/asio/object_server.hpp>
10 #include <sdbusplus/async.hpp>
11 #include <sdbusplus/server.hpp>
12 #include <xyz/openbmc_project/Association/Definitions/server.hpp>
13 #include <xyz/openbmc_project/Software/Update/server.hpp>
14 
15 #include <memory>
16 
17 PHOSPHOR_LOG2_USING;
18 
19 using namespace phosphor::software;
20 using namespace phosphor::software::config;
21 using namespace phosphor::software::manager;
22 using namespace phosphor::software::device;
23 using namespace phosphor::software::example_device;
24 
25 SoftwareConfig ExampleDevice::defaultConfig =
26     SoftwareConfig(exampleInvObjPath, exampleVendorIANA,
27                    exampleCompatibleHardware, "Nop", exampleName);
28 
29 long ExampleCodeUpdater::getRandomId()
30 {
31     struct timespec ts;
32     clock_gettime(CLOCK_REALTIME, &ts);
33     unsigned int seed = ts.tv_nsec ^ getpid();
34     srandom(seed);
35     return random() % 10000;
36 }
37 
38 // nop code updater needs unique suffix on dbus for parallel unit testing
39 ExampleCodeUpdater::ExampleCodeUpdater(sdbusplus::async::context& ctx,
40                                        long uniqueSuffix) :
41     SoftwareManager(ctx, "ExampleUpdater" + std::to_string(uniqueSuffix))
42 {}
43 
44 // NOLINTBEGIN(readability-static-accessed-through-instance)
45 sdbusplus::async::task<bool> ExampleCodeUpdater::initDevice(
46     const std::string& /*unused*/, const std::string& /*unused*/,
47     SoftwareConfig& /*unused*/)
48 // NOLINTEND(readability-static-accessed-through-instance)
49 {
50     auto device = std::make_unique<ExampleDevice>(ctx, this);
51 
52     device->softwareCurrent = std::make_unique<Software>(ctx, *device);
53 
54     device->softwareCurrent->setVersion("v1.0");
55     device->softwareCurrent->setActivation(
56         SoftwareActivation::Activations::Active);
57 
58     auto applyTimes = {RequestedApplyTimes::OnReset};
59     device->softwareCurrent->enableUpdate(applyTimes);
60 
61     devices.insert({exampleInvObjPath, std::move(device)});
62 
63     co_return true;
64 }
65 
66 ExampleDevice::ExampleDevice(sdbusplus::async::context& ctx,
67                              SoftwareManager* parent,
68                              const SoftwareConfig& config) :
69     Device(ctx, config, parent,
70            {RequestedApplyTimes::Immediate, RequestedApplyTimes::OnReset})
71 {}
72 
73 // NOLINTBEGIN(readability-static-accessed-through-instance)
74 sdbusplus::async::task<bool> ExampleDevice::updateDevice(
75     const uint8_t* /*unused*/, size_t compImageSize)
76 // NOLINTEND(readability-static-accessed-through-instance)
77 {
78     debug("Called device specific update function with image size {SIZE}",
79           "SIZE", compImageSize);
80 
81     deviceSpecificUpdateFunctionCalled = true;
82 
83     // Setting this property for demonstration purpose.
84     // For a real device, this could represent the
85     // percentage completion of writing the firmware,
86     // and any progress made in the update process within this function.
87     // There is no hard constraint on the values here,
88     // we do not have to reach any specific percentage.
89     // The percentage should be monotonic and increasing.
90     for (auto progress = 0; progress <= 100; progress += 20)
91     {
92         setUpdateProgress(progress);
93     }
94 
95     co_return true;
96 }
97