1155c34fbSMatthew Barth #include "argument.hpp" 2155c34fbSMatthew Barth #include "writefrudata.hpp" 3155c34fbSMatthew Barth 452f1f189SPatrick Venture #include <cstdlib> 552f1f189SPatrick Venture #include <cstring> 6c9508db8SPatrick Venture #include <iostream> 7c9508db8SPatrick Venture #include <memory> 807f635c8SPatrick Venture #include <phosphor-logging/log.hpp> 907f635c8SPatrick Venture 1007f635c8SPatrick Venture using namespace phosphor::logging; 11c9508db8SPatrick Venture 12155c34fbSMatthew Barth static void exit_with_error(const char* err, char** argv) 13155c34fbSMatthew Barth { 14155c34fbSMatthew Barth ArgumentParser::usage(argv); 15155c34fbSMatthew Barth std::cerr << std::endl; 16155c34fbSMatthew Barth std::cerr << "ERROR: " << err << std::endl; 17155c34fbSMatthew Barth exit(-1); 18155c34fbSMatthew Barth } 19155c34fbSMatthew Barth 20*8f51109dSOskar Senft static uint8_t parse_fruid_or_exit(const char* fruid_str, char** argv) 21*8f51109dSOskar Senft { 22*8f51109dSOskar Senft const uint8_t MAX_FRU_ID = 0xfe; 23*8f51109dSOskar Senft unsigned long fruid; 24*8f51109dSOskar Senft char* endptr = NULL; 25*8f51109dSOskar Senft 26*8f51109dSOskar Senft // The FRUID string must not be empty. 27*8f51109dSOskar Senft if (fruid_str == nullptr || *fruid_str == '\0') 28*8f51109dSOskar Senft { 29*8f51109dSOskar Senft exit_with_error("Empty fruid.", argv); 30*8f51109dSOskar Senft } 31*8f51109dSOskar Senft 32*8f51109dSOskar Senft errno = 0; 33*8f51109dSOskar Senft fruid = std::strtoul(fruid_str, &endptr, 16); 34*8f51109dSOskar Senft 35*8f51109dSOskar Senft // Handle error cases 36*8f51109dSOskar Senft if (errno == ERANGE) 37*8f51109dSOskar Senft { 38*8f51109dSOskar Senft exit_with_error("fruid is out of range.", argv); 39*8f51109dSOskar Senft } 40*8f51109dSOskar Senft if (errno != 0) 41*8f51109dSOskar Senft { 42*8f51109dSOskar Senft exit_with_error("Could not parse fruid.", argv); 43*8f51109dSOskar Senft } 44*8f51109dSOskar Senft if (*endptr != '\0') 45*8f51109dSOskar Senft { 46*8f51109dSOskar Senft // The string was not fully parsed, e.g. contains invalid characters 47*8f51109dSOskar Senft exit_with_error("Invalid fruid.", argv); 48*8f51109dSOskar Senft } 49*8f51109dSOskar Senft if (fruid > MAX_FRU_ID) 50*8f51109dSOskar Senft { 51*8f51109dSOskar Senft // The string was parsed, but the set FRUID is too large. 52*8f51109dSOskar Senft exit_with_error("fruid is out of range.", argv); 53*8f51109dSOskar Senft } 54*8f51109dSOskar Senft 55*8f51109dSOskar Senft return fruid; 56*8f51109dSOskar Senft } 57*8f51109dSOskar Senft 58155c34fbSMatthew Barth //-------------------------------------------------------------------------- 59155c34fbSMatthew Barth // This gets called by udev monitor soon after seeing hog plugs for EEPROMS. 60155c34fbSMatthew Barth //-------------------------------------------------------------------------- 61155c34fbSMatthew Barth int main(int argc, char** argv) 62155c34fbSMatthew Barth { 63155c34fbSMatthew Barth int rc = 0; 64*8f51109dSOskar Senft uint8_t fruid; 65155c34fbSMatthew Barth 66155c34fbSMatthew Barth // Read the arguments. 67155c34fbSMatthew Barth auto cli_options = std::make_unique<ArgumentParser>(argc, argv); 68155c34fbSMatthew Barth 69155c34fbSMatthew Barth // Parse out each argument. 70155c34fbSMatthew Barth auto eeprom_file = (*cli_options)["eeprom"]; 71155c34fbSMatthew Barth if (eeprom_file == ArgumentParser::empty_string) 72155c34fbSMatthew Barth { 73155c34fbSMatthew Barth // User has not passed in the appropriate argument value 74155c34fbSMatthew Barth exit_with_error("eeprom data not found.", argv); 75155c34fbSMatthew Barth } 76155c34fbSMatthew Barth 77155c34fbSMatthew Barth auto fruid_str = (*cli_options)["fruid"]; 7805261aa5SDmitry Bazhenov if (fruid_str == ArgumentParser::empty_string) 79155c34fbSMatthew Barth { 80155c34fbSMatthew Barth // User has not passed in the appropriate argument value 81155c34fbSMatthew Barth exit_with_error("fruid data not found.", argv); 82155c34fbSMatthew Barth } 83155c34fbSMatthew Barth 84155c34fbSMatthew Barth // Extract the fruid 85*8f51109dSOskar Senft fruid = parse_fruid_or_exit(fruid_str.c_str(), argv); 86155c34fbSMatthew Barth 87155c34fbSMatthew Barth // Finished getting options out, so release the parser. 88155c34fbSMatthew Barth cli_options.release(); 89155c34fbSMatthew Barth 90c9508db8SPatrick Venture // Now that we have the file that contains the eeprom data, go read it 91c9508db8SPatrick Venture // and update the Inventory DB. 92a8093a25SPatrick Venture auto bus = sdbusplus::bus::new_default(); 93155c34fbSMatthew Barth bool bmc_fru = true; 94a8093a25SPatrick Venture rc = validateFRUArea(fruid, eeprom_file.c_str(), bus, bmc_fru); 95155c34fbSMatthew Barth 96155c34fbSMatthew Barth return (rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS); 97155c34fbSMatthew Barth } 98