blob: 6f286df0f27b66c777a15917170b086486811306 [file] [log] [blame]
George Liub6151622020-11-23 18:16:18 +08001#include "config.h"
2
Patrick Venture91ac8d32018-11-01 17:03:22 -07003#include "manager.hpp"
4
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +05305#include <phosphor-logging/log.hpp>
William A. Kennington III151122a2018-05-15 12:00:32 -07006#include <sdbusplus/exception.hpp>
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +05307#include <xyz/openbmc_project/Led/Physical/server.hpp>
George Liua6c18f82020-06-22 10:50:04 +08008
9#include <algorithm>
10#include <iostream>
11#include <string>
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053012namespace phosphor
13{
14namespace led
15{
16
George Liu1c737af2020-10-16 09:07:02 +080017using namespace phosphor::logging;
18
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053019// Assert -or- De-assert
Vishwanatha Subbannaed490732016-12-20 15:59:29 +053020bool Manager::setGroupState(const std::string& path, bool assert,
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053021 group& ledsAssert, group& ledsDeAssert)
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053022{
23 if (assert)
24 {
25 assertedGroups.insert(&ledMap.at(path));
26 }
27 else
28 {
29 auto search = assertedGroups.find(&ledMap.at(path));
30 if (search != assertedGroups.end())
31 {
32 assertedGroups.erase(&ledMap.at(path));
33 }
34 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053035
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053036 // This will contain the union of what's already in the asserted group
Patrick Venture91ac8d32018-11-01 17:03:22 -070037 group desiredState{};
38 for (const auto& grp : assertedGroups)
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053039 {
40 desiredState.insert(grp->cbegin(), grp->cend());
41 }
42
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053043 // Find difference between Combined and Desired to identify
44 // which LEDs are getting altered
Patrick Venture91ac8d32018-11-01 17:03:22 -070045 group transient{};
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053046 std::set_difference(combinedState.begin(), combinedState.end(),
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053047 desiredState.begin(), desiredState.end(),
Patrick Venture91ac8d32018-11-01 17:03:22 -070048 std::inserter(transient, transient.begin()), ledComp);
49 if (transient.size())
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053050 {
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053051 // Find common LEDs between transient and Desired to know if some LEDs
52 // are changing state and not really getting DeAsserted
Patrick Venture91ac8d32018-11-01 17:03:22 -070053 group ledsTransient{};
54 std::set_intersection(
55 transient.begin(), transient.end(), desiredState.begin(),
56 desiredState.end(),
57 std::inserter(ledsTransient, ledsTransient.begin()), ledLess);
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053058
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053059 // Find difference between above 2 to identify those LEDs which are
60 // really getting DeAsserted
Patrick Venture91ac8d32018-11-01 17:03:22 -070061 std::set_difference(transient.begin(), transient.end(),
62 ledsTransient.begin(), ledsTransient.end(),
Vishwanatha Subbanna447d0c82016-12-19 14:12:42 +053063 std::inserter(ledsDeAssert, ledsDeAssert.begin()),
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053064 ledLess);
Vishwanatha Subbanna447d0c82016-12-19 14:12:42 +053065
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053066 // Remove the elements from Current that are being DeAsserted.
Patrick Venture91ac8d32018-11-01 17:03:22 -070067 if (ledsDeAssert.size())
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053068 {
69 // Power off LEDs that are to be really DeAsserted
Patrick Venture91ac8d32018-11-01 17:03:22 -070070 for (auto& it : ledsDeAssert)
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053071 {
72 // Update LEDs in "physically asserted" set by removing those
73 // LEDs which are De-Asserted
74 auto found = currentState.find(it);
75 if (found != currentState.end())
76 {
77 currentState.erase(found);
78 }
79 }
80 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053081 }
82
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053083 // Now LEDs that are to be Asserted. These could either be fresh asserts
84 // -or- change between [On]<-->[Blink]
Patrick Venture91ac8d32018-11-01 17:03:22 -070085 group temp{};
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053086 std::unique_copy(desiredState.begin(), desiredState.end(),
Patrick Venture91ac8d32018-11-01 17:03:22 -070087 std::inserter(temp, temp.begin()), ledEqual);
88 if (temp.size())
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053089 {
90 // Find difference between [desired to be Asserted] and those LEDs
91 // that are physically asserted currently.
Patrick Venture91ac8d32018-11-01 17:03:22 -070092 std::set_difference(
93 temp.begin(), temp.end(), currentState.begin(), currentState.end(),
94 std::inserter(ledsAssert, ledsAssert.begin()), ledComp);
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053095 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053096
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053097 // Update the current actual and desired(the virtual actual)
98 currentState = std::move(temp);
99 combinedState = std::move(desiredState);
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530100
101 // If we survive, then set the state accordingly.
102 return assert;
103}
104
George Liub6151622020-11-23 18:16:18 +0800105void Manager::setLampTestCallBack(
106 std::function<bool(group& ledsAssert, group& ledsDeAssert)> callBack)
107{
108 lampTestCallBack = callBack;
109}
110
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530111/** @brief Run through the map and apply action on the LEDs */
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +0530112void Manager::driveLEDs(group& ledsAssert, group& ledsDeAssert)
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530113{
George Liub6151622020-11-23 18:16:18 +0800114#ifdef USE_LAMP_TEST
115 // Use the lampTestCallBack method and trigger the callback method in the
116 // lamp test(processLEDUpdates), in this way, all lamp test operations
117 // are performed in the lamp test class.
118 if (lampTestCallBack(ledsAssert, ledsDeAssert))
119 {
120 return;
121 }
122#endif
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530123 // This order of LED operation is important.
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530124 if (ledsDeAssert.size())
125 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700126 for (const auto& it : ledsDeAssert)
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530127 {
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530128 std::string objPath = std::string(PHY_LED_PATH) + it.name;
Patrick Venture91ac8d32018-11-01 17:03:22 -0700129 log<level::DEBUG>("De-Asserting LED",
130 entry("NAME=%s", it.name.c_str()));
tony lee6fd9e442019-04-23 09:09:15 +0800131 drivePhysicalLED(objPath, Layout::Action::Off, it.dutyOn,
132 it.period);
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530133 }
134 }
135
Patrick Venture91ac8d32018-11-01 17:03:22 -0700136 if (ledsAssert.size())
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530137 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700138 for (const auto& it : ledsAssert)
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530139 {
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530140 std::string objPath = std::string(PHY_LED_PATH) + it.name;
Patrick Venture91ac8d32018-11-01 17:03:22 -0700141 log<level::DEBUG>("Asserting LED",
142 entry("NAME=%s", it.name.c_str()));
tony lee6fd9e442019-04-23 09:09:15 +0800143 drivePhysicalLED(objPath, it.action, it.dutyOn, it.period);
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530144 }
145 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530146 return;
147}
148
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530149// Calls into driving physical LED post choosing the action
150void Manager::drivePhysicalLED(const std::string& objPath,
tony lee6fd9e442019-04-23 09:09:15 +0800151 Layout::Action action, uint8_t dutyOn,
152 const uint16_t period)
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530153{
George Liu1c737af2020-10-16 09:07:02 +0800154 try
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530155 {
George Liu1c737af2020-10-16 09:07:02 +0800156 // If Blink, set its property
157 if (action == Layout::Action::Blink)
158 {
159 PropertyValue dutyOnValue{dutyOn};
160 PropertyValue periodValue{period};
161
162 dBusHandler.setProperty(objPath, PHY_LED_IFACE, "DutyOn",
163 dutyOnValue);
164 dBusHandler.setProperty(objPath, PHY_LED_IFACE, "Period",
165 periodValue);
166 }
167
168 PropertyValue actionValue{getPhysicalAction(action)};
169 dBusHandler.setProperty(objPath, PHY_LED_IFACE, "State", actionValue);
170 }
171 catch (const std::exception& e)
172 {
173 log<level::ERR>("Error setting property for physical LED",
174 entry("ERROR=%s", e.what()),
175 entry("OBJECT_PATH=%s", objPath.c_str()));
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530176 }
Vishwanatha Subbannadcc3f382017-03-24 20:15:02 +0530177
Patrick Venture91ac8d32018-11-01 17:03:22 -0700178 return;
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530179}
180
181/** @brief Returns action string based on enum */
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530182std::string Manager::getPhysicalAction(Layout::Action action)
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530183{
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530184 namespace server = sdbusplus::xyz::openbmc_project::Led::server;
185
186 // TODO: openbmc/phosphor-led-manager#5
187 // Somehow need to use the generated Action enum than giving one
188 // in ledlayout.
Patrick Venture91ac8d32018-11-01 17:03:22 -0700189 if (action == Layout::Action::On)
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530190 {
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530191 return server::convertForMessage(server::Physical::Action::On);
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530192 }
Patrick Venture91ac8d32018-11-01 17:03:22 -0700193 else if (action == Layout::Action::Blink)
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530194 {
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530195 return server::convertForMessage(server::Physical::Action::Blink);
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530196 }
197 else
198 {
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530199 return server::convertForMessage(server::Physical::Action::Off);
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530200 }
201}
202
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530203} // namespace led
204} // namespace phosphor