blob: f1254cbdb26bcea500b6ca547f60ef36435d0a36 [file] [log] [blame]
Nikhil Potadeb669b6b2019-03-13 10:52:21 -07001/*
2// Copyright (c) 2019 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16
Andrew Jefferye3e3c972021-05-26 14:37:07 +093017#include <NVMeBasicContext.hpp>
Andrew Jefferydae6e182021-05-21 16:23:07 +093018#include <NVMeContext.hpp>
Andrew Jefferya9d15082021-05-24 13:55:12 +093019#include <NVMeMCTPContext.hpp>
Ed Tanous8a57ec02020-10-09 12:46:52 -070020#include <NVMeSensor.hpp>
Nikhil Potadeb669b6b2019-03-13 10:52:21 -070021#include <boost/asio/deadline_timer.hpp>
James Feist38fb5982020-05-28 10:09:54 -070022
Nikhil Potadeb669b6b2019-03-13 10:52:21 -070023#include <regex>
24
25static constexpr const char* sensorType =
26 "xyz.openbmc_project.Configuration.NVME1000";
27
28static NVMEMap nvmeDeviceMap;
29
Ed Tanous8a57ec02020-10-09 12:46:52 -070030static constexpr bool debug = false;
Nikhil Potadeb669b6b2019-03-13 10:52:21 -070031
32NVMEMap& getNVMEMap()
33{
34 return nvmeDeviceMap;
35}
36
37void createSensors(boost::asio::io_service& io,
38 sdbusplus::asio::object_server& objectServer,
39 std::shared_ptr<sdbusplus::asio::connection>& dbusConnection)
40{
41
42 auto getter = std::make_shared<GetSensorConfiguration>(
43 dbusConnection,
44 std::move([&io, &objectServer, &dbusConnection](
45 const ManagedObjectType& sensorConfigurations) {
46 // todo: it'd be better to only update the ones we care about
James Feist375ade22020-07-16 16:32:10 -070047 for (const auto& [_, nvmeContextPtr] : nvmeDeviceMap)
48 {
49 if (nvmeContextPtr)
50 {
51 nvmeContextPtr->close();
52 }
53 }
Nikhil Potadeb669b6b2019-03-13 10:52:21 -070054 nvmeDeviceMap.clear();
55
56 // iterate through all found configurations
57 for (const std::pair<sdbusplus::message::object_path, SensorData>&
58 sensor : sensorConfigurations)
59 {
60 const SensorData& sensorData = sensor.second;
61 const std::string& interfacePath = sensor.first.str;
62 const std::pair<
63 std::string,
64 boost::container::flat_map<std::string, BasicVariantType>>*
65 baseConfiguration = nullptr;
66
67 // find base configuration
68 auto sensorBase = sensor.second.find(sensorType);
69 if (sensorBase != sensor.second.end())
70 {
71 baseConfiguration = &(*sensorBase);
72 }
73
74 if (baseConfiguration == nullptr)
75 {
76 continue;
77 }
78 auto findBus = baseConfiguration->second.find("Bus");
79 if (findBus == baseConfiguration->second.end())
80 {
81 continue;
82 }
83
Andrew Jeffery9f315582021-05-25 13:32:14 +093084 int busNumber =
85 std::visit(VariantToIntVisitor(), findBus->second);
Nikhil Potadeb669b6b2019-03-13 10:52:21 -070086
87 auto findSensorName = baseConfiguration->second.find("Name");
88 if (findSensorName == baseConfiguration->second.end())
89 {
90 std::cerr << "could not determine configuration name for "
91 << interfacePath << "\n";
92 continue;
93 }
94 std::string sensorName =
95 std::get<std::string>(findSensorName->second);
96
97 std::vector<thresholds::Threshold> sensorThresholds;
98
99 if (!parseThresholdsFromConfig(sensorData, sensorThresholds))
100 {
101 std::cerr << "error populating thresholds for "
102 << sensorName << "\n";
103 }
104
105 int rootBus = busNumber;
106
107 std::string muxPath = "/sys/bus/i2c/devices/i2c-" +
108 std::to_string(busNumber) + "/mux_device";
109
110 if (std::filesystem::is_symlink(muxPath))
111 {
112 std::string rootName =
113 std::filesystem::read_symlink(muxPath).filename();
Andrew Jefferyc12ceac2021-05-25 13:34:06 +0930114 size_t dash = rootName.find('-');
Nikhil Potadeb669b6b2019-03-13 10:52:21 -0700115 if (dash == std::string::npos)
116 {
117 std::cerr << "Error finding root bus for " << rootName
118 << "\n";
119 continue;
120 }
121 rootBus = std::stoi(rootName.substr(0, dash));
122 }
123
124 std::shared_ptr<NVMeContext> context;
125 auto findRoot = nvmeDeviceMap.find(rootBus);
126 if (findRoot != nvmeDeviceMap.end())
127 {
128 context = findRoot->second;
129 }
130 else
131 {
Andrew Jefferya9d15082021-05-24 13:55:12 +0930132 context = std::make_shared<NVMeMCTPContext>(io, rootBus);
Nikhil Potadeb669b6b2019-03-13 10:52:21 -0700133 nvmeDeviceMap[rootBus] = context;
134 }
135
136 std::shared_ptr<NVMeSensor> sensorPtr =
137 std::make_shared<NVMeSensor>(
138 objectServer, io, dbusConnection, sensorName,
139 std::move(sensorThresholds), interfacePath, busNumber);
140
Andrew Jefferyfa500ae2021-05-21 16:46:36 +0930141 context->addSensor(sensorPtr);
Nikhil Potadeb669b6b2019-03-13 10:52:21 -0700142 }
143 for (const auto& [_, context] : nvmeDeviceMap)
144 {
145 context->pollNVMeDevices();
146 }
147 }));
148 getter->getConfiguration(std::vector<std::string>{sensorType});
149}
150
151int main()
152{
153 boost::asio::io_service io;
154 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
155 systemBus->request_name("xyz.openbmc_project.NVMeSensor");
156 sdbusplus::asio::object_server objectServer(systemBus);
157 nvmeMCTP::init();
158
159 io.post([&]() { createSensors(io, objectServer, systemBus); });
160
161 boost::asio::deadline_timer filterTimer(io);
162 std::function<void(sdbusplus::message::message&)> eventHandler =
163 [&filterTimer, &io, &objectServer,
James Feist7d7579f2020-09-02 14:13:08 -0700164 &systemBus](sdbusplus::message::message&) {
Nikhil Potadeb669b6b2019-03-13 10:52:21 -0700165 // this implicitly cancels the timer
166 filterTimer.expires_from_now(boost::posix_time::seconds(1));
167
168 filterTimer.async_wait([&](const boost::system::error_code& ec) {
169 if (ec == boost::asio::error::operation_aborted)
170 {
171 return; // we're being canceled
172 }
Andrew Jeffery7279f932021-05-25 13:35:27 +0930173
174 if (ec)
Nikhil Potadeb669b6b2019-03-13 10:52:21 -0700175 {
176 std::cerr << "Error: " << ec.message() << "\n";
177 return;
178 }
179
180 createSensors(io, objectServer, systemBus);
181 });
182 };
183
184 sdbusplus::bus::match::match configMatch(
185 static_cast<sdbusplus::bus::bus&>(*systemBus),
186 "type='signal',member='PropertiesChanged',path_namespace='" +
187 std::string(inventoryPath) + "',arg0namespace='" +
188 std::string(sensorType) + "'",
189 eventHandler);
190
Bruce Lee1263c3d2021-06-04 15:16:33 +0800191 setupManufacturingModeMatch(*systemBus);
Nikhil Potadeb669b6b2019-03-13 10:52:21 -0700192 io.run();
193}