blob: aa1eb24e60b54a94abcb2f5e61c44d0d04fef4e2 [file] [log] [blame]
Gunnar Mills72639152017-06-22 15:06:21 -05001#include "gpio_presence.hpp"
2
Patrick Venturedace6802018-11-01 16:52:10 -07003#include <systemd/sd-event.h>
4
George Liu7d7cc9e2023-08-02 08:52:01 +08005#include <CLI/CLI.hpp>
George Liu2a8848c2023-08-01 13:49:28 +08006#include <phosphor-logging/lg2.hpp>
Patrick Venturedace6802018-11-01 16:52:10 -07007
Patrick Williams39084b42023-05-10 07:50:58 -05008#include <iostream>
9
Gunnar Mills72639152017-06-22 15:06:21 -050010using namespace phosphor::gpio;
Gunnar Mills5f101102017-06-29 13:07:39 -050011using namespace phosphor::gpio::presence;
Gunnar Mills72639152017-06-22 15:06:21 -050012
Matt Spinlerd5636b02017-09-01 14:00:19 -050013/**
14 * Pulls out the path,device pairs from the string
15 * passed in
16 *
17 * @param[in] driverString - space separated path,device pairs
18 * @param[out] drivers - vector of device,path tuples filled in
19 * from driverString
20 *
21 * @return int - 0 if successful, < 0 else
22 */
Patrick Venture3c4a23e2018-10-14 14:26:35 -070023static int getDrivers(const std::string& driverString,
Matt Spinlerd5636b02017-09-01 14:00:19 -050024 std::vector<Driver>& drivers)
25{
26 std::istringstream stream{driverString};
27
28 while (true)
29 {
30 std::string entry;
31
Patrick Venturedace6802018-11-01 16:52:10 -070032 // Extract each path,device pair
Matt Spinlerd5636b02017-09-01 14:00:19 -050033 stream >> entry;
34
35 if (entry.empty())
36 {
37 break;
38 }
39
Patrick Venturedace6802018-11-01 16:52:10 -070040 // Extract the path and device and save them
Matt Spinlerd5636b02017-09-01 14:00:19 -050041 auto pos = entry.rfind(',');
42 if (pos != std::string::npos)
43 {
44 auto path = entry.substr(0, pos);
45 auto device = entry.substr(pos + 1);
46
Patrick Williams162bd712023-06-01 09:19:10 -050047 drivers.emplace_back(std::move(device), std::move(path));
Matt Spinlerd5636b02017-09-01 14:00:19 -050048 }
49 else
50 {
George Liu2a8848c2023-08-01 13:49:28 +080051 lg2::error("Invalid path,device combination: {ENTRY}", "ENTRY",
52 entry);
Matt Spinlerd5636b02017-09-01 14:00:19 -050053 return -1;
54 }
55 }
56
57 return 0;
58}
59
George Liu7d7cc9e2023-08-02 08:52:01 +080060int main(int argc, char** argv)
Gunnar Mills72639152017-06-22 15:06:21 -050061{
George Liu7d7cc9e2023-08-02 08:52:01 +080062 CLI::App app{"Monitor gpio presence status"};
Gunnar Mills72639152017-06-22 15:06:21 -050063
George Liu7d7cc9e2023-08-02 08:52:01 +080064 std::string path{};
65 std::string key{};
66 std::string name{};
67 std::string inventory{};
68 std::string drivers{};
69 std::string ifaces{};
70
71 /* Add an input option */
72 app.add_option(
73 "-p,--path", path,
74 " Path of device to read for GPIO pin state to determine presence of inventory item")
75 ->required();
76 app.add_option("-k,--key", key, "Input GPIO key number")->required();
77 app.add_option("-n,--name", name, "Pretty name of the inventory item")
78 ->required();
79 app.add_option("-i,--inventory", inventory,
80 "Object path under inventory that will be created")
81 ->required();
82 app.add_option(
83 "-d,--drivers", drivers,
84 "List of drivers to bind when card is added and unbind when card is removed\n"
85 "Format is a space separated list of path,device pairs.\n"
86 "For example: /sys/bus/i2c/drivers/some-driver,3-0068");
87 app.add_option(
88 "-e,--extra-ifaces", ifaces,
89 "List of interfaces to associate to inventory item\n"
90 "Format is a comma separated list of interfaces.\n"
91 "For example: /xyz/openbmc_project/.../1,/xyz/openbmc_project/.../2");
92
93 /* Parse input parameter */
94 try
Gunnar Mills72639152017-06-22 15:06:21 -050095 {
George Liu7d7cc9e2023-08-02 08:52:01 +080096 app.parse(argc, argv);
Gunnar Mills72639152017-06-22 15:06:21 -050097 }
George Liu7d7cc9e2023-08-02 08:52:01 +080098 catch (const CLI::Error& e)
Gunnar Mills72639152017-06-22 15:06:21 -050099 {
George Liu7d7cc9e2023-08-02 08:52:01 +0800100 return app.exit(e);
Gunnar Mills72639152017-06-22 15:06:21 -0500101 }
Gunnar Mills80292bb2017-07-05 16:34:51 -0500102
Matt Spinler902d1c32017-09-01 11:03:02 -0500103 std::vector<Driver> driverList;
104
Patrick Venturedace6802018-11-01 16:52:10 -0700105 // Driver list is optional
George Liu7d7cc9e2023-08-02 08:52:01 +0800106 if (!drivers.empty())
Matt Spinlerd5636b02017-09-01 14:00:19 -0500107 {
108 if (getDrivers(drivers, driverList) < 0)
109 {
George Liu7d7cc9e2023-08-02 08:52:01 +0800110 lg2::error("Failed to parser drivers: {DRIVERS}", "DRIVERS",
111 drivers);
112 return -1;
Matt Spinlerd5636b02017-09-01 14:00:19 -0500113 }
114 }
Matt Spinler902d1c32017-09-01 11:03:02 -0500115
Anthony Wilson206f0042019-05-02 00:02:23 -0500116 std::vector<Interface> ifaceList;
117
118 // Extra interfaces list is optional
George Liu7d7cc9e2023-08-02 08:52:01 +0800119 if (!ifaces.empty())
Anthony Wilson206f0042019-05-02 00:02:23 -0500120 {
121 std::stringstream ss(ifaces);
122 Interface iface;
123 while (std::getline(ss, iface, ','))
124 {
125 ifaceList.push_back(iface);
126 }
127 }
128
Gunnar Mills80292bb2017-07-05 16:34:51 -0500129 auto bus = sdbusplus::bus::new_default();
Gunnar Mills765725e2017-07-06 14:17:44 -0500130 auto rc = 0;
131 sd_event* event = nullptr;
132 rc = sd_event_default(&event);
133 if (rc < 0)
134 {
George Liu2a8848c2023-08-01 13:49:28 +0800135 lg2::error("Error creating a default sd_event handler");
Gunnar Mills765725e2017-07-06 14:17:44 -0500136 return rc;
137 }
138 EventPtr eventP{event};
139 event = nullptr;
Gunnar Mills72639152017-06-22 15:06:21 -0500140
Patrick Venturedace6802018-11-01 16:52:10 -0700141 Presence presence(bus, inventory, path, std::stoul(key), name, eventP,
Anthony Wilson206f0042019-05-02 00:02:23 -0500142 driverList, ifaceList);
Gunnar Mills765725e2017-07-06 14:17:44 -0500143
144 while (true)
145 {
146 // -1 denotes wait forever
Patrick Venturedace6802018-11-01 16:52:10 -0700147 rc = sd_event_run(eventP.get(), (uint64_t)-1);
Gunnar Mills765725e2017-07-06 14:17:44 -0500148 if (rc < 0)
149 {
George Liu2a8848c2023-08-01 13:49:28 +0800150 lg2::error("Failure in processing request: {RC}", "RC", rc);
Gunnar Mills765725e2017-07-06 14:17:44 -0500151 break;
152 }
153 }
154 return rc;
Gunnar Mills72639152017-06-22 15:06:21 -0500155}