blob: 4eb81e4abb474d1c26f0868b3b4ee82967bf1294 [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>
Andrew Jefferydae6e182021-05-21 16:23:07 +09307
8#include <memory>
Andrew Jeffery25e20bd2022-03-15 22:26:04 +10309#include <stdexcept>
Andrew Jefferydae6e182021-05-21 16:23:07 +093010
Andrew Jefferyfa500ae2021-05-21 16:46:36 +093011class NVMeContext : public std::enable_shared_from_this<NVMeContext>
Andrew Jefferydae6e182021-05-21 16:23:07 +093012{
Andrew Jefferyfa500ae2021-05-21 16:46:36 +093013 public:
Ed Tanous1f978632023-02-28 18:16:39 -080014 NVMeContext(boost::asio::io_context& io, int rootBus) :
Andrew Jefferyb5d7a7f2022-05-02 11:57:03 +093015 scanTimer(io), rootBus(rootBus), pollCursor(sensors.end())
Andrew Jeffery25e20bd2022-03-15 22:26:04 +103016 {
17 if (rootBus < 0)
18 {
19 throw std::invalid_argument(
20 "Invalid root bus: Bus ID must not be negative");
21 }
22 }
Andrew Jefferydae6e182021-05-21 16:23:07 +093023
Andrew Jefferya9d15082021-05-24 13:55:12 +093024 virtual ~NVMeContext()
25 {
Ed Tanousec77caa2023-02-17 10:46:06 -080026 scanTimer.cancel();
Andrew Jefferya9d15082021-05-24 13:55:12 +093027 }
Andrew Jefferydae6e182021-05-21 16:23:07 +093028
Ed Tanous74cffa82022-01-25 13:00:28 -080029 void addSensor(const std::shared_ptr<NVMeSensor>& sensor)
Andrew Jefferya9d15082021-05-24 13:55:12 +093030 {
31 sensors.emplace_back(sensor);
32 }
Andrew Jefferydae6e182021-05-21 16:23:07 +093033
Andrew Jeffery3db6f9c2021-12-08 10:55:47 +103034 std::optional<std::shared_ptr<NVMeSensor>>
35 getSensorAtPath(const std::string& path)
36 {
37 for (auto& sensor : sensors)
38 {
39 if (sensor->configurationPath == path)
40 {
41 return sensor;
42 }
43 }
44
45 return std::nullopt;
46 }
47
Andrew Jefferyb5d7a7f2022-05-02 11:57:03 +093048 // Post-condition: The sensor list does not contain the provided sensor
49 // Post-condition: pollCursor is a valid iterator for the sensor list
Ed Tanous74cffa82022-01-25 13:00:28 -080050 void removeSensor(const std::shared_ptr<NVMeSensor>& sensor)
Andrew Jeffery3db6f9c2021-12-08 10:55:47 +103051 {
Andrew Jefferyb5d7a7f2022-05-02 11:57:03 +093052 // Locate the sensor that we're removing in the sensor list
53 auto found = std::find(sensors.begin(), sensors.end(), sensor);
54
55 // If we failed to find the sensor in the list the post-condition is
56 // already satisfied
57 if (found == sensors.end())
58 {
59 return;
60 }
61
62 // We've found the sensor in the list
63
64 // If we're not actively polling the sensor list, then remove the sensor
65 if (pollCursor == sensors.end())
66 {
67 sensors.erase(found);
68 return;
69 }
70
71 // We're actively polling the sensor list
72
73 // If we're not polling the specific sensor that has been removed, then
74 // remove the sensor
75 if (*pollCursor != *found)
76 {
77 sensors.erase(found);
78 return;
79 }
80
81 // We're polling the sensor that is being removed
82
83 // Remove the sensor and update the poll cursor so the cursor remains
84 // valid
85 pollCursor = sensors.erase(found);
Andrew Jeffery3db6f9c2021-12-08 10:55:47 +103086 }
87
Andrew Jefferya9d15082021-05-24 13:55:12 +093088 virtual void close()
89 {
90 scanTimer.cancel();
91 }
92
Andrew Jeffery8c7074e2022-03-21 14:58:13 +103093 virtual void pollNVMeDevices() = 0;
Andrew Jefferya9d15082021-05-24 13:55:12 +093094
Andrew Jefferyb5d7a7f2022-05-02 11:57:03 +093095 virtual void readAndProcessNVMeSensor() = 0;
Andrew Jeffery8c7074e2022-03-21 14:58:13 +103096
97 virtual void processResponse(std::shared_ptr<NVMeSensor>& sensor, void* msg,
98 size_t len) = 0;
Andrew Jefferya9d15082021-05-24 13:55:12 +093099
100 protected:
Ed Tanous9b4a20e2022-09-06 08:47:11 -0700101 boost::asio::steady_timer scanTimer;
Andrew Jefferyb5d7a7f2022-05-02 11:57:03 +0930102 int rootBus; // Root bus for this drive
103 std::list<std::shared_ptr<NVMeSensor>> sensors;
104 std::list<std::shared_ptr<NVMeSensor>>::iterator pollCursor;
Andrew Jefferydae6e182021-05-21 16:23:07 +0930105};
106
107using NVMEMap = boost::container::flat_map<int, std::shared_ptr<NVMeContext>>;
108
Ed Tanous201a1012024-04-03 18:07:28 -0700109NVMEMap& getNVMEMap();