blob: 998f22d11885f1f13d7874d66d388c73ef404360 [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
George Liue9fb5c62021-07-01 14:05:32 +08005#include <phosphor-logging/lg2.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
17// Assert -or- De-assert
Vishwanatha Subbannaed490732016-12-20 15:59:29 +053018bool Manager::setGroupState(const std::string& path, bool assert,
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053019 group& ledsAssert, group& ledsDeAssert)
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053020{
21 if (assert)
22 {
23 assertedGroups.insert(&ledMap.at(path));
24 }
25 else
26 {
George Liu7f53a032021-05-04 11:18:21 +080027 if (assertedGroups.contains(&ledMap.at(path)))
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053028 {
29 assertedGroups.erase(&ledMap.at(path));
30 }
31 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053032
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053033 // This will contain the union of what's already in the asserted group
Patrick Venture91ac8d32018-11-01 17:03:22 -070034 group desiredState{};
35 for (const auto& grp : assertedGroups)
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053036 {
37 desiredState.insert(grp->cbegin(), grp->cend());
38 }
39
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053040 // Find difference between Combined and Desired to identify
41 // which LEDs are getting altered
Patrick Venture91ac8d32018-11-01 17:03:22 -070042 group transient{};
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053043 std::set_difference(combinedState.begin(), combinedState.end(),
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053044 desiredState.begin(), desiredState.end(),
Patrick Venture91ac8d32018-11-01 17:03:22 -070045 std::inserter(transient, transient.begin()), ledComp);
46 if (transient.size())
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053047 {
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053048 // Find common LEDs between transient and Desired to know if some LEDs
49 // are changing state and not really getting DeAsserted
Patrick Venture91ac8d32018-11-01 17:03:22 -070050 group ledsTransient{};
51 std::set_intersection(
52 transient.begin(), transient.end(), desiredState.begin(),
53 desiredState.end(),
54 std::inserter(ledsTransient, ledsTransient.begin()), ledLess);
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053055
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053056 // Find difference between above 2 to identify those LEDs which are
57 // really getting DeAsserted
Patrick Venture91ac8d32018-11-01 17:03:22 -070058 std::set_difference(transient.begin(), transient.end(),
59 ledsTransient.begin(), ledsTransient.end(),
Vishwanatha Subbanna447d0c82016-12-19 14:12:42 +053060 std::inserter(ledsDeAssert, ledsDeAssert.begin()),
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053061 ledLess);
Vishwanatha Subbanna447d0c82016-12-19 14:12:42 +053062
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053063 // Remove the elements from Current that are being DeAsserted.
Patrick Venture91ac8d32018-11-01 17:03:22 -070064 if (ledsDeAssert.size())
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053065 {
66 // Power off LEDs that are to be really DeAsserted
Patrick Venture91ac8d32018-11-01 17:03:22 -070067 for (auto& it : ledsDeAssert)
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053068 {
69 // Update LEDs in "physically asserted" set by removing those
70 // LEDs which are De-Asserted
71 auto found = currentState.find(it);
72 if (found != currentState.end())
73 {
74 currentState.erase(found);
75 }
76 }
77 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053078 }
79
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053080 // Now LEDs that are to be Asserted. These could either be fresh asserts
81 // -or- change between [On]<-->[Blink]
Patrick Venture91ac8d32018-11-01 17:03:22 -070082 group temp{};
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053083 std::unique_copy(desiredState.begin(), desiredState.end(),
Patrick Venture91ac8d32018-11-01 17:03:22 -070084 std::inserter(temp, temp.begin()), ledEqual);
85 if (temp.size())
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053086 {
87 // Find difference between [desired to be Asserted] and those LEDs
88 // that are physically asserted currently.
Patrick Venture91ac8d32018-11-01 17:03:22 -070089 std::set_difference(
90 temp.begin(), temp.end(), currentState.begin(), currentState.end(),
91 std::inserter(ledsAssert, ledsAssert.begin()), ledComp);
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053092 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053093
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053094 // Update the current actual and desired(the virtual actual)
95 currentState = std::move(temp);
96 combinedState = std::move(desiredState);
Vishwanatha Subbannaed490732016-12-20 15:59:29 +053097
98 // If we survive, then set the state accordingly.
99 return assert;
100}
101
George Liub6151622020-11-23 18:16:18 +0800102void Manager::setLampTestCallBack(
103 std::function<bool(group& ledsAssert, group& ledsDeAssert)> callBack)
104{
105 lampTestCallBack = callBack;
106}
107
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530108/** @brief Run through the map and apply action on the LEDs */
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +0530109void Manager::driveLEDs(group& ledsAssert, group& ledsDeAssert)
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530110{
George Liub6151622020-11-23 18:16:18 +0800111#ifdef USE_LAMP_TEST
112 // Use the lampTestCallBack method and trigger the callback method in the
113 // lamp test(processLEDUpdates), in this way, all lamp test operations
114 // are performed in the lamp test class.
115 if (lampTestCallBack(ledsAssert, ledsDeAssert))
116 {
117 return;
118 }
119#endif
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530120 // This order of LED operation is important.
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530121 if (ledsDeAssert.size())
122 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700123 for (const auto& it : ledsDeAssert)
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530124 {
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530125 std::string objPath = std::string(PHY_LED_PATH) + it.name;
George Liue9fb5c62021-07-01 14:05:32 +0800126 lg2::debug("De-Asserting LED, NAME = {NAME}", "NAME", it.name);
tony lee6fd9e442019-04-23 09:09:15 +0800127 drivePhysicalLED(objPath, Layout::Action::Off, it.dutyOn,
128 it.period);
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530129 }
130 }
131
Patrick Venture91ac8d32018-11-01 17:03:22 -0700132 if (ledsAssert.size())
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530133 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700134 for (const auto& it : ledsAssert)
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530135 {
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530136 std::string objPath = std::string(PHY_LED_PATH) + it.name;
George Liue9fb5c62021-07-01 14:05:32 +0800137 lg2::debug("Asserting LED, NAME = {NAME}", "NAME", it.name);
tony lee6fd9e442019-04-23 09:09:15 +0800138 drivePhysicalLED(objPath, it.action, it.dutyOn, it.period);
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530139 }
140 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530141 return;
142}
143
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530144// Calls into driving physical LED post choosing the action
145void Manager::drivePhysicalLED(const std::string& objPath,
tony lee6fd9e442019-04-23 09:09:15 +0800146 Layout::Action action, uint8_t dutyOn,
147 const uint16_t period)
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530148{
George Liu1c737af2020-10-16 09:07:02 +0800149 try
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530150 {
George Liu1c737af2020-10-16 09:07:02 +0800151 // If Blink, set its property
152 if (action == Layout::Action::Blink)
153 {
154 PropertyValue dutyOnValue{dutyOn};
155 PropertyValue periodValue{period};
156
157 dBusHandler.setProperty(objPath, PHY_LED_IFACE, "DutyOn",
158 dutyOnValue);
159 dBusHandler.setProperty(objPath, PHY_LED_IFACE, "Period",
160 periodValue);
161 }
162
163 PropertyValue actionValue{getPhysicalAction(action)};
164 dBusHandler.setProperty(objPath, PHY_LED_IFACE, "State", actionValue);
165 }
166 catch (const std::exception& e)
167 {
George Liue9fb5c62021-07-01 14:05:32 +0800168 lg2::error(
169 "Error setting property for physical LED, ERROR = {ERROR}, OBJECT_PATH = {PATH}",
170 "ERROR", e, "PATH", objPath);
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530171 }
Vishwanatha Subbannadcc3f382017-03-24 20:15:02 +0530172
Patrick Venture91ac8d32018-11-01 17:03:22 -0700173 return;
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530174}
175
176/** @brief Returns action string based on enum */
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530177std::string Manager::getPhysicalAction(Layout::Action action)
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530178{
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530179 namespace server = sdbusplus::xyz::openbmc_project::Led::server;
180
181 // TODO: openbmc/phosphor-led-manager#5
182 // Somehow need to use the generated Action enum than giving one
183 // in ledlayout.
Patrick Venture91ac8d32018-11-01 17:03:22 -0700184 if (action == Layout::Action::On)
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530185 {
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530186 return server::convertForMessage(server::Physical::Action::On);
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530187 }
Patrick Venture91ac8d32018-11-01 17:03:22 -0700188 else if (action == Layout::Action::Blink)
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530189 {
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530190 return server::convertForMessage(server::Physical::Action::Blink);
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530191 }
192 else
193 {
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530194 return server::convertForMessage(server::Physical::Action::Off);
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530195 }
196}
197
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530198} // namespace led
199} // namespace phosphor