blob: 04e0cbc15724c29727a3dd482badad5231f58d8d [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
Jeremy Kerr8d9af022024-07-26 16:47:16 +080059 Interface interface{indexInt};
60
Ratan Guptaed5d7ff2018-03-23 00:27:52 +053061 // Parse out package argument.
62 auto package = (options)["package"];
63 try
64 {
65 packageInt = stoi(package, nullptr);
66 }
67 catch (const std::exception& e)
68 {
Gunnar Mills57d9c502018-09-14 14:42:34 -050069 packageInt = DEFAULT_VALUE;
Ratan Guptaed5d7ff2018-03-23 00:27:52 +053070 }
71
72 if (packageInt < 0)
73 {
74 packageInt = DEFAULT_VALUE;
75 }
76
77 // Parse out channel argument.
78 auto channel = (options)["channel"];
79 try
80 {
81 channelInt = stoi(channel, nullptr);
82 }
83 catch (const std::exception& e)
84 {
Gunnar Mills57d9c502018-09-14 14:42:34 -050085 channelInt = DEFAULT_VALUE;
Ratan Guptaed5d7ff2018-03-23 00:27:52 +053086 }
87
88 if (channelInt < 0)
89 {
90 channelInt = DEFAULT_VALUE;
91 }
92
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050093 auto payloadStr = (options)["oem-payload"];
94 if (!payloadStr.empty())
95 {
96 std::string byte(2, '\0');
97 std::vector<unsigned char> payload;
98
99 if (payloadStr.size() % 2)
100 exitWithError("Payload invalid: specify two hex digits per byte.",
101 argv);
102
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800103 // Parse the payload string (e.g. "50000001572100") to byte data
104 // The first two characters (i.e. "50") represent the Send Cmd Operation
105 // All remaining pairs, interpreted in hex radix, represent the command
106 // payload
107 int sendCmdSelect{};
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500108 for (unsigned int i = 1; i < payloadStr.size(); i += 2)
109 {
110 byte[0] = payloadStr[i - 1];
111 byte[1] = payloadStr[i];
112
113 try
114 {
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800115 sendCmdSelect = stoi(byte, nullptr, 16);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500116 }
117 catch (const std::exception& e)
118 {
119 exitWithError("Payload invalid.", argv);
120 }
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800121 if (i == 1)
122 {
123 operationInt = sendCmdSelect;
124 }
125 else
126 {
127 payload.push_back(sendCmdSelect);
128 }
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500129 }
130
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800131 if (operationInt == DEFAULT_VALUE)
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500132 {
133 exitWithError("No payload specified.", argv);
134 }
135
136 if (packageInt == DEFAULT_VALUE)
137 {
138 exitWithError("Package not specified.", argv);
139 }
140
Jeremy Kerrbc22f812024-07-29 17:43:35 +0800141 return interface.sendOemCommand(
142 packageInt, channelInt, operationInt,
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500143 std::span<const unsigned char>(payload.begin(), payload.end()));
144 }
145 else if ((options)["set"] == "true")
Ratan Guptaed5d7ff2018-03-23 00:27:52 +0530146 {
Gunnar Mills6af61442018-04-08 14:50:06 -0500147 // Can not perform set operation without package.
Ratan Guptaed5d7ff2018-03-23 00:27:52 +0530148 if (packageInt == DEFAULT_VALUE)
149 {
150 exitWithError("Package not specified.", argv);
151 }
Jeremy Kerrbc22f812024-07-29 17:43:35 +0800152 return interface.setChannel(packageInt, channelInt);
Ratan Guptaed5d7ff2018-03-23 00:27:52 +0530153 }
154 else if ((options)["info"] == "true")
155 {
Jeremy Kerrbc22f812024-07-29 17:43:35 +0800156 return interface.getInfo(packageInt);
Ratan Guptaed5d7ff2018-03-23 00:27:52 +0530157 }
158 else if ((options)["clear"] == "true")
159 {
Jeremy Kerrbc22f812024-07-29 17:43:35 +0800160 return interface.clearInterface();
Ratan Guptaed5d7ff2018-03-23 00:27:52 +0530161 }
Johnathan Mantey5a456062024-02-15 08:45:08 -0800162 else if (!(options)["pmask"].empty())
163 {
164 unsigned int mask{};
165 try
166 {
167 size_t lastChar{};
168 mask = std::stoul((options)["pmask"], &lastChar, 0);
169 if (lastChar < (options["pmask"].size()))
170 {
171 exitWithError("Package mask value is not valid", argv);
172 }
173 }
174 catch (const std::exception& e)
175 {
176 exitWithError("Package mask value is not valid", argv);
177 }
Jeremy Kerrbc22f812024-07-29 17:43:35 +0800178 return interface.setPackageMask(mask);
Johnathan Mantey5a456062024-02-15 08:45:08 -0800179 }
180 else if (!(options)["cmask"].empty())
181 {
182 if (packageInt == DEFAULT_VALUE)
183 {
184 exitWithError("Package is not specified", argv);
185 }
186 unsigned int mask{};
187 try
188 {
189 size_t lastChar{};
190 mask = stoul((options)["cmask"], &lastChar, 0);
191 if (lastChar < (options["cmask"].size()))
192 {
193 exitWithError("Channel mask value is not valid", argv);
194 }
195 }
196 catch (const std::exception& e)
197 {
198 exitWithError("Channel mask value is not valid", argv);
199 }
Jeremy Kerrbc22f812024-07-29 17:43:35 +0800200 return interface.setChannelMask(packageInt, mask);
Johnathan Mantey5a456062024-02-15 08:45:08 -0800201 }
Ratan Guptaed5d7ff2018-03-23 00:27:52 +0530202 else
203 {
204 exitWithError("No Command specified", argv);
205 }
Ratan Guptab38401b2018-03-16 12:44:26 +0530206 return 0;
207}