blob: 000c11e076061f157b35257df6b7b5e474bfeb7e [file] [log] [blame]
Patrick Venture5794fcf2017-10-26 11:11:14 -07001#include "channel.hpp"
2#include "types.hpp"
3#include "transporthandler.hpp"
4#include "utils.hpp"
Patrick Venturec7c1c3c2017-11-15 14:29:18 -08005#include "net.hpp"
Patrick Venture5794fcf2017-10-26 11:11:14 -07006
7#include <string>
8#include <arpa/inet.h>
9
10#include <phosphor-logging/log.hpp>
11#include <phosphor-logging/elog-errors.hpp>
12#include "xyz/openbmc_project/Common/error.hpp"
13
Patrick Venture5794fcf2017-10-26 11:11:14 -070014
15using namespace phosphor::logging;
16using namespace sdbusplus::xyz::openbmc_project::Common::Error;
17
18/** @struct GetChannelAccessRequest
19 *
20 * IPMI payload for Get Channel access command request.
21 */
22struct GetChannelAccessRequest
23{
24 uint8_t channelNumber; //!< Channel number.
25 uint8_t volatileSetting; //!< Get non-volatile or the volatile setting.
26} __attribute__((packed));
27
28/** @struct GetChannelAccessResponse
29 *
30 * IPMI payload for Get Channel access command response.
31 */
32struct GetChannelAccessResponse
33{
34 uint8_t settings; //!< Channel settings.
35 uint8_t privilegeLimit; //!< Channel privilege level limit.
36} __attribute__((packed));
37
Patrick Venture5794fcf2017-10-26 11:11:14 -070038
39ipmi_ret_t ipmi_get_channel_access(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
40 ipmi_request_t request, ipmi_response_t response,
41 ipmi_data_len_t data_len, ipmi_context_t context)
42{
43 auto requestData = reinterpret_cast<const GetChannelAccessRequest*>
44 (request);
45 std::vector<uint8_t> outPayload(sizeof(GetChannelAccessResponse));
46 auto responseData = reinterpret_cast<GetChannelAccessResponse*>
47 (outPayload.data());
48
Patrick Venture5794fcf2017-10-26 11:11:14 -070049 /*
50 * The value Eh is used as a way to identify the current channel that
51 * the command is being received from.
52 */
53 constexpr auto channelE = 0x0E;
Patrick Venturec7c1c3c2017-11-15 14:29:18 -080054 int channel = requestData->channelNumber;
55 auto ethdevice = ipmi::network::ChanneltoEthernet(channel);
Patrick Venture5794fcf2017-10-26 11:11:14 -070056
Patrick Venturec7c1c3c2017-11-15 14:29:18 -080057 if (channel != channelE && ethdevice.empty())
Patrick Venture5794fcf2017-10-26 11:11:14 -070058 {
59 *data_len = 0;
60 return IPMI_CC_INVALID_FIELD_REQUEST;
61 }
62
63 /*
64 * [7:6] - reserved
65 * [5] - 1b = Alerting disabled
66 * [4] - 1b = per message authentication disabled
67 * [3] - 0b = User level authentication enabled
68 * [2:0] - 2h = always available
69 */
70 constexpr auto channelSetting = 0x32;
71
72 responseData->settings = channelSetting;
73 //Defaulting the channel privilege to administrator level.
74 responseData->privilegeLimit = PRIVILEGE_ADMIN;
75
76 *data_len = outPayload.size();
77 memcpy(response, outPayload.data(), *data_len);
78
79 return IPMI_CC_OK;
80}
81
82// ATTENTION: This ipmi function is very hardcoded on purpose
83// OpenBMC does not fully support IPMI. This command is useful
84// to have around because it enables testing of interfaces with
85// the IPMI tool.
86#define GET_CHANNEL_INFO_CHANNEL_OFFSET 0
87// IPMI Table 6-2
88#define IPMI_CHANNEL_TYPE_IPMB 1
89// IPMI Table 6-3
90#define IPMI_CHANNEL_MEDIUM_TYPE_OTHER 6
91
92ipmi_ret_t ipmi_app_channel_info(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
93 ipmi_request_t request, ipmi_response_t response,
94 ipmi_data_len_t data_len, ipmi_context_t context)
95{
96 ipmi_ret_t rc = IPMI_CC_OK;
97 uint8_t resp[] = {
98 1,
99 IPMI_CHANNEL_MEDIUM_TYPE_OTHER,
100 IPMI_CHANNEL_TYPE_IPMB,
101 1,0x41,0xA7,0x00,0,0};
102 uint8_t *p = (uint8_t*) request;
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800103 int channel = (*p) & CHANNEL_MASK;
104 std::string ethdevice = ipmi::network::ChanneltoEthernet(channel);
Patrick Venture5794fcf2017-10-26 11:11:14 -0700105
106 printf("IPMI APP GET CHANNEL INFO\n");
107
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800108 // The supported channels numbers are those which are configured.
Patrick Venture5794fcf2017-10-26 11:11:14 -0700109 // Channel Number E is used as way to identify the current channel
110 // that the command is being is received from.
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800111 if (channel != 0xe && ethdevice.empty()) {
Patrick Venture5794fcf2017-10-26 11:11:14 -0700112 rc = IPMI_CC_PARM_OUT_OF_RANGE;
113 *data_len = 0;
Patrick Venturec7c1c3c2017-11-15 14:29:18 -0800114 } else {
115 *data_len = sizeof(resp);
116 memcpy(response, resp, *data_len);
Patrick Venture5794fcf2017-10-26 11:11:14 -0700117 }
118
119 return rc;
120}