blob: 63995d9b36acafc552d52afd8bd97bd90e394fa1 [file] [log] [blame]
/*
* Copyright (c) 2018 Intel Corporation.
* Copyright (c) 2018-present Facebook.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <ipmid/api.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <commandutils.hpp>
#include <iostream>
#include <phosphor-logging/log.hpp>
#include <sdbusplus/message/types.hpp>
#include <appcommands.hpp>
namespace ipmi
{
static void registerAPPFunctions() __attribute__((constructor));
static constexpr size_t GUID_SIZE = 16;
// TODO Make offset and location runtime configurable to ensure we
// can make each define their own locations.
static constexpr off_t OFFSET_SYS_GUID = 0x17F0;
static constexpr off_t OFFSET_DEV_GUID = 0x1800;
static constexpr const char *FRU_EEPROM = "/sys/bus/i2c/devices/6-0054/eeprom";
static uint8_t globEna = 0x09;
void printGUID(uint8_t *guid, off_t offset)
{
std::cout << "Read GUID from offset : " << offset << " :\n";
for (int i = 0; i < GUID_SIZE; i++)
{
int data = guid[i];
std::cout << std::hex << data << " ";
}
std::cout << std::endl;
}
int getGUID(off_t offset, uint8_t *guid)
{
int fd = -1;
ssize_t bytes_rd;
int ret = 0;
errno = 0;
// Check if file is present
if (access(FRU_EEPROM, F_OK) == -1)
{
std::cerr << "Unable to access: " << FRU_EEPROM << std::endl;
return errno;
}
// Open the file
fd = open(FRU_EEPROM, O_RDONLY);
if (fd == -1)
{
std::cerr << "Unable to open: " << FRU_EEPROM << std::endl;
return errno;
}
// seek to the offset
lseek(fd, offset, SEEK_SET);
// Read bytes from location
bytes_rd = read(fd, guid, GUID_SIZE);
if (bytes_rd != GUID_SIZE)
{
phosphor::logging::log<phosphor::logging::level::ERR>(
"GUID read data from EEPROM failed");
ret = errno;
}
else
{
printGUID(guid, offset);
}
close(fd);
return ret;
}
int getSystemGUID(uint8_t *guid)
{
return getGUID(OFFSET_SYS_GUID, guid);
}
int getDeviceGUID(uint8_t *guid)
{
return getGUID(OFFSET_DEV_GUID, guid);
}
//----------------------------------------------------------------------
// Get Device GUID (CMD_APP_GET_DEV_GUID)
//----------------------------------------------------------------------
ipmi_ret_t ipmiAppGetDevGUID(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request, ipmi_response_t response,
ipmi_data_len_t data_len, ipmi_context_t context)
{
uint8_t *res = reinterpret_cast<uint8_t *>(response);
if (getDeviceGUID(res))
{
return IPMI_CC_UNSPECIFIED_ERROR;
}
*data_len = GUID_SIZE;
return IPMI_CC_OK;
}
//----------------------------------------------------------------------
// Set Global Enables (CMD_APP_SET_GLOBAL_ENABLES)
//----------------------------------------------------------------------
ipmi_ret_t ipmiAppSetGlobalEnables(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request,
ipmi_response_t response,
ipmi_data_len_t data_len,
ipmi_context_t context)
{
uint8_t *req = reinterpret_cast<uint8_t *>(request);
globEna = *req;
*data_len = 0;
return IPMI_CC_OK;
}
//----------------------------------------------------------------------
// Get Global Enables (CMD_APP_GET_GLOBAL_ENABLES)
//----------------------------------------------------------------------
ipmi_ret_t ipmiAppGetGlobalEnables(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request,
ipmi_response_t response,
ipmi_data_len_t data_len,
ipmi_context_t context)
{
uint8_t *res = reinterpret_cast<uint8_t *>(response);
*data_len = 1;
*res++ = globEna;
return IPMI_CC_OK;
}
//----------------------------------------------------------------------
// Get System GUID (CMD_APP_GET_SYS_GUID)
//----------------------------------------------------------------------
ipmi_ret_t ipmiAppGetSysGUID(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request, ipmi_response_t response,
ipmi_data_len_t data_len, ipmi_context_t context)
{
uint8_t *res = reinterpret_cast<uint8_t *>(response);
if (getSystemGUID(res))
{
return IPMI_CC_UNSPECIFIED_ERROR;
}
*data_len = GUID_SIZE;
return IPMI_CC_OK;
}
void registerAPPFunctions()
{
ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_DEV_GUID, NULL,
ipmiAppGetDevGUID,
PRIVILEGE_USER); // Get Device GUID
ipmiPrintAndRegister(NETFUN_APP, CMD_APP_SET_GLOBAL_ENABLES, NULL,
ipmiAppSetGlobalEnables,
PRIVILEGE_USER); // Get Global Enables
ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_GLOBAL_ENABLES, NULL,
ipmiAppGetGlobalEnables,
PRIVILEGE_USER); // Get Global Enables
ipmiPrintAndRegister(NETFUN_APP, CMD_APP_GET_SYS_GUID, NULL,
ipmiAppGetSysGUID,
PRIVILEGE_USER); // Get System GUID
return;
}
} // namespace ipmi