| George Liu | 073a653 | 2021-10-25 14:40:03 +0800 | [diff] [blame] | 1 | #include "config.h" | 
|  | 2 |  | 
|  | 3 | #include "usb_manager.hpp" | 
|  | 4 |  | 
| George Liu | 6d775e6 | 2021-10-26 10:44:30 +0800 | [diff] [blame] | 5 | #include <sys/mount.h> | 
|  | 6 |  | 
| Jagpal Singh Gill | 6fbb54c | 2024-08-03 16:39:24 -0700 | [diff] [blame] | 7 | #include <xyz/openbmc_project/ObjectMapper/client.hpp> | 
|  | 8 | #include <xyz/openbmc_project/Software/ApplyTime/common.hpp> | 
|  | 9 | #include <xyz/openbmc_project/Software/Update/client.hpp> | 
|  | 10 |  | 
| George Liu | 44b9fef | 2023-02-07 14:31:32 +0800 | [diff] [blame] | 11 | #include <system_error> | 
|  | 12 |  | 
| George Liu | 073a653 | 2021-10-25 14:40:03 +0800 | [diff] [blame] | 13 | namespace phosphor | 
|  | 14 | { | 
|  | 15 | namespace usb | 
|  | 16 | { | 
|  | 17 |  | 
| Jagpal Singh Gill | 6fbb54c | 2024-08-03 16:39:24 -0700 | [diff] [blame] | 18 | using Association = std::tuple<std::string, std::string, std::string>; | 
|  | 19 | using Paths = std::vector<std::string>; | 
|  | 20 |  | 
|  | 21 | bool USBManager::copyImage() | 
| George Liu | 073a653 | 2021-10-25 14:40:03 +0800 | [diff] [blame] | 22 | { | 
| George Liu | 44b9fef | 2023-02-07 14:31:32 +0800 | [diff] [blame] | 23 | std::error_code ec; | 
| George Liu | 073a653 | 2021-10-25 14:40:03 +0800 | [diff] [blame] | 24 | fs::path dir(usbPath); | 
| George Liu | 44b9fef | 2023-02-07 14:31:32 +0800 | [diff] [blame] | 25 | fs::create_directories(dir, ec); | 
| George Liu | 6d775e6 | 2021-10-26 10:44:30 +0800 | [diff] [blame] | 26 |  | 
|  | 27 | auto rc = mount(devicePath.c_str(), usbPath.c_str(), "vfat", 0, NULL); | 
|  | 28 | if (rc) | 
| George Liu | 073a653 | 2021-10-25 14:40:03 +0800 | [diff] [blame] | 29 | { | 
| George Liu | 6d775e6 | 2021-10-26 10:44:30 +0800 | [diff] [blame] | 30 | lg2::error("Error ({ERRNO}) occurred during the mount call", "ERRNO", | 
|  | 31 | errno); | 
| George Liu | 073a653 | 2021-10-25 14:40:03 +0800 | [diff] [blame] | 32 | return false; | 
|  | 33 | } | 
|  | 34 |  | 
|  | 35 | for (const auto& p : std::filesystem::directory_iterator(dir)) | 
|  | 36 | { | 
|  | 37 | if (p.path().extension() == ".tar") | 
|  | 38 | { | 
|  | 39 | fs::path dstPath{IMG_UPLOAD_DIR / p.path().filename()}; | 
| George Liu | 44b9fef | 2023-02-07 14:31:32 +0800 | [diff] [blame] | 40 | if (fs::exists(dstPath, ec)) | 
| George Liu | 073a653 | 2021-10-25 14:40:03 +0800 | [diff] [blame] | 41 | { | 
|  | 42 | lg2::info( | 
|  | 43 | "{DSTPATH} already exists in the /tmp/images directory, exit the upgrade", | 
|  | 44 | "DSTPATH", p.path().filename()); | 
|  | 45 |  | 
|  | 46 | break; | 
|  | 47 | } | 
|  | 48 |  | 
|  | 49 | try | 
|  | 50 | { | 
| Jagpal Singh Gill | 6fbb54c | 2024-08-03 16:39:24 -0700 | [diff] [blame] | 51 | imageDstPath = dstPath; | 
| George Liu | 073a653 | 2021-10-25 14:40:03 +0800 | [diff] [blame] | 52 | return fs::copy_file(fs::absolute(p.path()), dstPath); | 
|  | 53 | } | 
|  | 54 | catch (const std::exception& e) | 
|  | 55 | { | 
|  | 56 | lg2::error("Error when copying {SRC} to /tmp/images: {ERROR}", | 
|  | 57 | "SRC", p.path(), "ERROR", e.what()); | 
|  | 58 | } | 
|  | 59 |  | 
|  | 60 | break; | 
|  | 61 | } | 
|  | 62 | } | 
|  | 63 |  | 
|  | 64 | return false; | 
|  | 65 | } | 
|  | 66 |  | 
| Jagpal Singh Gill | 6fbb54c | 2024-08-03 16:39:24 -0700 | [diff] [blame] | 67 | #ifdef START_UPDATE_DBUS_INTEFACE | 
|  | 68 |  | 
| Jagpal Singh Gill | 6fbb54c | 2024-08-03 16:39:24 -0700 | [diff] [blame] | 69 | auto findAssociatedUpdatablePath(sdbusplus::async::context& ctx) | 
|  | 70 | -> sdbusplus::async::task<Paths> | 
|  | 71 | { | 
|  | 72 | constexpr auto associatedPath = | 
|  | 73 | "/xyz/openbmc_project/software/bmc/updateable"; | 
|  | 74 | constexpr auto interface = "xyz.openbmc_project.Association"; | 
|  | 75 | constexpr auto propertyName = "endpoints"; | 
|  | 76 |  | 
|  | 77 | co_return utils::getProperty<Paths>(ctx.get_bus(), associatedPath, | 
|  | 78 | interface, propertyName); | 
|  | 79 | } | 
|  | 80 |  | 
| Jagpal Singh Gill | 6fbb54c | 2024-08-03 16:39:24 -0700 | [diff] [blame] | 81 | auto USBManager::startUpdate(int fd) -> sdbusplus::async::task<bool> | 
|  | 82 | { | 
|  | 83 | using Updater = sdbusplus::client::xyz::openbmc_project::software::Update<>; | 
|  | 84 | using ApplyTimeIntf = | 
|  | 85 | sdbusplus::common::xyz::openbmc_project::software::ApplyTime; | 
|  | 86 |  | 
|  | 87 | constexpr auto serviceName = "xyz.openbmc_project.Software.Manager"; | 
|  | 88 |  | 
|  | 89 | auto paths = co_await findAssociatedUpdatablePath(ctx); | 
|  | 90 | if (paths.size() != 1) | 
|  | 91 | { | 
|  | 92 | lg2::error("Failed to find associated updatable path"); | 
|  | 93 | co_return false; | 
|  | 94 | } | 
|  | 95 |  | 
|  | 96 | auto updater = Updater(ctx).service(serviceName).path(paths[0]); | 
|  | 97 | sdbusplus::message::object_path objectPath = co_await updater.start_update( | 
|  | 98 | fd, ApplyTimeIntf::RequestedApplyTimes::OnReset); | 
|  | 99 | if (objectPath.str.empty()) | 
|  | 100 | { | 
|  | 101 | lg2::error("StartUpdate failed"); | 
|  | 102 | co_return false; | 
|  | 103 | } | 
|  | 104 | lg2::info("StartUpdate succeeded, objectPath: {PATH}", "PATH", objectPath); | 
|  | 105 |  | 
|  | 106 | co_return true; | 
|  | 107 | } | 
|  | 108 |  | 
| Jagpal Singh Gill | 6fbb54c | 2024-08-03 16:39:24 -0700 | [diff] [blame] | 109 | auto USBManager::run() -> sdbusplus::async::task<void> | 
|  | 110 | { | 
|  | 111 | auto res = copyImage(); | 
|  | 112 | if (!res) | 
|  | 113 | { | 
|  | 114 | lg2::error("Failed to copy image from USB"); | 
|  | 115 | co_return; | 
|  | 116 | } | 
|  | 117 |  | 
|  | 118 | int fd = open(imageDstPath.c_str(), O_RDONLY); | 
|  | 119 | if (fd < 0) | 
|  | 120 | { | 
|  | 121 | lg2::error("Failed to open {PATH}", "PATH", imageDstPath); | 
|  | 122 | co_return; | 
|  | 123 | } | 
|  | 124 |  | 
|  | 125 | co_await startUpdate(fd); | 
|  | 126 |  | 
|  | 127 | ctx.request_stop(); | 
|  | 128 |  | 
|  | 129 | co_return; | 
|  | 130 | } | 
|  | 131 |  | 
|  | 132 | #else | 
|  | 133 |  | 
|  | 134 | bool USBManager::run() | 
|  | 135 | { | 
|  | 136 | return copyImage(); | 
|  | 137 | } | 
|  | 138 |  | 
| George Liu | 5107c45 | 2021-11-09 20:06:31 +0800 | [diff] [blame] | 139 | void USBManager::setApplyTime() | 
|  | 140 | { | 
|  | 141 | utils::PropertyValue value = | 
|  | 142 | "xyz.openbmc_project.Software.ApplyTime.RequestedApplyTimes.OnReset"; | 
| George Liu | 5107c45 | 2021-11-09 20:06:31 +0800 | [diff] [blame] | 143 | try | 
|  | 144 | { | 
| Lei YU | 0cd6d84 | 2021-12-27 11:56:02 +0800 | [diff] [blame] | 145 | constexpr auto objectPath = "/xyz/openbmc_project/software/apply_time"; | 
|  | 146 | constexpr auto interface = "xyz.openbmc_project.Software.ApplyTime"; | 
|  | 147 | constexpr auto propertyName = "RequestedApplyTime"; | 
| George Liu | 5107c45 | 2021-11-09 20:06:31 +0800 | [diff] [blame] | 148 | utils::setProperty(bus, objectPath, interface, propertyName, value); | 
|  | 149 | } | 
|  | 150 | catch (const std::exception& e) | 
|  | 151 | { | 
|  | 152 | lg2::error("Failed to set RequestedApplyTime property, ERROR:{ERROR}", | 
|  | 153 | "ERROR", e.what()); | 
|  | 154 | } | 
|  | 155 | } | 
|  | 156 |  | 
|  | 157 | void USBManager::setRequestedActivation(const std::string& path) | 
|  | 158 | { | 
|  | 159 | utils::PropertyValue value = | 
|  | 160 | "xyz.openbmc_project.Software.Activation.RequestedActivations.Active"; | 
| George Liu | 5107c45 | 2021-11-09 20:06:31 +0800 | [diff] [blame] | 161 | try | 
|  | 162 | { | 
| Lei YU | 0cd6d84 | 2021-12-27 11:56:02 +0800 | [diff] [blame] | 163 | constexpr auto interface = "xyz.openbmc_project.Software.Activation"; | 
|  | 164 | constexpr auto propertyName = "RequestedActivation"; | 
| George Liu | 5107c45 | 2021-11-09 20:06:31 +0800 | [diff] [blame] | 165 | utils::setProperty(bus, path, interface, propertyName, value); | 
|  | 166 | } | 
|  | 167 | catch (const std::exception& e) | 
|  | 168 | { | 
|  | 169 | lg2::error("Failed to set RequestedActivation property, ERROR:{ERROR}", | 
|  | 170 | "ERROR", e.what()); | 
|  | 171 | } | 
|  | 172 |  | 
|  | 173 | return; | 
|  | 174 | } | 
|  | 175 |  | 
| Patrick Williams | bf2bb2b | 2022-07-22 19:26:52 -0500 | [diff] [blame] | 176 | void USBManager::updateActivation(sdbusplus::message_t& msg) | 
| George Liu | 5107c45 | 2021-11-09 20:06:31 +0800 | [diff] [blame] | 177 | { | 
|  | 178 | std::map<std::string, std::map<std::string, std::variant<std::string>>> | 
|  | 179 | interfaces; | 
|  | 180 | sdbusplus::message::object_path path; | 
|  | 181 | msg.read(path, interfaces); | 
|  | 182 |  | 
|  | 183 | constexpr auto imageInterface = "xyz.openbmc_project.Software.Activation"; | 
|  | 184 | constexpr auto readyPro = | 
|  | 185 | "xyz.openbmc_project.Software.Activation.Activations.Ready"; | 
|  | 186 | for (auto& interface : interfaces) | 
|  | 187 | { | 
|  | 188 | if (interface.first != imageInterface) | 
|  | 189 | { | 
|  | 190 | continue; | 
|  | 191 | } | 
|  | 192 |  | 
|  | 193 | try | 
|  | 194 | { | 
| Andrew Geissler | 047f60e | 2022-04-06 15:38:07 -0500 | [diff] [blame] | 195 | auto imageProp = utils::getProperty<std::string>( | 
|  | 196 | bus, path.str, imageInterface, "Activation"); | 
|  | 197 |  | 
| George Liu | 5107c45 | 2021-11-09 20:06:31 +0800 | [diff] [blame] | 198 | if (imageProp == readyPro && isUSBCodeUpdate) | 
|  | 199 | { | 
|  | 200 | setApplyTime(); | 
|  | 201 | setRequestedActivation(path.str); | 
|  | 202 | event.exit(0); | 
|  | 203 | } | 
|  | 204 | } | 
|  | 205 | catch (const std::exception& e) | 
|  | 206 | { | 
|  | 207 | lg2::error("Failed in getting Activation status, ERROR:{ERROR}", | 
|  | 208 | "ERROR", e.what()); | 
|  | 209 | } | 
|  | 210 | } | 
|  | 211 | } | 
|  | 212 |  | 
| Jagpal Singh Gill | 6fbb54c | 2024-08-03 16:39:24 -0700 | [diff] [blame] | 213 | #endif // START_UPDATE_DBUS_INTEFACE | 
|  | 214 |  | 
| George Liu | 073a653 | 2021-10-25 14:40:03 +0800 | [diff] [blame] | 215 | } // namespace usb | 
| George Liu | 5107c45 | 2021-11-09 20:06:31 +0800 | [diff] [blame] | 216 | } // namespace phosphor |