blob: 9880d72add9f7afafd8dc54093c188b9b5733b61 [file] [log] [blame]
William A. Kennington III194375f2018-12-14 02:14:33 -08001#include <ipmid/api.h>
Peter Hanson4a589852017-06-07 17:40:45 -07002
Jayanth Othayotha8205ff2025-03-07 06:57:54 -06003#include <include/ipmid/api-types.hpp>
William A. Kennington III194375f2018-12-14 02:14:33 -08004#include <ipmid/oemrouter.hpp>
Patrick Venture0b02be92018-08-31 11:55:55 -07005
Patrick Williamsfbc6c9d2023-05-10 07:50:16 -05006#include <cstring>
Patrick Venture0b02be92018-08-31 11:55:55 -07007
Peter Hanson4a589852017-06-07 17:40:45 -07008#include <gtest/gtest.h>
9
10// Watch for correct singleton behavior.
11static oem::Router* singletonUnderTest;
12
13static ipmid_callback_t wildHandler;
14
15static ipmi_netfn_t lastNetFunction;
16
17// Fake ipmi_register_callback() for this test.
18void ipmi_register_callback(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
19 ipmi_context_t context, ipmid_callback_t cb,
20 ipmi_cmd_privilege_t priv)
21{
George Liuae30d812025-04-03 09:56:47 +080022 EXPECT_EQ(ipmi::netFnOem, netfn);
Jayanth Othayotha8205ff2025-03-07 06:57:54 -060023 EXPECT_EQ(ipmi::cmdWildcard, cmd);
Peter Hanson4a589852017-06-07 17:40:45 -070024 EXPECT_EQ(reinterpret_cast<void*>(singletonUnderTest), context);
25 EXPECT_EQ(PRIVILEGE_OEM, priv);
26 lastNetFunction = netfn;
27 wildHandler = cb;
28}
29
30namespace oem
31{
32
33namespace
34{
35void MakeRouter()
36{
37 if (!singletonUnderTest)
38 {
39 singletonUnderTest = mutableRouter();
40 }
41 ASSERT_EQ(singletonUnderTest, mutableRouter());
42}
43
44void ActivateRouter()
45{
46 MakeRouter();
47 singletonUnderTest->activate();
George Liuae30d812025-04-03 09:56:47 +080048 ASSERT_EQ(ipmi::netFnOem, lastNetFunction);
Peter Hanson4a589852017-06-07 17:40:45 -070049}
50
51void RegisterWithRouter(Number oen, ipmi_cmd_t cmd, Handler cb)
52{
53 ActivateRouter();
54 singletonUnderTest->registerHandler(oen, cmd, cb);
55}
56
Patrick Venture0b02be92018-08-31 11:55:55 -070057uint8_t msgPlain[] = {0x56, 0x34, 0x12};
58uint8_t replyPlain[] = {0x56, 0x34, 0x12, 0x31, 0x41};
59uint8_t msgPlus2[] = {0x67, 0x45, 0x23, 0x10, 0x20};
60uint8_t msgBadOen[] = {0x57, 0x34, 0x12};
Peter Hanson4a589852017-06-07 17:40:45 -070061
Patrick Venture0b02be92018-08-31 11:55:55 -070062void RegisterTwoWays(ipmi_cmd_t* nextCmd)
Peter Hanson4a589852017-06-07 17:40:45 -070063{
Jayanth Othayoth9db18cd2025-03-07 07:25:43 -060064 Handler f = [](ipmi_cmd_t cmd, [[maybe_unused]] const uint8_t* reqBuf,
65 uint8_t* replyBuf, size_t* dataLen) {
Peter Hanson4a589852017-06-07 17:40:45 -070066 // Check inputs
67 EXPECT_EQ(0x78, cmd);
Patrick Venture0b02be92018-08-31 11:55:55 -070068 EXPECT_EQ(0, *dataLen); // Excludes OEN
Peter Hanson4a589852017-06-07 17:40:45 -070069
70 // Generate reply.
71 *dataLen = 2;
72 std::memcpy(replyBuf, replyPlain + 3, *dataLen);
73 return 0;
74 };
75 RegisterWithRouter(0x123456, 0x78, f);
76
Jayanth Othayotha8205ff2025-03-07 06:57:54 -060077 *nextCmd = ipmi::cmdWildcard;
Peter Hanson4a589852017-06-07 17:40:45 -070078 Handler g = [nextCmd](ipmi_cmd_t cmd, const uint8_t* reqBuf,
Jayanth Othayoth9db18cd2025-03-07 07:25:43 -060079 [[maybe_unused]] uint8_t* replyBuf, size_t* dataLen) {
Peter Hanson4a589852017-06-07 17:40:45 -070080 // Check inputs
81 EXPECT_EQ(*nextCmd, cmd);
Patrick Venture0b02be92018-08-31 11:55:55 -070082 EXPECT_EQ(2, *dataLen); // Excludes OEN
Peter Hanson4a589852017-06-07 17:40:45 -070083 if (2 != *dataLen)
84 {
85 return 0xE0;
86 }
87 EXPECT_EQ(msgPlus2[3], reqBuf[0]);
88 EXPECT_EQ(msgPlus2[4], reqBuf[1]);
89
90 // Generate reply.
91 *dataLen = 0;
92 return 0;
93 };
Jayanth Othayotha8205ff2025-03-07 06:57:54 -060094 RegisterWithRouter(0x234567, ipmi::cmdWildcard, g);
Peter Hanson4a589852017-06-07 17:40:45 -070095}
Patrick Venture0b02be92018-08-31 11:55:55 -070096} // namespace
Peter Hanson4a589852017-06-07 17:40:45 -070097
Patrick Venture0b02be92018-08-31 11:55:55 -070098TEST(OemRouterTest, MakeRouterProducesConsistentSingleton)
99{
Peter Hanson4a589852017-06-07 17:40:45 -0700100 MakeRouter();
101}
102
Patrick Venture0b02be92018-08-31 11:55:55 -0700103TEST(OemRouterTest, ActivateRouterSetsLastNetToOEMGROUP)
104{
Peter Hanson4a589852017-06-07 17:40:45 -0700105 lastNetFunction = 0;
106 ActivateRouter();
107}
108
Patrick Venture0b02be92018-08-31 11:55:55 -0700109TEST(OemRouterTest, VerifiesSpecificCommandMatches)
110{
Peter Hanson4a589852017-06-07 17:40:45 -0700111 ipmi_cmd_t cmd;
112 uint8_t reply[256];
113 size_t dataLen;
114
115 RegisterTwoWays(&cmd);
116
117 dataLen = 3;
George Liuae30d812025-04-03 09:56:47 +0800118 EXPECT_EQ(0, wildHandler(ipmi::netFnOem, 0x78, msgPlain, reply, &dataLen,
Patrick Venture0b02be92018-08-31 11:55:55 -0700119 nullptr));
Peter Hanson4a589852017-06-07 17:40:45 -0700120 EXPECT_EQ(5, dataLen);
121 EXPECT_EQ(replyPlain[0], reply[0]);
122 EXPECT_EQ(replyPlain[1], reply[1]);
123 EXPECT_EQ(replyPlain[2], reply[2]);
124 EXPECT_EQ(replyPlain[3], reply[3]);
125 EXPECT_EQ(replyPlain[4], reply[4]);
126}
127
Patrick Venture0b02be92018-08-31 11:55:55 -0700128TEST(OemRouterTest, WildCardMatchesTwoRandomCodes)
129{
Peter Hanson4a589852017-06-07 17:40:45 -0700130 ipmi_cmd_t cmd;
131 uint8_t reply[256];
132 size_t dataLen;
133
134 RegisterTwoWays(&cmd);
135
136 // Check two random command codes.
137 dataLen = 5;
138 cmd = 0x89;
George Liuae30d812025-04-03 09:56:47 +0800139 EXPECT_EQ(0, wildHandler(ipmi::netFnOem, cmd, msgPlus2, reply, &dataLen,
Patrick Venture0b02be92018-08-31 11:55:55 -0700140 nullptr));
Peter Hanson4a589852017-06-07 17:40:45 -0700141 EXPECT_EQ(3, dataLen);
142
143 dataLen = 5;
144 cmd = 0x67;
George Liuae30d812025-04-03 09:56:47 +0800145 EXPECT_EQ(0, wildHandler(ipmi::netFnOem, cmd, msgPlus2, reply, &dataLen,
Patrick Venture0b02be92018-08-31 11:55:55 -0700146 nullptr));
Peter Hanson4a589852017-06-07 17:40:45 -0700147 EXPECT_EQ(3, dataLen);
148}
149
Patrick Venture0b02be92018-08-31 11:55:55 -0700150TEST(OemRouterTest, CommandsAreRejectedIfInvalid)
151{
Peter Hanson4a589852017-06-07 17:40:45 -0700152 ipmi_cmd_t cmd;
153 uint8_t reply[256];
154 size_t dataLen;
155
156 RegisterTwoWays(&cmd);
157
158 // Message too short to include whole OEN?
159 dataLen = 2;
160 EXPECT_EQ(IPMI_CC_REQ_DATA_LEN_INVALID,
George Liuae30d812025-04-03 09:56:47 +0800161 wildHandler(ipmi::netFnOem, 0x78, msgPlain, reply, &dataLen,
Patrick Venture0b02be92018-08-31 11:55:55 -0700162 nullptr));
Peter Hanson4a589852017-06-07 17:40:45 -0700163
164 // Wrong specific command?
165 dataLen = 3;
George Liuae30d812025-04-03 09:56:47 +0800166 EXPECT_EQ(IPMI_CC_INVALID, wildHandler(ipmi::netFnOem, 0x89, msgPlain,
Patrick Venture0b02be92018-08-31 11:55:55 -0700167 reply, &dataLen, nullptr));
Peter Hanson4a589852017-06-07 17:40:45 -0700168
169 // Wrong OEN?
170 dataLen = 3;
George Liuae30d812025-04-03 09:56:47 +0800171 EXPECT_EQ(IPMI_CC_INVALID, wildHandler(ipmi::netFnOem, 0x78, msgBadOen,
Patrick Venture0b02be92018-08-31 11:55:55 -0700172 reply, &dataLen, nullptr));
Peter Hanson4a589852017-06-07 17:40:45 -0700173}
174
Patrick Venture0b02be92018-08-31 11:55:55 -0700175} // namespace oem