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 <iostream> 20 #include <string> 21 #include <vector> 22 23 static void exitWithError(const char* err, char** argv) 24 { 25 phosphor::network::ncsi::ArgumentParser::usage(argv); 26 std::cerr << "ERROR: " << err << "\n"; 27 exit(EXIT_FAILURE); 28 } 29 30 int main(int argc, char** argv) 31 { 32 using namespace phosphor::network; 33 using namespace phosphor::network::ncsi; 34 // Read arguments. 35 auto options = ArgumentParser(argc, argv); 36 int packageInt{}; 37 int channelInt{}; 38 int indexInt{}; 39 40 // Parse out interface argument. 41 auto ifIndex = (options)["index"]; 42 try 43 { 44 indexInt = stoi(ifIndex, nullptr); 45 } 46 catch (const std::exception& e) 47 { 48 exitWithError("Interface not specified.", argv); 49 } 50 51 if (indexInt < 0) 52 { 53 exitWithError("Interface value should be greater than equal to 0", 54 argv); 55 } 56 57 // Parse out package argument. 58 auto package = (options)["package"]; 59 try 60 { 61 packageInt = stoi(package, nullptr); 62 } 63 catch (const std::exception& e) 64 { 65 packageInt = DEFAULT_VALUE; 66 } 67 68 if (packageInt < 0) 69 { 70 packageInt = DEFAULT_VALUE; 71 } 72 73 // Parse out channel argument. 74 auto channel = (options)["channel"]; 75 try 76 { 77 channelInt = stoi(channel, nullptr); 78 } 79 catch (const std::exception& e) 80 { 81 channelInt = DEFAULT_VALUE; 82 } 83 84 if (channelInt < 0) 85 { 86 channelInt = DEFAULT_VALUE; 87 } 88 89 auto payloadStr = (options)["oem-payload"]; 90 if (!payloadStr.empty()) 91 { 92 std::string byte(2, '\0'); 93 std::vector<unsigned char> payload; 94 95 if (payloadStr.size() % 2) 96 exitWithError("Payload invalid: specify two hex digits per byte.", 97 argv); 98 99 // Parse the payload string (e.g. "000001572100") to byte data 100 for (unsigned int i = 1; i < payloadStr.size(); i += 2) 101 { 102 byte[0] = payloadStr[i - 1]; 103 byte[1] = payloadStr[i]; 104 105 try 106 { 107 payload.push_back(stoi(byte, nullptr, 16)); 108 } 109 catch (const std::exception& e) 110 { 111 exitWithError("Payload invalid.", argv); 112 } 113 } 114 115 if (payload.empty()) 116 { 117 exitWithError("No payload specified.", argv); 118 } 119 120 if (packageInt == DEFAULT_VALUE) 121 { 122 exitWithError("Package not specified.", argv); 123 } 124 125 return ncsi::sendOemCommand( 126 indexInt, packageInt, channelInt, 127 std::span<const unsigned char>(payload.begin(), payload.end())); 128 } 129 else if ((options)["set"] == "true") 130 { 131 // Can not perform set operation without package. 132 if (packageInt == DEFAULT_VALUE) 133 { 134 exitWithError("Package not specified.", argv); 135 } 136 return ncsi::setChannel(indexInt, packageInt, channelInt); 137 } 138 else if ((options)["info"] == "true") 139 { 140 return ncsi::getInfo(indexInt, packageInt); 141 } 142 else if ((options)["clear"] == "true") 143 { 144 return ncsi::clearInterface(indexInt); 145 } 146 else 147 { 148 exitWithError("No Command specified", argv); 149 } 150 return 0; 151 } 152