blob: e2ada1b5e25950ee58e6bfe728fa07421535fdfc [file] [log] [blame]
Andrew Jefferydae6e182021-05-21 16:23:07 +09301#pragma once
2
3#include "NVMeSensor.hpp"
4
Ed Tanous1f978632023-02-28 18:16:39 -08005#include <boost/asio/io_context.hpp>
Ed Tanous9b4a20e2022-09-06 08:47:11 -07006#include <boost/asio/steady_timer.hpp>
Ed Tanous18b61862025-01-30 10:56:28 -08007#include <boost/container/flat_map.hpp>
Andrew Jefferydae6e182021-05-21 16:23:07 +09308
Ed Tanous18b61862025-01-30 10:56:28 -08009#include <algorithm>
10#include <cstddef>
11#include <list>
Andrew Jefferydae6e182021-05-21 16:23:07 +093012#include <memory>
Ed Tanous18b61862025-01-30 10:56:28 -080013#include <optional>
Andrew Jeffery25e20bd2022-03-15 22:26:04 +103014#include <stdexcept>
Ed Tanous18b61862025-01-30 10:56:28 -080015#include <string>
Andrew Jefferydae6e182021-05-21 16:23:07 +093016
Andrew Jefferyfa500ae2021-05-21 16:46:36 +093017class NVMeContext : public std::enable_shared_from_this<NVMeContext>
Andrew Jefferydae6e182021-05-21 16:23:07 +093018{
Andrew Jefferyfa500ae2021-05-21 16:46:36 +093019 public:
Ed Tanous1f978632023-02-28 18:16:39 -080020 NVMeContext(boost::asio::io_context& io, int rootBus) :
Andrew Jefferyb5d7a7f2022-05-02 11:57:03 +093021 scanTimer(io), rootBus(rootBus), pollCursor(sensors.end())
Andrew Jeffery25e20bd2022-03-15 22:26:04 +103022 {
23 if (rootBus < 0)
24 {
25 throw std::invalid_argument(
26 "Invalid root bus: Bus ID must not be negative");
27 }
28 }
Andrew Jefferydae6e182021-05-21 16:23:07 +093029
Andrew Jefferya9d15082021-05-24 13:55:12 +093030 virtual ~NVMeContext()
31 {
Ed Tanousec77caa2023-02-17 10:46:06 -080032 scanTimer.cancel();
Andrew Jefferya9d15082021-05-24 13:55:12 +093033 }
Andrew Jefferydae6e182021-05-21 16:23:07 +093034
Ed Tanous74cffa82022-01-25 13:00:28 -080035 void addSensor(const std::shared_ptr<NVMeSensor>& sensor)
Andrew Jefferya9d15082021-05-24 13:55:12 +093036 {
37 sensors.emplace_back(sensor);
38 }
Andrew Jefferydae6e182021-05-21 16:23:07 +093039
Andrew Jeffery3db6f9c2021-12-08 10:55:47 +103040 std::optional<std::shared_ptr<NVMeSensor>>
41 getSensorAtPath(const std::string& path)
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 Jefferyb5d7a7f2022-05-02 11:57:03 +093054 // Post-condition: The sensor list does not contain the provided sensor
55 // Post-condition: pollCursor is a valid iterator for the sensor list
Ed Tanous74cffa82022-01-25 13:00:28 -080056 void removeSensor(const std::shared_ptr<NVMeSensor>& sensor)
Andrew Jeffery3db6f9c2021-12-08 10:55:47 +103057 {
Andrew Jefferyb5d7a7f2022-05-02 11:57:03 +093058 // 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 Jeffery3db6f9c2021-12-08 10:55:47 +103092 }
93
Andrew Jefferya9d15082021-05-24 13:55:12 +093094 virtual void close()
95 {
96 scanTimer.cancel();
97 }
98
Andrew Jeffery8c7074e2022-03-21 14:58:13 +103099 virtual void pollNVMeDevices() = 0;
Andrew Jefferya9d15082021-05-24 13:55:12 +0930100
Andrew Jefferyb5d7a7f2022-05-02 11:57:03 +0930101 virtual void readAndProcessNVMeSensor() = 0;
Andrew Jeffery8c7074e2022-03-21 14:58:13 +1030102
103 virtual void processResponse(std::shared_ptr<NVMeSensor>& sensor, void* msg,
104 size_t len) = 0;
Andrew Jefferya9d15082021-05-24 13:55:12 +0930105
106 protected:
Ed Tanous9b4a20e2022-09-06 08:47:11 -0700107 boost::asio::steady_timer scanTimer;
Andrew Jefferyb5d7a7f2022-05-02 11:57:03 +0930108 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 Jefferydae6e182021-05-21 16:23:07 +0930111};
112
113using NVMEMap = boost::container::flat_map<int, std::shared_ptr<NVMeContext>>;
114
Ed Tanous201a1012024-04-03 18:07:28 -0700115NVMEMap& getNVMEMap();