1 #include <iostream> 2 #include <systemd/sd-event.h> 3 #include <phosphor-logging/log.hpp> 4 #include "argument.hpp" 5 #include "gpio_presence.hpp" 6 7 using namespace phosphor::logging; 8 using namespace phosphor::gpio; 9 using namespace phosphor::gpio::presence; 10 11 /** 12 * Pulls out the path,device pairs from the string 13 * passed in 14 * 15 * @param[in] driverString - space separated path,device pairs 16 * @param[out] drivers - vector of device,path tuples filled in 17 * from driverString 18 * 19 * @return int - 0 if successful, < 0 else 20 */ 21 static int getDrivers(const std::string driverString, 22 std::vector<Driver>& drivers) 23 { 24 std::istringstream stream{driverString}; 25 26 while (true) 27 { 28 std::string entry; 29 30 //Extract each path,device pair 31 stream >> entry; 32 33 if (entry.empty()) 34 { 35 break; 36 } 37 38 //Extract the path and device and save them 39 auto pos = entry.rfind(','); 40 if (pos != std::string::npos) 41 { 42 auto path = entry.substr(0, pos); 43 auto device = entry.substr(pos + 1); 44 45 drivers.emplace_back(device, path); 46 } 47 else 48 { 49 std::cerr << "Invalid path,device combination: " << entry << "\n"; 50 return -1; 51 } 52 } 53 54 return 0; 55 } 56 57 int main(int argc, char* argv[]) 58 { 59 auto options = ArgumentParser(argc, argv); 60 61 auto inventory = options["inventory"]; 62 auto key = options["key"]; 63 auto path = options["path"]; 64 auto drivers = options["drivers"]; 65 if (argc < 4) 66 { 67 std::cerr << "Too few arguments\n"; 68 options.usage(argv); 69 } 70 71 if (inventory == ArgumentParser::emptyString) 72 { 73 std::cerr << "Inventory argument required\n"; 74 options.usage(argv); 75 } 76 77 if (key == ArgumentParser::emptyString) 78 { 79 std::cerr << "GPIO key argument required\n"; 80 options.usage(argv); 81 } 82 83 if (path == ArgumentParser::emptyString) 84 { 85 std::cerr << "Device path argument required\n"; 86 options.usage(argv); 87 } 88 89 std::vector<Driver> driverList; 90 91 //Driver list is optional 92 if (drivers != ArgumentParser::emptyString) 93 { 94 if (getDrivers(drivers, driverList) < 0) 95 { 96 options.usage(argv); 97 } 98 } 99 100 auto bus = sdbusplus::bus::new_default(); 101 auto rc = 0; 102 sd_event* event = nullptr; 103 rc = sd_event_default(&event); 104 if (rc < 0) 105 { 106 log<level::ERR>("Error creating a default sd_event handler"); 107 return rc; 108 } 109 EventPtr eventP{event}; 110 event = nullptr; 111 112 auto name = options["name"]; 113 Presence presence( 114 bus, inventory, path, std::stoul(key), name, eventP, driverList); 115 116 while (true) 117 { 118 // -1 denotes wait forever 119 rc = sd_event_run(eventP.get(), (uint64_t) - 1); 120 if (rc < 0) 121 { 122 log<level::ERR>("Failure in processing request", 123 entry("ERROR=%s", strerror(-rc))); 124 break; 125 } 126 } 127 return rc; 128 } 129 130