blob: 839c80d71506b5cf060b180181989090b1d07fa5 [file] [log] [blame]
Patrick Venture189d44e2018-07-09 12:30:59 -07001#include "ncsi_util.hpp"
2
Ratan Guptabbe45792018-03-23 00:22:55 +05303#include <linux/ncsi.h>
Ratan Guptabbe45792018-03-23 00:22:55 +05304#include <netlink/genl/ctrl.h>
Gunnar Mills57d9c502018-09-14 14:42:34 -05005#include <netlink/genl/genl.h>
6#include <netlink/netlink.h>
Ratan Guptabbe45792018-03-23 00:22:55 +05307
Patrick Williams89d734b2023-05-10 07:50:25 -05008#include <phosphor-logging/lg2.hpp>
William A. Kennington IIIcbe50732023-07-25 13:52:18 -07009#include <stdplus/numeric/str.hpp>
10#include <stdplus/str/buf.hpp>
Patrick Williams89d734b2023-05-10 07:50:25 -050011
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050012#include <iomanip>
Manojkiran Edae5a867a2020-06-01 18:08:30 +053013#include <iostream>
Jiaqing Zhao7c44a782022-04-10 15:30:04 +080014#include <vector>
Ratan Guptabbe45792018-03-23 00:22:55 +053015
16namespace phosphor
17{
18namespace network
19{
20namespace ncsi
21{
22
Gunnar Mills57d9c502018-09-14 14:42:34 -050023using CallBack = int (*)(struct nl_msg* msg, void* arg);
Ratan Guptaaac603e2018-03-23 00:25:54 +053024
William A. Kennington IIIcbe50732023-07-25 13:52:18 -070025static stdplus::StrBuf toHexStr(std::span<const uint8_t> c) noexcept
26{
27 stdplus::StrBuf ret;
28 if (c.empty())
29 {
30 return ret;
31 }
32 stdplus::IntToStr<16, uint8_t> its;
Johnathan Mantey1ebea282024-02-15 10:26:06 -080033 auto oit = ret.append(c.size() * 3);
William A. Kennington IIIcbe50732023-07-25 13:52:18 -070034 auto cit = c.begin();
35 oit = its(oit, *cit++, 2);
36 for (; cit != c.end(); ++cit)
37 {
38 *oit++ = ' ';
39 oit = its(oit, *cit, 2);
40 }
Johnathan Mantey1ebea282024-02-15 10:26:06 -080041 *oit = 0;
William A. Kennington IIIcbe50732023-07-25 13:52:18 -070042 return ret;
43}
44
Ratan Guptaaac603e2018-03-23 00:25:54 +053045namespace internal
46{
Ratan Guptabbe45792018-03-23 00:22:55 +053047
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050048struct NCSIPacketHeader
49{
50 uint8_t MCID;
51 uint8_t revision;
52 uint8_t reserved;
53 uint8_t id;
54 uint8_t type;
55 uint8_t channel;
56 uint16_t length;
57 uint32_t rsvd[2];
58};
59
60class Command
61{
62 public:
63 Command() = delete;
64 ~Command() = default;
65 Command(const Command&) = delete;
66 Command& operator=(const Command&) = delete;
67 Command(Command&&) = default;
68 Command& operator=(Command&&) = default;
69 Command(
Johnathan Mantey1ebea282024-02-15 10:26:06 -080070 int ncsiCmd, int operation = DEFAULT_VALUE,
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050071 std::span<const unsigned char> p = std::span<const unsigned char>()) :
Patrick Williamsad205022024-08-16 15:20:07 -040072 ncsi_cmd(ncsiCmd), operation(operation), payload(p)
Patrick Williams89d734b2023-05-10 07:50:25 -050073 {}
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050074
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050075 int ncsi_cmd;
Johnathan Mantey1ebea282024-02-15 10:26:06 -080076 int operation;
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050077 std::span<const unsigned char> payload;
78};
79
Ratan Guptabbe45792018-03-23 00:22:55 +053080using nlMsgPtr = std::unique_ptr<nl_msg, decltype(&::nlmsg_free)>;
81using nlSocketPtr = std::unique_ptr<nl_sock, decltype(&::nl_socket_free)>;
82
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050083CallBack infoCallBack = [](struct nl_msg* msg, void* arg) {
Ratan Guptaaac603e2018-03-23 00:25:54 +053084 using namespace phosphor::network::ncsi;
85 auto nlh = nlmsg_hdr(msg);
86
Gunnar Mills57d9c502018-09-14 14:42:34 -050087 struct nlattr* tb[NCSI_ATTR_MAX + 1] = {nullptr};
88 struct nla_policy ncsiPolicy[NCSI_ATTR_MAX + 1] = {
William A. Kennington III05368f12021-05-13 18:40:47 -070089 {NLA_UNSPEC, 0, 0}, {NLA_U32, 0, 0}, {NLA_NESTED, 0, 0},
90 {NLA_U32, 0, 0}, {NLA_U32, 0, 0},
Ratan Guptaaac603e2018-03-23 00:25:54 +053091 };
92
Gunnar Mills57d9c502018-09-14 14:42:34 -050093 struct nlattr* packagetb[NCSI_PKG_ATTR_MAX + 1] = {nullptr};
94 struct nla_policy packagePolicy[NCSI_PKG_ATTR_MAX + 1] = {
William A. Kennington III05368f12021-05-13 18:40:47 -070095 {NLA_UNSPEC, 0, 0}, {NLA_NESTED, 0, 0}, {NLA_U32, 0, 0},
96 {NLA_FLAG, 0, 0}, {NLA_NESTED, 0, 0},
Ratan Guptaaac603e2018-03-23 00:25:54 +053097 };
98
Gunnar Mills57d9c502018-09-14 14:42:34 -050099 struct nlattr* channeltb[NCSI_CHANNEL_ATTR_MAX + 1] = {nullptr};
100 struct nla_policy channelPolicy[NCSI_CHANNEL_ATTR_MAX + 1] = {
William A. Kennington III05368f12021-05-13 18:40:47 -0700101 {NLA_UNSPEC, 0, 0}, {NLA_NESTED, 0, 0}, {NLA_U32, 0, 0},
102 {NLA_FLAG, 0, 0}, {NLA_NESTED, 0, 0}, {NLA_UNSPEC, 0, 0},
Ratan Guptaaac603e2018-03-23 00:25:54 +0530103 };
104
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500105 *(int*)arg = 0;
106
Ratan Guptaaac603e2018-03-23 00:25:54 +0530107 auto ret = genlmsg_parse(nlh, 0, tb, NCSI_ATTR_MAX, ncsiPolicy);
108 if (!tb[NCSI_ATTR_PACKAGE_LIST])
109 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700110 lg2::error("No Packages");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530111 return -1;
112 }
113
114 auto attrTgt = static_cast<nlattr*>(nla_data(tb[NCSI_ATTR_PACKAGE_LIST]));
115 if (!attrTgt)
116 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700117 lg2::error("Package list attribute is null");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530118 return -1;
119 }
120
121 auto rem = nla_len(tb[NCSI_ATTR_PACKAGE_LIST]);
122 nla_for_each_nested(attrTgt, tb[NCSI_ATTR_PACKAGE_LIST], rem)
123 {
124 ret = nla_parse_nested(packagetb, NCSI_PKG_ATTR_MAX, attrTgt,
125 packagePolicy);
126 if (ret < 0)
127 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700128 lg2::error("Failed to parse package nested");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530129 return -1;
130 }
131
132 if (packagetb[NCSI_PKG_ATTR_ID])
133 {
134 auto attrID = nla_get_u32(packagetb[NCSI_PKG_ATTR_ID]);
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700135 lg2::debug("Package has id : {ATTR_ID}", "ATTR_ID", lg2::hex,
136 attrID);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530137 }
138 else
139 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700140 lg2::debug("Package with no id");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530141 }
142
143 if (packagetb[NCSI_PKG_ATTR_FORCED])
144 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700145 lg2::debug("This package is forced");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530146 }
147
148 auto channelListTarget = static_cast<nlattr*>(
Gunnar Mills57d9c502018-09-14 14:42:34 -0500149 nla_data(packagetb[NCSI_PKG_ATTR_CHANNEL_LIST]));
Ratan Guptaaac603e2018-03-23 00:25:54 +0530150
151 auto channelrem = nla_len(packagetb[NCSI_PKG_ATTR_CHANNEL_LIST]);
152 nla_for_each_nested(channelListTarget,
153 packagetb[NCSI_PKG_ATTR_CHANNEL_LIST], channelrem)
154 {
155 ret = nla_parse_nested(channeltb, NCSI_CHANNEL_ATTR_MAX,
156 channelListTarget, channelPolicy);
157 if (ret < 0)
158 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700159 lg2::error("Failed to parse channel nested");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530160 return -1;
161 }
162
163 if (channeltb[NCSI_CHANNEL_ATTR_ID])
164 {
165 auto channel = nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_ID]);
166 if (channeltb[NCSI_CHANNEL_ATTR_ACTIVE])
167 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700168 lg2::debug("Channel Active : {CHANNEL}", "CHANNEL",
169 lg2::hex, channel);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530170 }
171 else
172 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700173 lg2::debug("Channel Not Active : {CHANNEL}", "CHANNEL",
174 lg2::hex, channel);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530175 }
176
177 if (channeltb[NCSI_CHANNEL_ATTR_FORCED])
178 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700179 lg2::debug("Channel is forced");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530180 }
Ratan Guptaaac603e2018-03-23 00:25:54 +0530181 }
182 else
183 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700184 lg2::debug("Channel with no ID");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530185 }
Ratan Guptaed5d7ff2018-03-23 00:27:52 +0530186
Ratan Guptaaac603e2018-03-23 00:25:54 +0530187 if (channeltb[NCSI_CHANNEL_ATTR_VERSION_MAJOR])
188 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500189 auto major =
190 nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_VERSION_MAJOR]);
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700191 lg2::debug("Channel Major Version : {CHANNEL_MAJOR_VERSION}",
192 "CHANNEL_MAJOR_VERSION", lg2::hex, major);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530193 }
194 if (channeltb[NCSI_CHANNEL_ATTR_VERSION_MINOR])
195 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500196 auto minor =
197 nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_VERSION_MINOR]);
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700198 lg2::debug("Channel Minor Version : {CHANNEL_MINOR_VERSION}",
199 "CHANNEL_MINOR_VERSION", lg2::hex, minor);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530200 }
201 if (channeltb[NCSI_CHANNEL_ATTR_VERSION_STR])
202 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500203 auto str =
204 nla_get_string(channeltb[NCSI_CHANNEL_ATTR_VERSION_STR]);
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700205 lg2::debug("Channel Version Str : {CHANNEL_VERSION_STR}",
206 "CHANNEL_VERSION_STR", str);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530207 }
208 if (channeltb[NCSI_CHANNEL_ATTR_LINK_STATE])
209 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500210 auto link =
211 nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_LINK_STATE]);
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700212 lg2::debug("Channel Link State : {LINK_STATE}", "LINK_STATE",
213 lg2::hex, link);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530214 }
215 if (channeltb[NCSI_CHANNEL_ATTR_VLAN_LIST])
216 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700217 lg2::debug("Active Vlan ids");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530218 auto vids = channeltb[NCSI_CHANNEL_ATTR_VLAN_LIST];
219 auto vid = static_cast<nlattr*>(nla_data(vids));
220 auto len = nla_len(vids);
221 while (nla_ok(vid, len))
222 {
223 auto id = nla_get_u16(vid);
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700224 lg2::debug("VID : {VLAN_ID}", "VLAN_ID", id);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530225 vid = nla_next(vid, &len);
226 }
227 }
Ratan Guptaaac603e2018-03-23 00:25:54 +0530228 }
Ratan Guptaaac603e2018-03-23 00:25:54 +0530229 }
230 return (int)NL_SKIP;
231};
232
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500233CallBack sendCallBack = [](struct nl_msg* msg, void* arg) {
234 using namespace phosphor::network::ncsi;
235 auto nlh = nlmsg_hdr(msg);
236 struct nlattr* tb[NCSI_ATTR_MAX + 1] = {nullptr};
237 static struct nla_policy ncsiPolicy[NCSI_ATTR_MAX + 1] = {
238 {NLA_UNSPEC, 0, 0}, {NLA_U32, 0, 0}, {NLA_NESTED, 0, 0},
239 {NLA_U32, 0, 0}, {NLA_U32, 0, 0}, {NLA_BINARY, 0, 0},
240 {NLA_FLAG, 0, 0}, {NLA_U32, 0, 0}, {NLA_U32, 0, 0},
241 };
242
243 *(int*)arg = 0;
244
245 auto ret = genlmsg_parse(nlh, 0, tb, NCSI_ATTR_MAX, ncsiPolicy);
246 if (ret)
247 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700248 lg2::error("Failed to parse package");
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500249 return ret;
250 }
251
Jian Zhang442d9e52022-10-20 22:11:14 +0800252 if (tb[NCSI_ATTR_DATA] == nullptr)
253 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700254 lg2::error("Response: No data");
Jian Zhang442d9e52022-10-20 22:11:14 +0800255 return -1;
256 }
257
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500258 auto data_len = nla_len(tb[NCSI_ATTR_DATA]) - sizeof(NCSIPacketHeader);
Patrick Williamsad205022024-08-16 15:20:07 -0400259 unsigned char* data =
260 (unsigned char*)nla_data(tb[NCSI_ATTR_DATA]) + sizeof(NCSIPacketHeader);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500261
262 // Dump the response to stdout. Enhancement: option to save response data
William A. Kennington IIIcbe50732023-07-25 13:52:18 -0700263 auto str = toHexStr(std::span<const unsigned char>(data, data_len));
264 lg2::debug("Response {DATA_LEN} bytes: {DATA}", "DATA_LEN", data_len,
265 "DATA", str);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500266
267 return 0;
268};
269
270int applyCmd(int ifindex, const Command& cmd, int package = DEFAULT_VALUE,
Ratan Guptaaac603e2018-03-23 00:25:54 +0530271 int channel = DEFAULT_VALUE, int flags = NONE,
272 CallBack function = nullptr)
Ratan Guptabbe45792018-03-23 00:22:55 +0530273{
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500274 int cb_ret = 0;
Gunnar Mills57d9c502018-09-14 14:42:34 -0500275 nlSocketPtr socket(nl_socket_alloc(), &::nl_socket_free);
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700276 if (socket == nullptr)
277 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700278 lg2::error("Unable to allocate memory for the socket");
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700279 return -ENOMEM;
280 }
281
Ratan Guptabbe45792018-03-23 00:22:55 +0530282 auto ret = genl_connect(socket.get());
283 if (ret < 0)
284 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700285 lg2::error("Failed to open the socket , RC : {RC}", "RC", ret);
Ratan Guptabbe45792018-03-23 00:22:55 +0530286 return ret;
287 }
288
289 auto driverID = genl_ctrl_resolve(socket.get(), "NCSI");
290 if (driverID < 0)
291 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700292 lg2::error("Failed to resolve, RC : {RC}", "RC", ret);
Ratan Guptabbe45792018-03-23 00:22:55 +0530293 return driverID;
294 }
295
296 nlMsgPtr msg(nlmsg_alloc(), &::nlmsg_free);
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700297 if (msg == nullptr)
298 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700299 lg2::error("Unable to allocate memory for the message");
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700300 return -ENOMEM;
301 }
Ratan Guptabbe45792018-03-23 00:22:55 +0530302
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800303 auto msgHdr = genlmsg_put(msg.get(), NL_AUTO_PORT, NL_AUTO_SEQ, driverID, 0,
304 flags, cmd.ncsi_cmd, 0);
Ratan Guptabbe45792018-03-23 00:22:55 +0530305 if (!msgHdr)
306 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700307 lg2::error("Unable to add the netlink headers , COMMAND : {COMMAND}",
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800308 "COMMAND", cmd.ncsi_cmd);
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700309 return -ENOMEM;
Ratan Guptabbe45792018-03-23 00:22:55 +0530310 }
311
312 if (package != DEFAULT_VALUE)
313 {
314 ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_PACKAGE_ID,
315 package);
316 if (ret < 0)
317 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700318 lg2::error("Failed to set the attribute , RC : {RC} PACKAGE "
319 "{PACKAGE}",
320 "RC", ret, "PACKAGE", lg2::hex, package);
Ratan Guptabbe45792018-03-23 00:22:55 +0530321 return ret;
322 }
323 }
324
325 if (channel != DEFAULT_VALUE)
326 {
327 ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_CHANNEL_ID,
328 channel);
329 if (ret < 0)
330 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700331 lg2::error("Failed to set the attribute , RC : {RC} CHANNEL : "
332 "{CHANNEL}",
333 "RC", ret, "CHANNEL", lg2::hex, channel);
Ratan Guptabbe45792018-03-23 00:22:55 +0530334 return ret;
335 }
336 }
337
338 ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_IFINDEX, ifindex);
339 if (ret < 0)
340 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700341 lg2::error("Failed to set the attribute , RC : {RC} INTERFACE : "
342 "{INTERFACE}",
343 "RC", ret, "INTERFACE", lg2::hex, ifindex);
Ratan Guptabbe45792018-03-23 00:22:55 +0530344 return ret;
345 }
346
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800347 if (cmd.operation != DEFAULT_VALUE)
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500348 {
Patrick Williamsad205022024-08-16 15:20:07 -0400349 std::vector<unsigned char> pl(
350 sizeof(NCSIPacketHeader) + cmd.payload.size());
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500351 NCSIPacketHeader* hdr = (NCSIPacketHeader*)pl.data();
352
353 std::copy(cmd.payload.begin(), cmd.payload.end(),
354 pl.begin() + sizeof(NCSIPacketHeader));
355
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800356 hdr->type = cmd.operation;
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500357 hdr->length = htons(cmd.payload.size());
358
359 ret = nla_put(msg.get(), ncsi_nl_attrs::NCSI_ATTR_DATA, pl.size(),
360 pl.data());
361 if (ret < 0)
362 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700363 lg2::error("Failed to set the data attribute, RC : {RC}", "RC",
364 ret);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500365 return ret;
366 }
367
368 nl_socket_disable_seq_check(socket.get());
369 }
370
Ratan Guptaaac603e2018-03-23 00:25:54 +0530371 if (function)
372 {
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500373 cb_ret = 1;
374
Ratan Guptaaac603e2018-03-23 00:25:54 +0530375 // Add a callback function to the socket
Gunnar Mills57d9c502018-09-14 14:42:34 -0500376 nl_socket_modify_cb(socket.get(), NL_CB_VALID, NL_CB_CUSTOM, function,
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500377 &cb_ret);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530378 }
Ratan Guptabbe45792018-03-23 00:22:55 +0530379
380 ret = nl_send_auto(socket.get(), msg.get());
381 if (ret < 0)
382 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700383 lg2::error("Failed to send the message , RC : {RC}", "RC", ret);
Ratan Guptabbe45792018-03-23 00:22:55 +0530384 return ret;
385 }
386
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500387 do
Ratan Guptabbe45792018-03-23 00:22:55 +0530388 {
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500389 ret = nl_recvmsgs_default(socket.get());
390 if (ret < 0)
391 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700392 lg2::error("Failed to receive the message , RC : {RC}", "RC", ret);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500393 break;
394 }
395 } while (cb_ret);
396
Ratan Guptabbe45792018-03-23 00:22:55 +0530397 return ret;
398}
399
Gunnar Mills57d9c502018-09-14 14:42:34 -0500400} // namespace internal
Ratan Guptabbe45792018-03-23 00:22:55 +0530401
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800402int sendOemCommand(int ifindex, int package, int channel, int operation,
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500403 std::span<const unsigned char> payload)
404{
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700405 lg2::debug("Send OEM Command, CHANNEL : {CHANNEL} , PACKAGE : {PACKAGE}, "
406 "INTERFACE_INDEX: {INTERFACE_INDEX}",
407 "CHANNEL", lg2::hex, channel, "PACKAGE", lg2::hex, package,
408 "INTERFACE_INDEX", lg2::hex, ifindex);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500409 if (!payload.empty())
410 {
William A. Kennington IIIcbe50732023-07-25 13:52:18 -0700411 lg2::debug("Payload: {PAYLOAD}", "PAYLOAD", toHexStr(payload));
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500412 }
413
414 return internal::applyCmd(
415 ifindex,
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800416 internal::Command(ncsi_nl_commands::NCSI_CMD_SEND_CMD, operation,
417 payload),
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500418 package, channel, NONE, internal::sendCallBack);
419}
420
Ratan Guptabbe45792018-03-23 00:22:55 +0530421int setChannel(int ifindex, int package, int channel)
422{
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700423 lg2::debug(
424 "Set CHANNEL : {CHANNEL} , PACKAGE : {PACKAGE}, INTERFACE_INDEX: "
425 "{INTERFACE_INDEX}",
426 "CHANNEL", lg2::hex, channel, "PACKAGE", lg2::hex, package,
427 "INTERFACE_INDEX", lg2::hex, ifindex);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500428 return internal::applyCmd(
429 ifindex, internal::Command(ncsi_nl_commands::NCSI_CMD_SET_INTERFACE),
430 package, channel);
Ratan Guptabbe45792018-03-23 00:22:55 +0530431}
432
433int clearInterface(int ifindex)
434{
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700435 lg2::debug("ClearInterface , INTERFACE_INDEX : {INTERFACE_INDEX}",
436 "INTERFACE_INDEX", lg2::hex, ifindex);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500437 return internal::applyCmd(
438 ifindex, internal::Command(ncsi_nl_commands::NCSI_CMD_CLEAR_INTERFACE));
Ratan Guptabbe45792018-03-23 00:22:55 +0530439}
440
Ratan Guptaaac603e2018-03-23 00:25:54 +0530441int getInfo(int ifindex, int package)
442{
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700443 lg2::debug(
444 "Get Info , PACKAGE : {PACKAGE}, INTERFACE_INDEX: {INTERFACE_INDEX}",
445 "PACKAGE", lg2::hex, package, "INTERFACE_INDEX", lg2::hex, ifindex);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530446 if (package == DEFAULT_VALUE)
447 {
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500448 return internal::applyCmd(
449 ifindex, internal::Command(ncsi_nl_commands::NCSI_CMD_PKG_INFO),
450 package, DEFAULT_VALUE, NLM_F_DUMP, internal::infoCallBack);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530451 }
452 else
453 {
454 return internal::applyCmd(ifindex, ncsi_nl_commands::NCSI_CMD_PKG_INFO,
455 package, DEFAULT_VALUE, NONE,
456 internal::infoCallBack);
457 }
458}
459
Gunnar Mills57d9c502018-09-14 14:42:34 -0500460} // namespace ncsi
461} // namespace network
462} // namespace phosphor