1 #include "argument.hpp" 2 #include "gpio_presence.hpp" 3 4 #include <systemd/sd-event.h> 5 6 #include <phosphor-logging/log.hpp> 7 8 #include <iostream> 9 10 using namespace phosphor::logging; 11 using namespace phosphor::gpio; 12 using namespace phosphor::gpio::presence; 13 14 /** 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 */ 24 static int getDrivers(const std::string& driverString, 25 std::vector<Driver>& drivers) 26 { 27 std::istringstream stream{driverString}; 28 29 while (true) 30 { 31 std::string entry; 32 33 // Extract each path,device pair 34 stream >> entry; 35 36 if (entry.empty()) 37 { 38 break; 39 } 40 41 // Extract the path and device and save them 42 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 48 drivers.emplace_back(std::move(device), std::move(path)); 49 } 50 else 51 { 52 std::cerr << "Invalid path,device combination: " << entry << "\n"; 53 return -1; 54 } 55 } 56 57 return 0; 58 } 59 60 int 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"]; 67 auto drivers = options["drivers"]; 68 auto ifaces = options["extra-ifaces"]; 69 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 } 92 93 std::vector<Driver> driverList; 94 95 // Driver list is optional 96 if (drivers != ArgumentParser::emptyString) 97 { 98 if (getDrivers(drivers, driverList) < 0) 99 { 100 options.usage(argv); 101 } 102 } 103 104 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 117 auto bus = sdbusplus::bus::new_default(); 118 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; 128 129 auto name = options["name"]; 130 Presence presence(bus, inventory, path, std::stoul(key), name, eventP, 131 driverList, ifaceList); 132 133 while (true) 134 { 135 // -1 denotes wait forever 136 rc = sd_event_run(eventP.get(), (uint64_t)-1); 137 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; 145 } 146