1 /** 2 * Copyright © 2018 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include "argument.hpp" 17 #include "ncsi_util.hpp" 18 19 #include <phosphor-logging/lg2.hpp> 20 21 #include <string> 22 #include <vector> 23 24 static void exitWithError(const char* err, char** argv) 25 { 26 phosphor::network::ncsi::ArgumentParser::usage(argv); 27 lg2::error("ERROR: {ERROR}", "ERROR", err); 28 exit(EXIT_FAILURE); 29 } 30 31 int main(int argc, char** argv) 32 { 33 using namespace phosphor::network; 34 using namespace phosphor::network::ncsi; 35 // Read arguments. 36 auto options = ArgumentParser(argc, argv); 37 int packageInt{}; 38 int channelInt{}; 39 int indexInt{}; 40 41 // Parse out interface argument. 42 auto ifIndex = (options)["index"]; 43 try 44 { 45 indexInt = stoi(ifIndex, nullptr); 46 } 47 catch (const std::exception& e) 48 { 49 exitWithError("Interface not specified.", argv); 50 } 51 52 if (indexInt < 0) 53 { 54 exitWithError("Interface value should be greater than equal to 0", 55 argv); 56 } 57 58 // Parse out package argument. 59 auto package = (options)["package"]; 60 try 61 { 62 packageInt = stoi(package, nullptr); 63 } 64 catch (const std::exception& e) 65 { 66 packageInt = DEFAULT_VALUE; 67 } 68 69 if (packageInt < 0) 70 { 71 packageInt = DEFAULT_VALUE; 72 } 73 74 // Parse out channel argument. 75 auto channel = (options)["channel"]; 76 try 77 { 78 channelInt = stoi(channel, nullptr); 79 } 80 catch (const std::exception& e) 81 { 82 channelInt = DEFAULT_VALUE; 83 } 84 85 if (channelInt < 0) 86 { 87 channelInt = DEFAULT_VALUE; 88 } 89 90 auto payloadStr = (options)["oem-payload"]; 91 if (!payloadStr.empty()) 92 { 93 std::string byte(2, '\0'); 94 std::vector<unsigned char> payload; 95 96 if (payloadStr.size() % 2) 97 exitWithError("Payload invalid: specify two hex digits per byte.", 98 argv); 99 100 // Parse the payload string (e.g. "000001572100") to byte data 101 for (unsigned int i = 1; i < payloadStr.size(); i += 2) 102 { 103 byte[0] = payloadStr[i - 1]; 104 byte[1] = payloadStr[i]; 105 106 try 107 { 108 payload.push_back(stoi(byte, nullptr, 16)); 109 } 110 catch (const std::exception& e) 111 { 112 exitWithError("Payload invalid.", argv); 113 } 114 } 115 116 if (payload.empty()) 117 { 118 exitWithError("No payload specified.", argv); 119 } 120 121 if (packageInt == DEFAULT_VALUE) 122 { 123 exitWithError("Package not specified.", argv); 124 } 125 126 return ncsi::sendOemCommand( 127 indexInt, packageInt, channelInt, 128 std::span<const unsigned char>(payload.begin(), payload.end())); 129 } 130 else if ((options)["set"] == "true") 131 { 132 // Can not perform set operation without package. 133 if (packageInt == DEFAULT_VALUE) 134 { 135 exitWithError("Package not specified.", argv); 136 } 137 return ncsi::setChannel(indexInt, packageInt, channelInt); 138 } 139 else if ((options)["info"] == "true") 140 { 141 return ncsi::getInfo(indexInt, packageInt); 142 } 143 else if ((options)["clear"] == "true") 144 { 145 return ncsi::clearInterface(indexInt); 146 } 147 else 148 { 149 exitWithError("No Command specified", argv); 150 } 151 return 0; 152 } 153