Add support for Entity Association Record
Adding support for Entity Association Record (SDR type - 0x08h)
This patch includes:
1) Entity Association Record yaml file example
2) Entity Assocation Record related script and mako file changes
3) Adding Entity Association Record in get_sdr IPMI command response
From the host, tested that entity association records can be fetched
Change-Id: I9cf598e5d27d2e8c6751bbaae2176e7c976974b1
Tested: Yes
Signed-off-by: Jaghathiswari Rankappagounder Natarajan <jaghu@google.com>
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index 40c0d3e..9d0364d 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -27,6 +27,7 @@
extern sd_bus* bus;
extern const ipmi::sensor::IdInfoMap sensors;
extern const FruMap frus;
+extern const ipmi::sensor::EntityInfoMap entities;
using namespace phosphor::logging;
using InternalFailure =
@@ -575,7 +576,7 @@
get_sdr_info::request::get_count(request) == false)
{
// Get Sensor Count
- resp->count = sensors.size() + frus.size();
+ resp->count = sensors.size() + frus.size() + entities.size();
}
else
{
@@ -748,13 +749,87 @@
if (++fru == frus.end())
{
+ // we have reached till end of fru, so assign the next record id to
+ // 512(Max fru ID = 511) + Entity Record ID(may start with 0).
+ auto next_record_id =
+ (entities.size()) ? entities.begin()->first + ENTITY_RECORD_ID_START
+ : END_OF_RECORD;
+ get_sdr::response::set_next_record_id(next_record_id, resp);
+ }
+ else
+ {
+ get_sdr::response::set_next_record_id(
+ (FRU_RECORD_ID_START + fru->first), resp);
+ }
+
+ // Check for invalid offset size
+ if (req->offset > sizeof(record))
+ {
+ return IPMI_CC_PARM_OUT_OF_RANGE;
+ }
+
+ dataLength = std::min(static_cast<size_t>(req->bytes_to_read),
+ sizeof(record) - req->offset);
+
+ std::memcpy(resp->record_data,
+ reinterpret_cast<uint8_t*>(&record) + req->offset, dataLength);
+
+ *data_len = dataLength;
+ *data_len += 2; // additional 2 bytes for next record ID
+
+ return IPMI_CC_OK;
+}
+
+ipmi_ret_t ipmi_entity_get_sdr(ipmi_request_t request, ipmi_response_t response,
+ ipmi_data_len_t data_len)
+{
+ auto req = reinterpret_cast<get_sdr::GetSdrReq*>(request);
+ auto resp = reinterpret_cast<get_sdr::GetSdrResp*>(response);
+ get_sdr::SensorDataEntityRecord record{};
+ auto dataLength = 0;
+
+ auto entity = entities.begin();
+ uint8_t entityRecordID;
+ auto recordID = get_sdr::request::get_record_id(req);
+
+ entityRecordID = recordID - ENTITY_RECORD_ID_START;
+ entity = entities.find(entityRecordID);
+ if (entity == entities.end())
+ {
+ return IPMI_CC_SENSOR_INVALID;
+ }
+
+ /* Header */
+ get_sdr::header::set_record_id(recordID, &(record.header));
+ record.header.sdr_version = SDR_VERSION; // Based on IPMI Spec v2.0 rev 1.1
+ record.header.record_type = get_sdr::SENSOR_DATA_ENTITY_RECORD;
+ record.header.record_length = sizeof(record.key) + sizeof(record.body);
+
+ /* Key */
+ record.key.containerEntityId = entity->second.containerEntityId;
+ record.key.containerEntityInstance = entity->second.containerEntityInstance;
+ get_sdr::key::set_flags(entity->second.isList, entity->second.isLinked,
+ &(record.key));
+ record.key.entityId1 = entity->second.containedEntities[0].first;
+ record.key.entityInstance1 = entity->second.containedEntities[0].second;
+
+ /* Body */
+ record.body.entityId2 = entity->second.containedEntities[1].first;
+ record.body.entityInstance2 = entity->second.containedEntities[1].second;
+ record.body.entityId3 = entity->second.containedEntities[2].first;
+ record.body.entityInstance3 = entity->second.containedEntities[2].second;
+ record.body.entityId4 = entity->second.containedEntities[3].first;
+ record.body.entityInstance4 = entity->second.containedEntities[3].second;
+
+ if (++entity == entities.end())
+ {
get_sdr::response::set_next_record_id(END_OF_RECORD,
resp); // last record
}
else
{
get_sdr::response::set_next_record_id(
- (FRU_RECORD_ID_START + fru->first), resp);
+ (ENTITY_RECORD_ID_START + entity->first), resp);
}
// Check for invalid offset size
@@ -793,10 +868,17 @@
// At the beginning of a scan, the host side will send us id=0.
if (recordID != 0)
{
- // recordID greater then 255,it means it is a FRU record.
- // Currently we are supporting two record types either FULL record
- // or FRU record.
- if (recordID >= FRU_RECORD_ID_START)
+ // recordID 0 to 255 means it is a FULL record.
+ // recordID 256 to 511 means it is a FRU record.
+ // recordID greater then 511 means it is a Entity Association
+ // record. Currently we are supporting three record types: FULL
+ // record, FRU record and Enttiy Association record.
+ if (recordID >= ENTITY_RECORD_ID_START)
+ {
+ return ipmi_entity_get_sdr(request, response, data_len);
+ }
+ else if (recordID >= FRU_RECORD_ID_START &&
+ recordID < ENTITY_RECORD_ID_START)
{
return ipmi_fru_get_sdr(request, response, data_len);
}