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 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 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 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 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 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 131 ExampleSoftware::ExampleSoftware(sdbusplus::async::context& ctx, 132 ExampleDevice& parent) : Software(ctx, parent) 133 {} 134