1 
2 #include "hostSelector_switch.hpp"
3 
4 #include <error.h>
5 
6 #include <phosphor-logging/lg2.hpp>
7 
8 // add the button iface class to registry
9 static ButtonIFRegister<HostSelector> buttonRegister;
10 
11 size_t HostSelector::getMappedHSConfig(size_t hsPosition)
12 {
13     size_t adjustedPosition = INVALID_INDEX; // set bmc as default value
14     std::string hsPosStr;
15     hsPosStr = std::to_string(hsPosition);
16 
17     if (hsPosMap.find(hsPosStr) != hsPosMap.end())
18     {
19         adjustedPosition = hsPosMap[hsPosStr];
20     }
21     else
22     {
23         lg2::debug("getMappedHSConfig : {TYPE}: no valid value in map.", "TYPE",
24                    getFormFactorType());
25     }
26     return adjustedPosition;
27 }
28 
29 size_t HostSelector::getGpioIndex(int fd)
30 {
31     for (size_t index = 0; index < gpioLineCount; index++)
32     {
33         if (config.gpios[index].fd == fd)
34         {
35             return index;
36         }
37     }
38     return INVALID_INDEX;
39 }
40 void HostSelector::setInitialHostSelectorValue()
41 {
42     char buf;
43     for (size_t index = 0; index < gpioLineCount; index++)
44     {
45         auto result = ::lseek(config.gpios[index].fd, 0, SEEK_SET);
46 
47         if (result < 0)
48         {
49             lg2::error("{TYPE}: Gpio fd lseek error: {ERROR}", "TYPE",
50                        getFormFactorType(), "ERROR", errno);
51             throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
52                 IOError();
53         }
54 
55         result = ::read(config.gpios[index].fd, &buf, sizeof(buf));
56         if (result < 0)
57         {
58             lg2::error("{TYPE}: Gpio fd read error: {ERROR}", "TYPE",
59                        getFormFactorType(), "ERROR", errno);
60             throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
61                 IOError();
62         }
63         GpioState gpioState = (buf == '0') ? (GpioState::deassert)
64                                            : (GpioState::assert);
65         setHostSelectorValue(config.gpios[index].fd, gpioState);
66         size_t hsPosMapped = getMappedHSConfig(hostSelectorPosition);
67         if (hsPosMapped != INVALID_INDEX)
68         {
69             position(hsPosMapped, true);
70         }
71     }
72 }
73 
74 void HostSelector::setHostSelectorValue(int fd, GpioState state)
75 {
76     size_t pos = getGpioIndex(fd);
77 
78     if (pos == INVALID_INDEX)
79     {
80         return;
81     }
82     auto set_bit = [](size_t& val, size_t n) { val |= 0xff & (1 << n); };
83 
84     auto clr_bit = [](size_t& val, size_t n) { val &= ~(0xff & (1 << n)); };
85 
86     auto bit_op = (state == GpioState::deassert) ? set_bit : clr_bit;
87 
88     bit_op(hostSelectorPosition, pos);
89     return;
90 }
91 /**
92  * @brief This method is called from sd-event provided callback function
93  * callbackHandler if platform specific event handling is needed then a
94  * derived class instance with its specific event handling logic along with
95  * init() function can be created to override the default event handling
96  */
97 
98 void HostSelector::handleEvent(sd_event_source* /* es */, int fd,
99                                uint32_t /* revents */)
100 {
101     int n = -1;
102     char buf = '0';
103 
104     n = ::lseek(fd, 0, SEEK_SET);
105 
106     if (n < 0)
107     {
108         lg2::error("{TYPE}: Gpio fd lseek error: {ERROR}", "TYPE",
109                    getFormFactorType(), "ERROR", errno);
110         return;
111     }
112 
113     n = ::read(fd, &buf, sizeof(buf));
114     if (n < 0)
115     {
116         lg2::error("{TYPE}: Gpio fd read error: {ERROR}", "TYPE",
117                    getFormFactorType(), "ERROR", errno);
118         throw sdbusplus::xyz::openbmc_project::Chassis::Common::Error::
119             IOError();
120     }
121 
122     // read the gpio state for the io event received
123     GpioState gpioState = (buf == '0') ? (GpioState::deassert)
124                                        : (GpioState::assert);
125 
126     setHostSelectorValue(fd, gpioState);
127 
128     size_t hsPosMapped = getMappedHSConfig(hostSelectorPosition);
129 
130     if (hsPosMapped != INVALID_INDEX)
131     {
132         position(hsPosMapped);
133     }
134 }
135