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
getRandomId()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
ExampleCodeUpdater(sdbusplus::async::context & ctx,long uniqueSuffix)39 ExampleCodeUpdater::ExampleCodeUpdater(sdbusplus::async::context& ctx,
40 long uniqueSuffix) :
41 SoftwareManager(ctx, "ExampleUpdater" + std::to_string(uniqueSuffix))
42 {}
43
ExampleCodeUpdater(sdbusplus::async::context & ctx,bool createDevice,const char * swVersion)44 ExampleCodeUpdater::ExampleCodeUpdater(
45 sdbusplus::async::context& ctx, bool createDevice, const char* swVersion) :
46 ExampleCodeUpdater(ctx)
47 {
48 if (!createDevice)
49 {
50 return;
51 }
52 const std::string exampleInvObjPath =
53 "/xyz/openbmc_project/inventory/system/board/ExampleBoard/ExampleDevice";
54 auto exampleDevice = std::make_unique<ExampleDevice>(ctx, &(*this));
55
56 devices.insert({exampleInvObjPath, std::move(exampleDevice)});
57
58 if (swVersion)
59 {
60 auto& device = getDevice();
61 device->softwareCurrent =
62 std::make_unique<ExampleSoftware>(ctx, *device);
63 device->softwareCurrent->setVersion(swVersion);
64 }
65 }
66
getDevice()67 std::unique_ptr<ExampleDevice>& ExampleCodeUpdater::getDevice()
68 {
69 if (devices.empty())
70 {
71 throw std::invalid_argument(
72 "could not find any device, example CU wrongly initialized");
73 }
74
75 auto& deviceRef = devices.begin()->second;
76
77 return reinterpret_cast<std::unique_ptr<ExampleDevice>&>(deviceRef);
78 }
79
initDevice(const std::string &,const std::string &,SoftwareConfig &)80 sdbusplus::async::task<bool> ExampleCodeUpdater::initDevice(
81 const std::string& /*unused*/, const std::string& /*unused*/,
82 SoftwareConfig& /*unused*/)
83 {
84 auto device = std::make_unique<ExampleDevice>(ctx, this);
85
86 device->softwareCurrent = std::make_unique<ExampleSoftware>(ctx, *device);
87
88 device->softwareCurrent->setVersion("v1.0",
89 SoftwareVersion::VersionPurpose::Other);
90 device->softwareCurrent->setActivation(
91 SoftwareActivation::Activations::Active);
92
93 auto applyTimes = {RequestedApplyTimes::OnReset};
94 device->softwareCurrent->enableUpdate(applyTimes);
95
96 devices.insert({exampleInvObjPath, std::move(device)});
97
98 co_return true;
99 }
100
ExampleDevice(sdbusplus::async::context & ctx,SoftwareManager * parent,const SoftwareConfig & config)101 ExampleDevice::ExampleDevice(sdbusplus::async::context& ctx,
102 SoftwareManager* parent,
103 const SoftwareConfig& config) :
104 Device(ctx, config, parent,
105 {RequestedApplyTimes::Immediate, RequestedApplyTimes::OnReset})
106 {}
107
updateDevice(const uint8_t *,size_t compImageSize)108 sdbusplus::async::task<bool> ExampleDevice::updateDevice(
109 const uint8_t* /*unused*/, size_t compImageSize)
110 {
111 debug("Called device specific update function with image size {SIZE}",
112 "SIZE", compImageSize);
113
114 deviceSpecificUpdateFunctionCalled = true;
115
116 // Setting this property for demonstration purpose.
117 // For a real device, this could represent the
118 // percentage completion of writing the firmware,
119 // and any progress made in the update process within this function.
120 // There is no hard constraint on the values here,
121 // we do not have to reach any specific percentage.
122 // The percentage should be monotonic and increasing.
123 for (auto progress = 0; progress <= 100; progress += 20)
124 {
125 setUpdateProgress(progress);
126 }
127
128 co_return true;
129 }
130
ExampleSoftware(sdbusplus::async::context & ctx,ExampleDevice & parent)131 ExampleSoftware::ExampleSoftware(sdbusplus::async::context& ctx,
132 ExampleDevice& parent) : Software(ctx, parent)
133 {}
134