blob: 826d7de8aed74eb3fd08468bf8ecb0456745246e [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>()) :
Johnathan Mantey1ebea282024-02-15 10:26:06 -080072 ncsi_cmd(ncsiCmd),
73 operation(operation), payload(p)
Patrick Williams89d734b2023-05-10 07:50:25 -050074 {}
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050075
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050076 int ncsi_cmd;
Johnathan Mantey1ebea282024-02-15 10:26:06 -080077 int operation;
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050078 std::span<const unsigned char> payload;
79};
80
Ratan Guptabbe45792018-03-23 00:22:55 +053081using nlMsgPtr = std::unique_ptr<nl_msg, decltype(&::nlmsg_free)>;
82using nlSocketPtr = std::unique_ptr<nl_sock, decltype(&::nl_socket_free)>;
83
Eddie Jamesfa1f5c02020-09-17 15:12:46 -050084CallBack infoCallBack = [](struct nl_msg* msg, void* arg) {
Ratan Guptaaac603e2018-03-23 00:25:54 +053085 using namespace phosphor::network::ncsi;
86 auto nlh = nlmsg_hdr(msg);
87
Gunnar Mills57d9c502018-09-14 14:42:34 -050088 struct nlattr* tb[NCSI_ATTR_MAX + 1] = {nullptr};
89 struct nla_policy ncsiPolicy[NCSI_ATTR_MAX + 1] = {
William A. Kennington III05368f12021-05-13 18:40:47 -070090 {NLA_UNSPEC, 0, 0}, {NLA_U32, 0, 0}, {NLA_NESTED, 0, 0},
91 {NLA_U32, 0, 0}, {NLA_U32, 0, 0},
Ratan Guptaaac603e2018-03-23 00:25:54 +053092 };
93
Gunnar Mills57d9c502018-09-14 14:42:34 -050094 struct nlattr* packagetb[NCSI_PKG_ATTR_MAX + 1] = {nullptr};
95 struct nla_policy packagePolicy[NCSI_PKG_ATTR_MAX + 1] = {
William A. Kennington III05368f12021-05-13 18:40:47 -070096 {NLA_UNSPEC, 0, 0}, {NLA_NESTED, 0, 0}, {NLA_U32, 0, 0},
97 {NLA_FLAG, 0, 0}, {NLA_NESTED, 0, 0},
Ratan Guptaaac603e2018-03-23 00:25:54 +053098 };
99
Gunnar Mills57d9c502018-09-14 14:42:34 -0500100 struct nlattr* channeltb[NCSI_CHANNEL_ATTR_MAX + 1] = {nullptr};
101 struct nla_policy channelPolicy[NCSI_CHANNEL_ATTR_MAX + 1] = {
William A. Kennington III05368f12021-05-13 18:40:47 -0700102 {NLA_UNSPEC, 0, 0}, {NLA_NESTED, 0, 0}, {NLA_U32, 0, 0},
103 {NLA_FLAG, 0, 0}, {NLA_NESTED, 0, 0}, {NLA_UNSPEC, 0, 0},
Ratan Guptaaac603e2018-03-23 00:25:54 +0530104 };
105
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500106 *(int*)arg = 0;
107
Ratan Guptaaac603e2018-03-23 00:25:54 +0530108 auto ret = genlmsg_parse(nlh, 0, tb, NCSI_ATTR_MAX, ncsiPolicy);
109 if (!tb[NCSI_ATTR_PACKAGE_LIST])
110 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700111 lg2::error("No Packages");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530112 return -1;
113 }
114
115 auto attrTgt = static_cast<nlattr*>(nla_data(tb[NCSI_ATTR_PACKAGE_LIST]));
116 if (!attrTgt)
117 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700118 lg2::error("Package list attribute is null");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530119 return -1;
120 }
121
122 auto rem = nla_len(tb[NCSI_ATTR_PACKAGE_LIST]);
123 nla_for_each_nested(attrTgt, tb[NCSI_ATTR_PACKAGE_LIST], rem)
124 {
125 ret = nla_parse_nested(packagetb, NCSI_PKG_ATTR_MAX, attrTgt,
126 packagePolicy);
127 if (ret < 0)
128 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700129 lg2::error("Failed to parse package nested");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530130 return -1;
131 }
132
133 if (packagetb[NCSI_PKG_ATTR_ID])
134 {
135 auto attrID = nla_get_u32(packagetb[NCSI_PKG_ATTR_ID]);
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700136 lg2::debug("Package has id : {ATTR_ID}", "ATTR_ID", lg2::hex,
137 attrID);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530138 }
139 else
140 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700141 lg2::debug("Package with no id");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530142 }
143
144 if (packagetb[NCSI_PKG_ATTR_FORCED])
145 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700146 lg2::debug("This package is forced");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530147 }
148
149 auto channelListTarget = static_cast<nlattr*>(
Gunnar Mills57d9c502018-09-14 14:42:34 -0500150 nla_data(packagetb[NCSI_PKG_ATTR_CHANNEL_LIST]));
Ratan Guptaaac603e2018-03-23 00:25:54 +0530151
152 auto channelrem = nla_len(packagetb[NCSI_PKG_ATTR_CHANNEL_LIST]);
153 nla_for_each_nested(channelListTarget,
154 packagetb[NCSI_PKG_ATTR_CHANNEL_LIST], channelrem)
155 {
156 ret = nla_parse_nested(channeltb, NCSI_CHANNEL_ATTR_MAX,
157 channelListTarget, channelPolicy);
158 if (ret < 0)
159 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700160 lg2::error("Failed to parse channel nested");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530161 return -1;
162 }
163
164 if (channeltb[NCSI_CHANNEL_ATTR_ID])
165 {
166 auto channel = nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_ID]);
167 if (channeltb[NCSI_CHANNEL_ATTR_ACTIVE])
168 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700169 lg2::debug("Channel Active : {CHANNEL}", "CHANNEL",
170 lg2::hex, channel);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530171 }
172 else
173 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700174 lg2::debug("Channel Not Active : {CHANNEL}", "CHANNEL",
175 lg2::hex, channel);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530176 }
177
178 if (channeltb[NCSI_CHANNEL_ATTR_FORCED])
179 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700180 lg2::debug("Channel is forced");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530181 }
Ratan Guptaaac603e2018-03-23 00:25:54 +0530182 }
183 else
184 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700185 lg2::debug("Channel with no ID");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530186 }
Ratan Guptaed5d7ff2018-03-23 00:27:52 +0530187
Ratan Guptaaac603e2018-03-23 00:25:54 +0530188 if (channeltb[NCSI_CHANNEL_ATTR_VERSION_MAJOR])
189 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500190 auto major =
191 nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_VERSION_MAJOR]);
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700192 lg2::debug("Channel Major Version : {CHANNEL_MAJOR_VERSION}",
193 "CHANNEL_MAJOR_VERSION", lg2::hex, major);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530194 }
195 if (channeltb[NCSI_CHANNEL_ATTR_VERSION_MINOR])
196 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500197 auto minor =
198 nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_VERSION_MINOR]);
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700199 lg2::debug("Channel Minor Version : {CHANNEL_MINOR_VERSION}",
200 "CHANNEL_MINOR_VERSION", lg2::hex, minor);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530201 }
202 if (channeltb[NCSI_CHANNEL_ATTR_VERSION_STR])
203 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500204 auto str =
205 nla_get_string(channeltb[NCSI_CHANNEL_ATTR_VERSION_STR]);
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700206 lg2::debug("Channel Version Str : {CHANNEL_VERSION_STR}",
207 "CHANNEL_VERSION_STR", str);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530208 }
209 if (channeltb[NCSI_CHANNEL_ATTR_LINK_STATE])
210 {
Gunnar Mills57d9c502018-09-14 14:42:34 -0500211 auto link =
212 nla_get_u32(channeltb[NCSI_CHANNEL_ATTR_LINK_STATE]);
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700213 lg2::debug("Channel Link State : {LINK_STATE}", "LINK_STATE",
214 lg2::hex, link);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530215 }
216 if (channeltb[NCSI_CHANNEL_ATTR_VLAN_LIST])
217 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700218 lg2::debug("Active Vlan ids");
Ratan Guptaaac603e2018-03-23 00:25:54 +0530219 auto vids = channeltb[NCSI_CHANNEL_ATTR_VLAN_LIST];
220 auto vid = static_cast<nlattr*>(nla_data(vids));
221 auto len = nla_len(vids);
222 while (nla_ok(vid, len))
223 {
224 auto id = nla_get_u16(vid);
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700225 lg2::debug("VID : {VLAN_ID}", "VLAN_ID", id);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530226 vid = nla_next(vid, &len);
227 }
228 }
Ratan Guptaaac603e2018-03-23 00:25:54 +0530229 }
Ratan Guptaaac603e2018-03-23 00:25:54 +0530230 }
231 return (int)NL_SKIP;
232};
233
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500234CallBack sendCallBack = [](struct nl_msg* msg, void* arg) {
235 using namespace phosphor::network::ncsi;
236 auto nlh = nlmsg_hdr(msg);
237 struct nlattr* tb[NCSI_ATTR_MAX + 1] = {nullptr};
238 static struct nla_policy ncsiPolicy[NCSI_ATTR_MAX + 1] = {
239 {NLA_UNSPEC, 0, 0}, {NLA_U32, 0, 0}, {NLA_NESTED, 0, 0},
240 {NLA_U32, 0, 0}, {NLA_U32, 0, 0}, {NLA_BINARY, 0, 0},
241 {NLA_FLAG, 0, 0}, {NLA_U32, 0, 0}, {NLA_U32, 0, 0},
242 };
243
244 *(int*)arg = 0;
245
246 auto ret = genlmsg_parse(nlh, 0, tb, NCSI_ATTR_MAX, ncsiPolicy);
247 if (ret)
248 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700249 lg2::error("Failed to parse package");
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500250 return ret;
251 }
252
Jian Zhang442d9e52022-10-20 22:11:14 +0800253 if (tb[NCSI_ATTR_DATA] == nullptr)
254 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700255 lg2::error("Response: No data");
Jian Zhang442d9e52022-10-20 22:11:14 +0800256 return -1;
257 }
258
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500259 auto data_len = nla_len(tb[NCSI_ATTR_DATA]) - sizeof(NCSIPacketHeader);
Patrick Williams89d734b2023-05-10 07:50:25 -0500260 unsigned char* data = (unsigned char*)nla_data(tb[NCSI_ATTR_DATA]) +
261 sizeof(NCSIPacketHeader);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500262
263 // Dump the response to stdout. Enhancement: option to save response data
William A. Kennington IIIcbe50732023-07-25 13:52:18 -0700264 auto str = toHexStr(std::span<const unsigned char>(data, data_len));
265 lg2::debug("Response {DATA_LEN} bytes: {DATA}", "DATA_LEN", data_len,
266 "DATA", str);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500267
268 return 0;
269};
270
271int applyCmd(int ifindex, const Command& cmd, int package = DEFAULT_VALUE,
Ratan Guptaaac603e2018-03-23 00:25:54 +0530272 int channel = DEFAULT_VALUE, int flags = NONE,
273 CallBack function = nullptr)
Ratan Guptabbe45792018-03-23 00:22:55 +0530274{
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500275 int cb_ret = 0;
Gunnar Mills57d9c502018-09-14 14:42:34 -0500276 nlSocketPtr socket(nl_socket_alloc(), &::nl_socket_free);
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700277 if (socket == nullptr)
278 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700279 lg2::error("Unable to allocate memory for the socket");
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700280 return -ENOMEM;
281 }
282
Ratan Guptabbe45792018-03-23 00:22:55 +0530283 auto ret = genl_connect(socket.get());
284 if (ret < 0)
285 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700286 lg2::error("Failed to open the socket , RC : {RC}", "RC", ret);
Ratan Guptabbe45792018-03-23 00:22:55 +0530287 return ret;
288 }
289
290 auto driverID = genl_ctrl_resolve(socket.get(), "NCSI");
291 if (driverID < 0)
292 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700293 lg2::error("Failed to resolve, RC : {RC}", "RC", ret);
Ratan Guptabbe45792018-03-23 00:22:55 +0530294 return driverID;
295 }
296
297 nlMsgPtr msg(nlmsg_alloc(), &::nlmsg_free);
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700298 if (msg == nullptr)
299 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700300 lg2::error("Unable to allocate memory for the message");
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700301 return -ENOMEM;
302 }
Ratan Guptabbe45792018-03-23 00:22:55 +0530303
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800304 auto msgHdr = genlmsg_put(msg.get(), NL_AUTO_PORT, NL_AUTO_SEQ, driverID, 0,
305 flags, cmd.ncsi_cmd, 0);
Ratan Guptabbe45792018-03-23 00:22:55 +0530306 if (!msgHdr)
307 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700308 lg2::error("Unable to add the netlink headers , COMMAND : {COMMAND}",
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800309 "COMMAND", cmd.ncsi_cmd);
Johnathan Manteyd49c5c62021-06-23 09:14:42 -0700310 return -ENOMEM;
Ratan Guptabbe45792018-03-23 00:22:55 +0530311 }
312
313 if (package != DEFAULT_VALUE)
314 {
315 ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_PACKAGE_ID,
316 package);
317 if (ret < 0)
318 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700319 lg2::error("Failed to set the attribute , RC : {RC} PACKAGE "
320 "{PACKAGE}",
321 "RC", ret, "PACKAGE", lg2::hex, package);
Ratan Guptabbe45792018-03-23 00:22:55 +0530322 return ret;
323 }
324 }
325
326 if (channel != DEFAULT_VALUE)
327 {
328 ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_CHANNEL_ID,
329 channel);
330 if (ret < 0)
331 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700332 lg2::error("Failed to set the attribute , RC : {RC} CHANNEL : "
333 "{CHANNEL}",
334 "RC", ret, "CHANNEL", lg2::hex, channel);
Ratan Guptabbe45792018-03-23 00:22:55 +0530335 return ret;
336 }
337 }
338
339 ret = nla_put_u32(msg.get(), ncsi_nl_attrs::NCSI_ATTR_IFINDEX, ifindex);
340 if (ret < 0)
341 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700342 lg2::error("Failed to set the attribute , RC : {RC} INTERFACE : "
343 "{INTERFACE}",
344 "RC", ret, "INTERFACE", lg2::hex, ifindex);
Ratan Guptabbe45792018-03-23 00:22:55 +0530345 return ret;
346 }
347
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800348 if (cmd.operation != DEFAULT_VALUE)
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500349 {
350 std::vector<unsigned char> pl(sizeof(NCSIPacketHeader) +
351 cmd.payload.size());
352 NCSIPacketHeader* hdr = (NCSIPacketHeader*)pl.data();
353
354 std::copy(cmd.payload.begin(), cmd.payload.end(),
355 pl.begin() + sizeof(NCSIPacketHeader));
356
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800357 hdr->type = cmd.operation;
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500358 hdr->length = htons(cmd.payload.size());
359
360 ret = nla_put(msg.get(), ncsi_nl_attrs::NCSI_ATTR_DATA, pl.size(),
361 pl.data());
362 if (ret < 0)
363 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700364 lg2::error("Failed to set the data attribute, RC : {RC}", "RC",
365 ret);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500366 return ret;
367 }
368
369 nl_socket_disable_seq_check(socket.get());
370 }
371
Ratan Guptaaac603e2018-03-23 00:25:54 +0530372 if (function)
373 {
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500374 cb_ret = 1;
375
Ratan Guptaaac603e2018-03-23 00:25:54 +0530376 // Add a callback function to the socket
Gunnar Mills57d9c502018-09-14 14:42:34 -0500377 nl_socket_modify_cb(socket.get(), NL_CB_VALID, NL_CB_CUSTOM, function,
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500378 &cb_ret);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530379 }
Ratan Guptabbe45792018-03-23 00:22:55 +0530380
381 ret = nl_send_auto(socket.get(), msg.get());
382 if (ret < 0)
383 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700384 lg2::error("Failed to send the message , RC : {RC}", "RC", ret);
Ratan Guptabbe45792018-03-23 00:22:55 +0530385 return ret;
386 }
387
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500388 do
Ratan Guptabbe45792018-03-23 00:22:55 +0530389 {
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500390 ret = nl_recvmsgs_default(socket.get());
391 if (ret < 0)
392 {
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700393 lg2::error("Failed to receive the message , RC : {RC}", "RC", ret);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500394 break;
395 }
396 } while (cb_ret);
397
Ratan Guptabbe45792018-03-23 00:22:55 +0530398 return ret;
399}
400
Gunnar Mills57d9c502018-09-14 14:42:34 -0500401} // namespace internal
Ratan Guptabbe45792018-03-23 00:22:55 +0530402
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800403int sendOemCommand(int ifindex, int package, int channel, int operation,
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500404 std::span<const unsigned char> payload)
405{
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700406 lg2::debug("Send OEM Command, CHANNEL : {CHANNEL} , PACKAGE : {PACKAGE}, "
407 "INTERFACE_INDEX: {INTERFACE_INDEX}",
408 "CHANNEL", lg2::hex, channel, "PACKAGE", lg2::hex, package,
409 "INTERFACE_INDEX", lg2::hex, ifindex);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500410 if (!payload.empty())
411 {
William A. Kennington IIIcbe50732023-07-25 13:52:18 -0700412 lg2::debug("Payload: {PAYLOAD}", "PAYLOAD", toHexStr(payload));
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500413 }
414
415 return internal::applyCmd(
416 ifindex,
Johnathan Mantey1ebea282024-02-15 10:26:06 -0800417 internal::Command(ncsi_nl_commands::NCSI_CMD_SEND_CMD, operation,
418 payload),
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500419 package, channel, NONE, internal::sendCallBack);
420}
421
Ratan Guptabbe45792018-03-23 00:22:55 +0530422int setChannel(int ifindex, int package, int channel)
423{
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700424 lg2::debug(
425 "Set CHANNEL : {CHANNEL} , PACKAGE : {PACKAGE}, INTERFACE_INDEX: "
426 "{INTERFACE_INDEX}",
427 "CHANNEL", lg2::hex, channel, "PACKAGE", lg2::hex, package,
428 "INTERFACE_INDEX", lg2::hex, ifindex);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500429 return internal::applyCmd(
430 ifindex, internal::Command(ncsi_nl_commands::NCSI_CMD_SET_INTERFACE),
431 package, channel);
Ratan Guptabbe45792018-03-23 00:22:55 +0530432}
433
434int clearInterface(int ifindex)
435{
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700436 lg2::debug("ClearInterface , INTERFACE_INDEX : {INTERFACE_INDEX}",
437 "INTERFACE_INDEX", lg2::hex, ifindex);
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500438 return internal::applyCmd(
439 ifindex, internal::Command(ncsi_nl_commands::NCSI_CMD_CLEAR_INTERFACE));
Ratan Guptabbe45792018-03-23 00:22:55 +0530440}
441
Ratan Guptaaac603e2018-03-23 00:25:54 +0530442int getInfo(int ifindex, int package)
443{
Jagpal Singh Gilld423beb2023-04-18 11:28:03 -0700444 lg2::debug(
445 "Get Info , PACKAGE : {PACKAGE}, INTERFACE_INDEX: {INTERFACE_INDEX}",
446 "PACKAGE", lg2::hex, package, "INTERFACE_INDEX", lg2::hex, ifindex);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530447 if (package == DEFAULT_VALUE)
448 {
Eddie Jamesfa1f5c02020-09-17 15:12:46 -0500449 return internal::applyCmd(
450 ifindex, internal::Command(ncsi_nl_commands::NCSI_CMD_PKG_INFO),
451 package, DEFAULT_VALUE, NLM_F_DUMP, internal::infoCallBack);
Ratan Guptaaac603e2018-03-23 00:25:54 +0530452 }
453 else
454 {
455 return internal::applyCmd(ifindex, ncsi_nl_commands::NCSI_CMD_PKG_INFO,
456 package, DEFAULT_VALUE, NONE,
457 internal::infoCallBack);
458 }
459}
460
Gunnar Mills57d9c502018-09-14 14:42:34 -0500461} // namespace ncsi
462} // namespace network
463} // namespace phosphor