blob: 7808ef731d53e658afc77840f3030b0461d56984 [file] [log] [blame]
Ratan Guptab38401b2018-03-16 12:44:26 +05301/**
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 */
Ratan Guptaed5d7ff2018-03-23 00:27:52 +053016#include "argument.hpp"
17#include "ncsi_util.hpp"
18
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -070019#include <phosphor-logging/lg2.hpp>
Patrick Williams89d734b2023-05-10 07:50:25 -050020
Ratan Guptaed5d7ff2018-03-23 00:27:52 +053021#include <string>
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050022#include <vector>
Ratan Guptaed5d7ff2018-03-23 00:27:52 +053023
24static void exitWithError(const char* err, char** argv)
25{
26 phosphor::network::ncsi::ArgumentParser::usage(argv);
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -070027 lg2::error("ERROR: {ERROR}", "ERROR", err);
Ratan Guptaed5d7ff2018-03-23 00:27:52 +053028 exit(EXIT_FAILURE);
29}
30
Ratan Guptab38401b2018-03-16 12:44:26 +053031int main(int argc, char** argv)
32{
Ratan Guptaed5d7ff2018-03-23 00:27:52 +053033 using namespace phosphor::network;
34 using namespace phosphor::network::ncsi;
35 // Read arguments.
36 auto options = ArgumentParser(argc, argv);
Gunnar Mills57d9c502018-09-14 14:42:34 -050037 int packageInt{};
38 int channelInt{};
39 int indexInt{};
Johnathan Mantey1ebea282024-02-15 10:26:06 -080040 int operationInt{DEFAULT_VALUE};
Ratan Guptaed5d7ff2018-03-23 00:27:52 +053041
42 // Parse out interface argument.
43 auto ifIndex = (options)["index"];
44 try
45 {
46 indexInt = stoi(ifIndex, nullptr);
47 }
48 catch (const std::exception& e)
49 {
50 exitWithError("Interface not specified.", argv);
51 }
52
53 if (indexInt < 0)
54 {
Gunnar Mills57d9c502018-09-14 14:42:34 -050055 exitWithError("Interface value should be greater than equal to 0",
56 argv);
Ratan Guptaed5d7ff2018-03-23 00:27:52 +053057 }
58
59 // Parse out package argument.
60 auto package = (options)["package"];
61 try
62 {
63 packageInt = stoi(package, nullptr);
64 }
65 catch (const std::exception& e)
66 {
Gunnar Mills57d9c502018-09-14 14:42:34 -050067 packageInt = DEFAULT_VALUE;
Ratan Guptaed5d7ff2018-03-23 00:27:52 +053068 }
69
70 if (packageInt < 0)
71 {
72 packageInt = DEFAULT_VALUE;
73 }
74
75 // Parse out channel argument.
76 auto channel = (options)["channel"];
77 try
78 {
79 channelInt = stoi(channel, nullptr);
80 }
81 catch (const std::exception& e)
82 {
Gunnar Mills57d9c502018-09-14 14:42:34 -050083 channelInt = DEFAULT_VALUE;
Ratan Guptaed5d7ff2018-03-23 00:27:52 +053084 }
85
86 if (channelInt < 0)
87 {
88 channelInt = DEFAULT_VALUE;
89 }
90
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050091 auto payloadStr = (options)["oem-payload"];
92 if (!payloadStr.empty())
93 {
94 std::string byte(2, '\0');
95 std::vector<unsigned char> payload;
96
97 if (payloadStr.size() % 2)
98 exitWithError("Payload invalid: specify two hex digits per byte.",
99 argv);
100
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800101 // Parse the payload string (e.g. "50000001572100") to byte data
102 // The first two characters (i.e. "50") represent the Send Cmd Operation
103 // All remaining pairs, interpreted in hex radix, represent the command
104 // payload
105 int sendCmdSelect{};
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500106 for (unsigned int i = 1; i < payloadStr.size(); i += 2)
107 {
108 byte[0] = payloadStr[i - 1];
109 byte[1] = payloadStr[i];
110
111 try
112 {
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800113 sendCmdSelect = stoi(byte, nullptr, 16);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500114 }
115 catch (const std::exception& e)
116 {
117 exitWithError("Payload invalid.", argv);
118 }
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800119 if (i == 1)
120 {
121 operationInt = sendCmdSelect;
122 }
123 else
124 {
125 payload.push_back(sendCmdSelect);
126 }
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500127 }
128
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800129 if (operationInt == DEFAULT_VALUE)
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500130 {
131 exitWithError("No payload specified.", argv);
132 }
133
134 if (packageInt == DEFAULT_VALUE)
135 {
136 exitWithError("Package not specified.", argv);
137 }
138
139 return ncsi::sendOemCommand(
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800140 indexInt, packageInt, channelInt, operationInt,
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500141 std::span<const unsigned char>(payload.begin(), payload.end()));
142 }
143 else if ((options)["set"] == "true")
Ratan Guptaed5d7ff2018-03-23 00:27:52 +0530144 {
Gunnar Mills6af61442018-04-08 14:50:06 -0500145 // Can not perform set operation without package.
Ratan Guptaed5d7ff2018-03-23 00:27:52 +0530146 if (packageInt == DEFAULT_VALUE)
147 {
148 exitWithError("Package not specified.", argv);
149 }
150 return ncsi::setChannel(indexInt, packageInt, channelInt);
151 }
152 else if ((options)["info"] == "true")
153 {
154 return ncsi::getInfo(indexInt, packageInt);
155 }
156 else if ((options)["clear"] == "true")
157 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500158 return ncsi::clearInterface(indexInt);
Ratan Guptaed5d7ff2018-03-23 00:27:52 +0530159 }
160 else
161 {
162 exitWithError("No Command specified", argv);
163 }
Ratan Guptab38401b2018-03-16 12:44:26 +0530164 return 0;
165}