blob: fe0f60582ca22bb5674f0abada8e9c6c2ed2279a [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 {
George Liu7f53a032021-05-04 11:18:21 +080029 if (assertedGroups.contains(&ledMap.at(path)))
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053030 {
31 assertedGroups.erase(&ledMap.at(path));
32 }
33 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053034
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053035 // This will contain the union of what's already in the asserted group
Patrick Venture91ac8d32018-11-01 17:03:22 -070036 group desiredState{};
37 for (const auto& grp : assertedGroups)
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053038 {
39 desiredState.insert(grp->cbegin(), grp->cend());
40 }
41
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053042 // Find difference between Combined and Desired to identify
43 // which LEDs are getting altered
Patrick Venture91ac8d32018-11-01 17:03:22 -070044 group transient{};
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053045 std::set_difference(combinedState.begin(), combinedState.end(),
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053046 desiredState.begin(), desiredState.end(),
Patrick Venture91ac8d32018-11-01 17:03:22 -070047 std::inserter(transient, transient.begin()), ledComp);
48 if (transient.size())
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053049 {
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053050 // Find common LEDs between transient and Desired to know if some LEDs
51 // are changing state and not really getting DeAsserted
Patrick Venture91ac8d32018-11-01 17:03:22 -070052 group ledsTransient{};
53 std::set_intersection(
54 transient.begin(), transient.end(), desiredState.begin(),
55 desiredState.end(),
56 std::inserter(ledsTransient, ledsTransient.begin()), ledLess);
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053057
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053058 // Find difference between above 2 to identify those LEDs which are
59 // really getting DeAsserted
Patrick Venture91ac8d32018-11-01 17:03:22 -070060 std::set_difference(transient.begin(), transient.end(),
61 ledsTransient.begin(), ledsTransient.end(),
Vishwanatha Subbanna447d0c82016-12-19 14:12:42 +053062 std::inserter(ledsDeAssert, ledsDeAssert.begin()),
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053063 ledLess);
Vishwanatha Subbanna447d0c82016-12-19 14:12:42 +053064
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053065 // Remove the elements from Current that are being DeAsserted.
Patrick Venture91ac8d32018-11-01 17:03:22 -070066 if (ledsDeAssert.size())
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053067 {
68 // Power off LEDs that are to be really DeAsserted
Patrick Venture91ac8d32018-11-01 17:03:22 -070069 for (auto& it : ledsDeAssert)
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053070 {
71 // Update LEDs in "physically asserted" set by removing those
72 // LEDs which are De-Asserted
73 auto found = currentState.find(it);
74 if (found != currentState.end())
75 {
76 currentState.erase(found);
77 }
78 }
79 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053080 }
81
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053082 // Now LEDs that are to be Asserted. These could either be fresh asserts
83 // -or- change between [On]<-->[Blink]
Patrick Venture91ac8d32018-11-01 17:03:22 -070084 group temp{};
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053085 std::unique_copy(desiredState.begin(), desiredState.end(),
Patrick Venture91ac8d32018-11-01 17:03:22 -070086 std::inserter(temp, temp.begin()), ledEqual);
87 if (temp.size())
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053088 {
89 // Find difference between [desired to be Asserted] and those LEDs
90 // that are physically asserted currently.
Patrick Venture91ac8d32018-11-01 17:03:22 -070091 std::set_difference(
92 temp.begin(), temp.end(), currentState.begin(), currentState.end(),
93 std::inserter(ledsAssert, ledsAssert.begin()), ledComp);
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053094 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +053095
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +053096 // Update the current actual and desired(the virtual actual)
97 currentState = std::move(temp);
98 combinedState = std::move(desiredState);
Vishwanatha Subbannaed490732016-12-20 15:59:29 +053099
100 // If we survive, then set the state accordingly.
101 return assert;
102}
103
George Liub6151622020-11-23 18:16:18 +0800104void Manager::setLampTestCallBack(
105 std::function<bool(group& ledsAssert, group& ledsDeAssert)> callBack)
106{
107 lampTestCallBack = callBack;
108}
109
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530110/** @brief Run through the map and apply action on the LEDs */
Vishwanatha Subbanna4b000d82017-05-03 18:44:16 +0530111void Manager::driveLEDs(group& ledsAssert, group& ledsDeAssert)
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530112{
George Liub6151622020-11-23 18:16:18 +0800113#ifdef USE_LAMP_TEST
114 // Use the lampTestCallBack method and trigger the callback method in the
115 // lamp test(processLEDUpdates), in this way, all lamp test operations
116 // are performed in the lamp test class.
117 if (lampTestCallBack(ledsAssert, ledsDeAssert))
118 {
119 return;
120 }
121#endif
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530122 // This order of LED operation is important.
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530123 if (ledsDeAssert.size())
124 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700125 for (const auto& it : ledsDeAssert)
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530126 {
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530127 std::string objPath = std::string(PHY_LED_PATH) + it.name;
Patrick Venture91ac8d32018-11-01 17:03:22 -0700128 log<level::DEBUG>("De-Asserting LED",
129 entry("NAME=%s", it.name.c_str()));
tony lee6fd9e442019-04-23 09:09:15 +0800130 drivePhysicalLED(objPath, Layout::Action::Off, it.dutyOn,
131 it.period);
Vishwanatha Subbannaed490732016-12-20 15:59:29 +0530132 }
133 }
134
Patrick Venture91ac8d32018-11-01 17:03:22 -0700135 if (ledsAssert.size())
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530136 {
Patrick Venture91ac8d32018-11-01 17:03:22 -0700137 for (const auto& it : ledsAssert)
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530138 {
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530139 std::string objPath = std::string(PHY_LED_PATH) + it.name;
Patrick Venture91ac8d32018-11-01 17:03:22 -0700140 log<level::DEBUG>("Asserting LED",
141 entry("NAME=%s", it.name.c_str()));
tony lee6fd9e442019-04-23 09:09:15 +0800142 drivePhysicalLED(objPath, it.action, it.dutyOn, it.period);
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530143 }
144 }
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530145 return;
146}
147
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530148// Calls into driving physical LED post choosing the action
149void Manager::drivePhysicalLED(const std::string& objPath,
tony lee6fd9e442019-04-23 09:09:15 +0800150 Layout::Action action, uint8_t dutyOn,
151 const uint16_t period)
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530152{
George Liu1c737af2020-10-16 09:07:02 +0800153 try
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530154 {
George Liu1c737af2020-10-16 09:07:02 +0800155 // If Blink, set its property
156 if (action == Layout::Action::Blink)
157 {
158 PropertyValue dutyOnValue{dutyOn};
159 PropertyValue periodValue{period};
160
161 dBusHandler.setProperty(objPath, PHY_LED_IFACE, "DutyOn",
162 dutyOnValue);
163 dBusHandler.setProperty(objPath, PHY_LED_IFACE, "Period",
164 periodValue);
165 }
166
167 PropertyValue actionValue{getPhysicalAction(action)};
168 dBusHandler.setProperty(objPath, PHY_LED_IFACE, "State", actionValue);
169 }
170 catch (const std::exception& e)
171 {
172 log<level::ERR>("Error setting property for physical LED",
173 entry("ERROR=%s", e.what()),
174 entry("OBJECT_PATH=%s", objPath.c_str()));
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530175 }
Vishwanatha Subbannadcc3f382017-03-24 20:15:02 +0530176
Patrick Venture91ac8d32018-11-01 17:03:22 -0700177 return;
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530178}
179
180/** @brief Returns action string based on enum */
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530181std::string Manager::getPhysicalAction(Layout::Action action)
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530182{
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530183 namespace server = sdbusplus::xyz::openbmc_project::Led::server;
184
185 // TODO: openbmc/phosphor-led-manager#5
186 // Somehow need to use the generated Action enum than giving one
187 // in ledlayout.
Patrick Venture91ac8d32018-11-01 17:03:22 -0700188 if (action == Layout::Action::On)
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530189 {
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530190 return server::convertForMessage(server::Physical::Action::On);
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530191 }
Patrick Venture91ac8d32018-11-01 17:03:22 -0700192 else if (action == Layout::Action::Blink)
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530193 {
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530194 return server::convertForMessage(server::Physical::Action::Blink);
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530195 }
196 else
197 {
Vishwanatha Subbanna4fa92482017-03-10 14:39:20 +0530198 return server::convertForMessage(server::Physical::Action::Off);
Vishwanatha Subbanna11ca8f92017-02-27 19:33:45 +0530199 }
200}
201
Vishwanatha Subbanna4c8c72b2016-11-29 23:02:06 +0530202} // namespace led
203} // namespace phosphor