11bbe3d1eSWilliam A. Kennington III /** 21bbe3d1eSWilliam A. Kennington III * Copyright © 2018 IBM Corporation 31bbe3d1eSWilliam A. Kennington III * 41bbe3d1eSWilliam A. Kennington III * Licensed under the Apache License, Version 2.0 (the "License"); 51bbe3d1eSWilliam A. Kennington III * you may not use this file except in compliance with the License. 61bbe3d1eSWilliam A. Kennington III * You may obtain a copy of the License at 71bbe3d1eSWilliam A. Kennington III * 81bbe3d1eSWilliam A. Kennington III * http://www.apache.org/licenses/LICENSE-2.0 91bbe3d1eSWilliam A. Kennington III * 101bbe3d1eSWilliam A. Kennington III * Unless required by applicable law or agreed to in writing, software 111bbe3d1eSWilliam A. Kennington III * distributed under the License is distributed on an "AS IS" BASIS, 121bbe3d1eSWilliam A. Kennington III * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131bbe3d1eSWilliam A. Kennington III * See the License for the specific language governing permissions and 141bbe3d1eSWilliam A. Kennington III * limitations under the License. 151bbe3d1eSWilliam A. Kennington III */ 161bbe3d1eSWilliam A. Kennington III #include "argument.hpp" 171bbe3d1eSWilliam A. Kennington III #include "ncsi_util.hpp" 181bbe3d1eSWilliam A. Kennington III 19*d423bebfSJagpal Singh Gill #include <phosphor-logging/lg2.hpp> 201bbe3d1eSWilliam A. Kennington III #include <string> 21fa1f5c03SEddie James #include <vector> 221bbe3d1eSWilliam A. Kennington III 231bbe3d1eSWilliam A. Kennington III static void exitWithError(const char* err, char** argv) 241bbe3d1eSWilliam A. Kennington III { 251bbe3d1eSWilliam A. Kennington III phosphor::network::ncsi::ArgumentParser::usage(argv); 26*d423bebfSJagpal Singh Gill lg2::error("ERROR: {ERROR}", "ERROR", err); 271bbe3d1eSWilliam A. Kennington III exit(EXIT_FAILURE); 281bbe3d1eSWilliam A. Kennington III } 291bbe3d1eSWilliam A. Kennington III 301bbe3d1eSWilliam A. Kennington III int main(int argc, char** argv) 311bbe3d1eSWilliam A. Kennington III { 321bbe3d1eSWilliam A. Kennington III using namespace phosphor::network; 331bbe3d1eSWilliam A. Kennington III using namespace phosphor::network::ncsi; 341bbe3d1eSWilliam A. Kennington III // Read arguments. 351bbe3d1eSWilliam A. Kennington III auto options = ArgumentParser(argc, argv); 361bbe3d1eSWilliam A. Kennington III int packageInt{}; 371bbe3d1eSWilliam A. Kennington III int channelInt{}; 381bbe3d1eSWilliam A. Kennington III int indexInt{}; 391bbe3d1eSWilliam A. Kennington III 401bbe3d1eSWilliam A. Kennington III // Parse out interface argument. 411bbe3d1eSWilliam A. Kennington III auto ifIndex = (options)["index"]; 421bbe3d1eSWilliam A. Kennington III try 431bbe3d1eSWilliam A. Kennington III { 441bbe3d1eSWilliam A. Kennington III indexInt = stoi(ifIndex, nullptr); 451bbe3d1eSWilliam A. Kennington III } 461bbe3d1eSWilliam A. Kennington III catch (const std::exception& e) 471bbe3d1eSWilliam A. Kennington III { 481bbe3d1eSWilliam A. Kennington III exitWithError("Interface not specified.", argv); 491bbe3d1eSWilliam A. Kennington III } 501bbe3d1eSWilliam A. Kennington III 511bbe3d1eSWilliam A. Kennington III if (indexInt < 0) 521bbe3d1eSWilliam A. Kennington III { 531bbe3d1eSWilliam A. Kennington III exitWithError("Interface value should be greater than equal to 0", 541bbe3d1eSWilliam A. Kennington III argv); 551bbe3d1eSWilliam A. Kennington III } 561bbe3d1eSWilliam A. Kennington III 571bbe3d1eSWilliam A. Kennington III // Parse out package argument. 581bbe3d1eSWilliam A. Kennington III auto package = (options)["package"]; 591bbe3d1eSWilliam A. Kennington III try 601bbe3d1eSWilliam A. Kennington III { 611bbe3d1eSWilliam A. Kennington III packageInt = stoi(package, nullptr); 621bbe3d1eSWilliam A. Kennington III } 631bbe3d1eSWilliam A. Kennington III catch (const std::exception& e) 641bbe3d1eSWilliam A. Kennington III { 651bbe3d1eSWilliam A. Kennington III packageInt = DEFAULT_VALUE; 661bbe3d1eSWilliam A. Kennington III } 671bbe3d1eSWilliam A. Kennington III 681bbe3d1eSWilliam A. Kennington III if (packageInt < 0) 691bbe3d1eSWilliam A. Kennington III { 701bbe3d1eSWilliam A. Kennington III packageInt = DEFAULT_VALUE; 711bbe3d1eSWilliam A. Kennington III } 721bbe3d1eSWilliam A. Kennington III 731bbe3d1eSWilliam A. Kennington III // Parse out channel argument. 741bbe3d1eSWilliam A. Kennington III auto channel = (options)["channel"]; 751bbe3d1eSWilliam A. Kennington III try 761bbe3d1eSWilliam A. Kennington III { 771bbe3d1eSWilliam A. Kennington III channelInt = stoi(channel, nullptr); 781bbe3d1eSWilliam A. Kennington III } 791bbe3d1eSWilliam A. Kennington III catch (const std::exception& e) 801bbe3d1eSWilliam A. Kennington III { 811bbe3d1eSWilliam A. Kennington III channelInt = DEFAULT_VALUE; 821bbe3d1eSWilliam A. Kennington III } 831bbe3d1eSWilliam A. Kennington III 841bbe3d1eSWilliam A. Kennington III if (channelInt < 0) 851bbe3d1eSWilliam A. Kennington III { 861bbe3d1eSWilliam A. Kennington III channelInt = DEFAULT_VALUE; 871bbe3d1eSWilliam A. Kennington III } 881bbe3d1eSWilliam A. Kennington III 89fa1f5c03SEddie James auto payloadStr = (options)["oem-payload"]; 90fa1f5c03SEddie James if (!payloadStr.empty()) 91fa1f5c03SEddie James { 92fa1f5c03SEddie James std::string byte(2, '\0'); 93fa1f5c03SEddie James std::vector<unsigned char> payload; 94fa1f5c03SEddie James 95fa1f5c03SEddie James if (payloadStr.size() % 2) 96fa1f5c03SEddie James exitWithError("Payload invalid: specify two hex digits per byte.", 97fa1f5c03SEddie James argv); 98fa1f5c03SEddie James 99fa1f5c03SEddie James // Parse the payload string (e.g. "000001572100") to byte data 100fa1f5c03SEddie James for (unsigned int i = 1; i < payloadStr.size(); i += 2) 101fa1f5c03SEddie James { 102fa1f5c03SEddie James byte[0] = payloadStr[i - 1]; 103fa1f5c03SEddie James byte[1] = payloadStr[i]; 104fa1f5c03SEddie James 105fa1f5c03SEddie James try 106fa1f5c03SEddie James { 107fa1f5c03SEddie James payload.push_back(stoi(byte, nullptr, 16)); 108fa1f5c03SEddie James } 109fa1f5c03SEddie James catch (const std::exception& e) 110fa1f5c03SEddie James { 111fa1f5c03SEddie James exitWithError("Payload invalid.", argv); 112fa1f5c03SEddie James } 113fa1f5c03SEddie James } 114fa1f5c03SEddie James 115fa1f5c03SEddie James if (payload.empty()) 116fa1f5c03SEddie James { 117fa1f5c03SEddie James exitWithError("No payload specified.", argv); 118fa1f5c03SEddie James } 119fa1f5c03SEddie James 120fa1f5c03SEddie James if (packageInt == DEFAULT_VALUE) 121fa1f5c03SEddie James { 122fa1f5c03SEddie James exitWithError("Package not specified.", argv); 123fa1f5c03SEddie James } 124fa1f5c03SEddie James 125fa1f5c03SEddie James return ncsi::sendOemCommand( 126fa1f5c03SEddie James indexInt, packageInt, channelInt, 127fa1f5c03SEddie James std::span<const unsigned char>(payload.begin(), payload.end())); 128fa1f5c03SEddie James } 129fa1f5c03SEddie James else if ((options)["set"] == "true") 1301bbe3d1eSWilliam A. Kennington III { 1311bbe3d1eSWilliam A. Kennington III // Can not perform set operation without package. 1321bbe3d1eSWilliam A. Kennington III if (packageInt == DEFAULT_VALUE) 1331bbe3d1eSWilliam A. Kennington III { 1341bbe3d1eSWilliam A. Kennington III exitWithError("Package not specified.", argv); 1351bbe3d1eSWilliam A. Kennington III } 1361bbe3d1eSWilliam A. Kennington III return ncsi::setChannel(indexInt, packageInt, channelInt); 1371bbe3d1eSWilliam A. Kennington III } 1381bbe3d1eSWilliam A. Kennington III else if ((options)["info"] == "true") 1391bbe3d1eSWilliam A. Kennington III { 1401bbe3d1eSWilliam A. Kennington III return ncsi::getInfo(indexInt, packageInt); 1411bbe3d1eSWilliam A. Kennington III } 1421bbe3d1eSWilliam A. Kennington III else if ((options)["clear"] == "true") 1431bbe3d1eSWilliam A. Kennington III { 1441bbe3d1eSWilliam A. Kennington III return ncsi::clearInterface(indexInt); 1451bbe3d1eSWilliam A. Kennington III } 1461bbe3d1eSWilliam A. Kennington III else 1471bbe3d1eSWilliam A. Kennington III { 1481bbe3d1eSWilliam A. Kennington III exitWithError("No Command specified", argv); 1491bbe3d1eSWilliam A. Kennington III } 1501bbe3d1eSWilliam A. Kennington III return 0; 1511bbe3d1eSWilliam A. Kennington III } 152