Andrew Jeffery | dae6e18 | 2021-05-21 16:23:07 +0930 | [diff] [blame] | 1 | #pragma once |
| 2 | |
| 3 | #include "NVMeSensor.hpp" |
| 4 | |
Ed Tanous | 1f97863 | 2023-02-28 18:16:39 -0800 | [diff] [blame] | 5 | #include <boost/asio/io_context.hpp> |
Ed Tanous | 9b4a20e | 2022-09-06 08:47:11 -0700 | [diff] [blame] | 6 | #include <boost/asio/steady_timer.hpp> |
Ed Tanous | 18b6186 | 2025-01-30 10:56:28 -0800 | [diff] [blame] | 7 | #include <boost/container/flat_map.hpp> |
Andrew Jeffery | dae6e18 | 2021-05-21 16:23:07 +0930 | [diff] [blame] | 8 | |
Ed Tanous | 18b6186 | 2025-01-30 10:56:28 -0800 | [diff] [blame] | 9 | #include <algorithm> |
| 10 | #include <cstddef> |
| 11 | #include <list> |
Andrew Jeffery | dae6e18 | 2021-05-21 16:23:07 +0930 | [diff] [blame] | 12 | #include <memory> |
Ed Tanous | 18b6186 | 2025-01-30 10:56:28 -0800 | [diff] [blame] | 13 | #include <optional> |
Andrew Jeffery | 25e20bd | 2022-03-15 22:26:04 +1030 | [diff] [blame] | 14 | #include <stdexcept> |
Ed Tanous | 18b6186 | 2025-01-30 10:56:28 -0800 | [diff] [blame] | 15 | #include <string> |
Andrew Jeffery | dae6e18 | 2021-05-21 16:23:07 +0930 | [diff] [blame] | 16 | |
Andrew Jeffery | fa500ae | 2021-05-21 16:46:36 +0930 | [diff] [blame] | 17 | class NVMeContext : public std::enable_shared_from_this<NVMeContext> |
Andrew Jeffery | dae6e18 | 2021-05-21 16:23:07 +0930 | [diff] [blame] | 18 | { |
Andrew Jeffery | fa500ae | 2021-05-21 16:46:36 +0930 | [diff] [blame] | 19 | public: |
Ed Tanous | 1f97863 | 2023-02-28 18:16:39 -0800 | [diff] [blame] | 20 | NVMeContext(boost::asio::io_context& io, int rootBus) : |
Andrew Jeffery | b5d7a7f | 2022-05-02 11:57:03 +0930 | [diff] [blame] | 21 | scanTimer(io), rootBus(rootBus), pollCursor(sensors.end()) |
Andrew Jeffery | 25e20bd | 2022-03-15 22:26:04 +1030 | [diff] [blame] | 22 | { |
| 23 | if (rootBus < 0) |
| 24 | { |
| 25 | throw std::invalid_argument( |
| 26 | "Invalid root bus: Bus ID must not be negative"); |
| 27 | } |
| 28 | } |
Andrew Jeffery | dae6e18 | 2021-05-21 16:23:07 +0930 | [diff] [blame] | 29 | |
Andrew Jeffery | a9d1508 | 2021-05-24 13:55:12 +0930 | [diff] [blame] | 30 | virtual ~NVMeContext() |
| 31 | { |
Ed Tanous | ec77caa | 2023-02-17 10:46:06 -0800 | [diff] [blame] | 32 | scanTimer.cancel(); |
Andrew Jeffery | a9d1508 | 2021-05-24 13:55:12 +0930 | [diff] [blame] | 33 | } |
Andrew Jeffery | dae6e18 | 2021-05-21 16:23:07 +0930 | [diff] [blame] | 34 | |
Ed Tanous | 74cffa8 | 2022-01-25 13:00:28 -0800 | [diff] [blame] | 35 | void addSensor(const std::shared_ptr<NVMeSensor>& sensor) |
Andrew Jeffery | a9d1508 | 2021-05-24 13:55:12 +0930 | [diff] [blame] | 36 | { |
| 37 | sensors.emplace_back(sensor); |
| 38 | } |
Andrew Jeffery | dae6e18 | 2021-05-21 16:23:07 +0930 | [diff] [blame] | 39 | |
Patrick Williams | 556e04b | 2025-02-01 08:22:22 -0500 | [diff] [blame] | 40 | std::optional<std::shared_ptr<NVMeSensor>> getSensorAtPath( |
| 41 | const std::string& path) |
Andrew Jeffery | 3db6f9c | 2021-12-08 10:55:47 +1030 | [diff] [blame] | 42 | { |
| 43 | for (auto& sensor : sensors) |
| 44 | { |
| 45 | if (sensor->configurationPath == path) |
| 46 | { |
| 47 | return sensor; |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | return std::nullopt; |
| 52 | } |
| 53 | |
Andrew Jeffery | b5d7a7f | 2022-05-02 11:57:03 +0930 | [diff] [blame] | 54 | // Post-condition: The sensor list does not contain the provided sensor |
| 55 | // Post-condition: pollCursor is a valid iterator for the sensor list |
Ed Tanous | 74cffa8 | 2022-01-25 13:00:28 -0800 | [diff] [blame] | 56 | void removeSensor(const std::shared_ptr<NVMeSensor>& sensor) |
Andrew Jeffery | 3db6f9c | 2021-12-08 10:55:47 +1030 | [diff] [blame] | 57 | { |
Andrew Jeffery | b5d7a7f | 2022-05-02 11:57:03 +0930 | [diff] [blame] | 58 | // Locate the sensor that we're removing in the sensor list |
| 59 | auto found = std::find(sensors.begin(), sensors.end(), sensor); |
| 60 | |
| 61 | // If we failed to find the sensor in the list the post-condition is |
| 62 | // already satisfied |
| 63 | if (found == sensors.end()) |
| 64 | { |
| 65 | return; |
| 66 | } |
| 67 | |
| 68 | // We've found the sensor in the list |
| 69 | |
| 70 | // If we're not actively polling the sensor list, then remove the sensor |
| 71 | if (pollCursor == sensors.end()) |
| 72 | { |
| 73 | sensors.erase(found); |
| 74 | return; |
| 75 | } |
| 76 | |
| 77 | // We're actively polling the sensor list |
| 78 | |
| 79 | // If we're not polling the specific sensor that has been removed, then |
| 80 | // remove the sensor |
| 81 | if (*pollCursor != *found) |
| 82 | { |
| 83 | sensors.erase(found); |
| 84 | return; |
| 85 | } |
| 86 | |
| 87 | // We're polling the sensor that is being removed |
| 88 | |
| 89 | // Remove the sensor and update the poll cursor so the cursor remains |
| 90 | // valid |
| 91 | pollCursor = sensors.erase(found); |
Andrew Jeffery | 3db6f9c | 2021-12-08 10:55:47 +1030 | [diff] [blame] | 92 | } |
| 93 | |
Andrew Jeffery | a9d1508 | 2021-05-24 13:55:12 +0930 | [diff] [blame] | 94 | virtual void close() |
| 95 | { |
| 96 | scanTimer.cancel(); |
| 97 | } |
| 98 | |
Andrew Jeffery | 8c7074e | 2022-03-21 14:58:13 +1030 | [diff] [blame] | 99 | virtual void pollNVMeDevices() = 0; |
Andrew Jeffery | a9d1508 | 2021-05-24 13:55:12 +0930 | [diff] [blame] | 100 | |
Andrew Jeffery | b5d7a7f | 2022-05-02 11:57:03 +0930 | [diff] [blame] | 101 | virtual void readAndProcessNVMeSensor() = 0; |
Andrew Jeffery | 8c7074e | 2022-03-21 14:58:13 +1030 | [diff] [blame] | 102 | |
| 103 | virtual void processResponse(std::shared_ptr<NVMeSensor>& sensor, void* msg, |
| 104 | size_t len) = 0; |
Andrew Jeffery | a9d1508 | 2021-05-24 13:55:12 +0930 | [diff] [blame] | 105 | |
| 106 | protected: |
Ed Tanous | 9b4a20e | 2022-09-06 08:47:11 -0700 | [diff] [blame] | 107 | boost::asio::steady_timer scanTimer; |
Andrew Jeffery | b5d7a7f | 2022-05-02 11:57:03 +0930 | [diff] [blame] | 108 | int rootBus; // Root bus for this drive |
| 109 | std::list<std::shared_ptr<NVMeSensor>> sensors; |
| 110 | std::list<std::shared_ptr<NVMeSensor>>::iterator pollCursor; |
Andrew Jeffery | dae6e18 | 2021-05-21 16:23:07 +0930 | [diff] [blame] | 111 | }; |
| 112 | |
| 113 | using NVMEMap = boost::container::flat_map<int, std::shared_ptr<NVMeContext>>; |
| 114 | |
Ed Tanous | 201a101 | 2024-04-03 18:07:28 -0700 | [diff] [blame] | 115 | NVMEMap& getNVMEMap(); |