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