xref: /openbmc/phosphor-buttons/src/main.cpp (revision eea8a4a5)
1 /*
2 // Copyright (c) 2018 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16 
17 #include "button_factory.hpp"
18 #include "gpio.hpp"
19 
20 #include <fstream>
21 #include <nlohmann/json.hpp>
22 #include <phosphor-logging/elog-errors.hpp>
23 static constexpr auto gpioDefFile = "/etc/default/obmc/gpio/gpio_defs.json";
24 
25 int main(int argc, char* argv[])
26 {
27     int ret = 0;
28 
29     phosphor::logging::log<phosphor::logging::level::INFO>(
30         "Start Phosphor buttons service...");
31 
32     sd_event* event = nullptr;
33     ret = sd_event_default(&event);
34     if (ret < 0)
35     {
36         phosphor::logging::log<phosphor::logging::level::ERR>(
37             "Error creating a default sd_event handler");
38         return ret;
39     }
40     EventPtr eventP{event};
41     event = nullptr;
42 
43     sdbusplus::bus::bus bus = sdbusplus::bus::new_default();
44     sdbusplus::server::manager::manager objManager{
45         bus, "/xyz/openbmc_project/Chassis/Buttons"};
46 
47     bus.request_name("xyz.openbmc_project.Chassis.Buttons");
48     //
49     std::vector<std::unique_ptr<ButtonIface>> buttonInterfaces;
50 
51     std::ifstream gpios{gpioDefFile};
52     auto json = nlohmann::json::parse(gpios, nullptr, true);
53     auto gpioDefs = json["gpio_definitions"];
54 
55     // load gpio config from gpio defs json file and create button interface
56     // objects based on the button form factor type
57 
58     for (const auto& gpioConfig : gpioDefs)
59     {
60         std::string formFactorName = gpioConfig["name"];
61         buttonConfig buttonCfg;
62         buttonCfg.formFactorName = formFactorName;
63 
64         /* The folloing code checks if the gpio config read
65         from json file is single gpio config or group gpio config,
66         based on that further data is processed. */
67         if (gpioConfig.contains("group_gpio_config"))
68         {
69             const auto& groupGpio = gpioConfig["group_gpio_config"];
70 
71             for (const auto& config : groupGpio)
72             {
73                 gpioInfo gpioCfg;
74                 gpioCfg.number = getGpioNum(config["pin"]);
75                 gpioCfg.direction = config["direction"];
76                 buttonCfg.gpios.push_back(gpioCfg);
77             }
78         }
79         else
80         {
81             gpioInfo gpioCfg;
82             gpioCfg.number = getGpioNum(gpioConfig["pin"]);
83             gpioCfg.direction = gpioConfig["direction"];
84             buttonCfg.gpios.push_back(gpioCfg);
85         }
86         auto tempButtonIf = ButtonFactory::instance().createInstance(
87             formFactorName, bus, eventP, buttonCfg);
88         /* There are additional gpio configs present in some platforms
89          that are not supported in phosphor-buttons.
90         But they may be used by other applications. so skipping such configs
91         if present in gpio_defs.json file*/
92         if (tempButtonIf)
93         {
94             buttonInterfaces.emplace_back(std::move(tempButtonIf));
95         }
96     }
97 
98     try
99     {
100         bus.attach_event(eventP.get(), SD_EVENT_PRIORITY_NORMAL);
101         ret = sd_event_loop(eventP.get());
102         if (ret < 0)
103         {
104             phosphor::logging::log<phosphor::logging::level::ERR>(
105                 "Error occurred during the sd_event_loop",
106                 phosphor::logging::entry("RET=%d", ret));
107         }
108     }
109     catch (const std::exception& e)
110     {
111         phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
112         ret = -1;
113     }
114     return ret;
115 }
116