blob: 96f6f8f711b3d5449f009045dae313b02c3ed482 [file] [log] [blame]
Gunnar Mills72639152017-06-22 15:06:21 -05001#include "argument.hpp"
2#include "gpio_presence.hpp"
3
Patrick Venturedace6802018-11-01 16:52:10 -07004#include <systemd/sd-event.h>
5
Patrick Venturedace6802018-11-01 16:52:10 -07006#include <phosphor-logging/log.hpp>
7
Patrick Williams39084b42023-05-10 07:50:58 -05008#include <iostream>
9
Gunnar Mills72639152017-06-22 15:06:21 -050010using namespace phosphor::logging;
11using namespace phosphor::gpio;
Gunnar Mills5f101102017-06-29 13:07:39 -050012using namespace phosphor::gpio::presence;
Gunnar Mills72639152017-06-22 15:06:21 -050013
Matt Spinlerd5636b02017-09-01 14:00:19 -050014/**
15 * Pulls out the path,device pairs from the string
16 * passed in
17 *
18 * @param[in] driverString - space separated path,device pairs
19 * @param[out] drivers - vector of device,path tuples filled in
20 * from driverString
21 *
22 * @return int - 0 if successful, < 0 else
23 */
Patrick Venture3c4a23e2018-10-14 14:26:35 -070024static int getDrivers(const std::string& driverString,
Matt Spinlerd5636b02017-09-01 14:00:19 -050025 std::vector<Driver>& drivers)
26{
27 std::istringstream stream{driverString};
28
29 while (true)
30 {
31 std::string entry;
32
Patrick Venturedace6802018-11-01 16:52:10 -070033 // Extract each path,device pair
Matt Spinlerd5636b02017-09-01 14:00:19 -050034 stream >> entry;
35
36 if (entry.empty())
37 {
38 break;
39 }
40
Patrick Venturedace6802018-11-01 16:52:10 -070041 // Extract the path and device and save them
Matt Spinlerd5636b02017-09-01 14:00:19 -050042 auto pos = entry.rfind(',');
43 if (pos != std::string::npos)
44 {
45 auto path = entry.substr(0, pos);
46 auto device = entry.substr(pos + 1);
47
Patrick Williams162bd712023-06-01 09:19:10 -050048 drivers.emplace_back(std::move(device), std::move(path));
Matt Spinlerd5636b02017-09-01 14:00:19 -050049 }
50 else
51 {
52 std::cerr << "Invalid path,device combination: " << entry << "\n";
53 return -1;
54 }
55 }
56
57 return 0;
58}
59
Gunnar Mills72639152017-06-22 15:06:21 -050060int main(int argc, char* argv[])
61{
62 auto options = ArgumentParser(argc, argv);
63
64 auto inventory = options["inventory"];
65 auto key = options["key"];
66 auto path = options["path"];
Matt Spinlerd5636b02017-09-01 14:00:19 -050067 auto drivers = options["drivers"];
Anthony Wilson206f0042019-05-02 00:02:23 -050068 auto ifaces = options["extra-ifaces"];
Gunnar Mills72639152017-06-22 15:06:21 -050069 if (argc < 4)
70 {
71 std::cerr << "Too few arguments\n";
72 options.usage(argv);
73 }
74
75 if (inventory == ArgumentParser::emptyString)
76 {
77 std::cerr << "Inventory argument required\n";
78 options.usage(argv);
79 }
80
81 if (key == ArgumentParser::emptyString)
82 {
83 std::cerr << "GPIO key argument required\n";
84 options.usage(argv);
85 }
86
87 if (path == ArgumentParser::emptyString)
88 {
89 std::cerr << "Device path argument required\n";
90 options.usage(argv);
91 }
Gunnar Mills80292bb2017-07-05 16:34:51 -050092
Matt Spinler902d1c32017-09-01 11:03:02 -050093 std::vector<Driver> driverList;
94
Patrick Venturedace6802018-11-01 16:52:10 -070095 // Driver list is optional
Matt Spinlerd5636b02017-09-01 14:00:19 -050096 if (drivers != ArgumentParser::emptyString)
97 {
98 if (getDrivers(drivers, driverList) < 0)
99 {
100 options.usage(argv);
101 }
102 }
Matt Spinler902d1c32017-09-01 11:03:02 -0500103
Anthony Wilson206f0042019-05-02 00:02:23 -0500104 std::vector<Interface> ifaceList;
105
106 // Extra interfaces list is optional
107 if (ifaces != ArgumentParser::emptyString)
108 {
109 std::stringstream ss(ifaces);
110 Interface iface;
111 while (std::getline(ss, iface, ','))
112 {
113 ifaceList.push_back(iface);
114 }
115 }
116
Gunnar Mills80292bb2017-07-05 16:34:51 -0500117 auto bus = sdbusplus::bus::new_default();
Gunnar Mills765725e2017-07-06 14:17:44 -0500118 auto rc = 0;
119 sd_event* event = nullptr;
120 rc = sd_event_default(&event);
121 if (rc < 0)
122 {
123 log<level::ERR>("Error creating a default sd_event handler");
124 return rc;
125 }
126 EventPtr eventP{event};
127 event = nullptr;
Gunnar Mills72639152017-06-22 15:06:21 -0500128
Gunnar Mills765725e2017-07-06 14:17:44 -0500129 auto name = options["name"];
Patrick Venturedace6802018-11-01 16:52:10 -0700130 Presence presence(bus, inventory, path, std::stoul(key), name, eventP,
Anthony Wilson206f0042019-05-02 00:02:23 -0500131 driverList, ifaceList);
Gunnar Mills765725e2017-07-06 14:17:44 -0500132
133 while (true)
134 {
135 // -1 denotes wait forever
Patrick Venturedace6802018-11-01 16:52:10 -0700136 rc = sd_event_run(eventP.get(), (uint64_t)-1);
Gunnar Mills765725e2017-07-06 14:17:44 -0500137 if (rc < 0)
138 {
139 log<level::ERR>("Failure in processing request",
140 entry("ERROR=%s", strerror(-rc)));
141 break;
142 }
143 }
144 return rc;
Gunnar Mills72639152017-06-22 15:06:21 -0500145}