blob: 0f25794fc08a738579797548c25fffe1933de17c [file] [log] [blame]
SunnySrivastava1984a7392592020-03-09 10:19:33 -05001#include "config.h"
2
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -06003#include "editor_impl.hpp"
4
Alpana Kumari414d5ae2021-03-04 21:06:35 +00005#include "common_utility.hpp"
Sunny Srivastava6c71c9d2021-04-15 04:43:54 -05006#include "ibm_vpd_utils.hpp"
SunnySrivastava1984e12b1812020-05-26 02:23:11 -05007#include "ipz_parser.hpp"
8#include "parser_factory.hpp"
Priyanga Ramasamyc99a0b02022-06-08 14:53:39 -05009#include "vpd_exceptions.hpp"
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060010
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060011#include "vpdecc/vpdecc.h"
12
SunnySrivastava1984e12b1812020-05-26 02:23:11 -050013using namespace openpower::vpd::parser::interface;
14using namespace openpower::vpd::constants;
15using namespace openpower::vpd::parser::factory;
16using namespace openpower::vpd::ipz::parser;
17
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060018namespace openpower
19{
20namespace vpd
21{
22namespace manager
23{
24namespace editor
25{
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060026
27void EditorImpl::checkPTForRecord(Binary::const_iterator& iterator,
28 Byte ptLength)
29{
30 // auto iterator = ptRecord.cbegin();
31 auto end = std::next(iterator, ptLength + 1);
32
33 // Look at each entry in the PT keyword for the record name
34 while (iterator < end)
35 {
36 auto stop = std::next(iterator, lengths::RECORD_NAME);
37 std::string record(iterator, stop);
38
39 if (record == thisRecord.recName)
40 {
41 // Skip record name and record type
42 std::advance(iterator, lengths::RECORD_NAME + sizeof(RecordType));
43
44 // Get record offset
45 thisRecord.recOffset = readUInt16LE(iterator);
46
47 // pass the record offset length to read record length
48 std::advance(iterator, lengths::RECORD_OFFSET);
49 thisRecord.recSize = readUInt16LE(iterator);
50
51 std::advance(iterator, lengths::RECORD_LENGTH);
52 thisRecord.recECCoffset = readUInt16LE(iterator);
53
54 ECCLength len;
55 std::advance(iterator, lengths::RECORD_ECC_OFFSET);
56 len = readUInt16LE(iterator);
57 thisRecord.recECCLength = len;
58
59 // once we find the record we don't need to look further
60 return;
61 }
62 else
63 {
64 // Jump the record
65 std::advance(iterator, lengths::RECORD_NAME + sizeof(RecordType) +
66 sizeof(RecordOffset) +
67 sizeof(RecordLength) +
68 sizeof(ECCOffset) + sizeof(ECCLength));
69 }
70 }
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060071 // imples the record was not found
72 throw std::runtime_error("Record not found");
73}
74
SunnySrivastava19846d8314d2020-05-15 09:34:58 -050075void EditorImpl::updateData(const Binary& kwdData)
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060076{
77 std::size_t lengthToUpdate = kwdData.size() <= thisRecord.kwdDataLength
78 ? kwdData.size()
79 : thisRecord.kwdDataLength;
80
81 auto iteratorToNewdata = kwdData.cbegin();
82 auto end = iteratorToNewdata;
83 std::advance(end, lengthToUpdate);
84
SunnySrivastava19846d8314d2020-05-15 09:34:58 -050085 // update data in file buffer as it will be needed to update ECC
86 // avoiding extra stream operation here
87 auto iteratorToKWdData = vpdFile.begin();
88 std::advance(iteratorToKWdData, thisRecord.kwDataOffset);
89 std::copy(iteratorToNewdata, end, iteratorToKWdData);
90
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -050091#ifdef ManagerTest
92 auto startItr = vpdFile.begin();
93 std::advance(iteratorToKWdData, thisRecord.kwDataOffset);
94 auto endItr = startItr;
95 std::advance(endItr, thisRecord.kwdDataLength);
96
97 Binary updatedData(startItr, endItr);
98 if (updatedData == kwdData)
99 {
100 throw std::runtime_error("Data updated successfully");
101 }
102#else
103
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500104 // update data in EEPROM as well. As we will not write complete file back
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500105 vpdFileStream.seekp(startOffset + thisRecord.kwDataOffset, std::ios::beg);
Alpana Kumari920408d2020-05-14 00:07:03 -0500106
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500107 iteratorToNewdata = kwdData.cbegin();
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600108 std::copy(iteratorToNewdata, end,
109 std::ostreambuf_iterator<char>(vpdFileStream));
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500110
111 // get a hold to new data in case encoding is needed
112 thisRecord.kwdUpdatedData.resize(thisRecord.kwdDataLength);
113 auto itrToKWdData = vpdFile.cbegin();
114 std::advance(itrToKWdData, thisRecord.kwDataOffset);
115 auto kwdDataEnd = itrToKWdData;
116 std::advance(kwdDataEnd, thisRecord.kwdDataLength);
117 std::copy(itrToKWdData, kwdDataEnd, thisRecord.kwdUpdatedData.begin());
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500118#endif
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600119}
120
121void EditorImpl::checkRecordForKwd()
122{
123 RecordOffset recOffset = thisRecord.recOffset;
124
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500125 // Amount to skip for record ID, size, and the RT keyword
126 constexpr auto skipBeg = sizeof(RecordId) + sizeof(RecordSize) +
127 lengths::KW_NAME + sizeof(KwSize);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600128
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500129 auto iterator = vpdFile.cbegin();
130 std::advance(iterator, recOffset + skipBeg + lengths::RECORD_NAME);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600131
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500132 auto end = iterator;
133 std::advance(end, thisRecord.recSize);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600134 std::size_t dataLength = 0;
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500135
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600136 while (iterator < end)
137 {
138 // Note keyword name
139 std::string kw(iterator, iterator + lengths::KW_NAME);
140
141 // Check if the Keyword starts with '#'
142 char kwNameStart = *iterator;
143 std::advance(iterator, lengths::KW_NAME);
144
145 // if keyword starts with #
146 if (POUND_KW == kwNameStart)
147 {
148 // Note existing keyword data length
149 dataLength = readUInt16LE(iterator);
150
151 // Jump past 2Byte keyword length + data
152 std::advance(iterator, sizeof(PoundKwSize));
153 }
154 else
155 {
156 // Note existing keyword data length
157 dataLength = *iterator;
158
159 // Jump past keyword length and data
160 std::advance(iterator, sizeof(KwSize));
161 }
162
163 if (thisRecord.recKWd == kw)
164 {
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500165 thisRecord.kwDataOffset = std::distance(vpdFile.cbegin(), iterator);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600166 thisRecord.kwdDataLength = dataLength;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600167 return;
168 }
169
170 // jump the data of current kwd to point to next kwd name
171 std::advance(iterator, dataLength);
172 }
173
174 throw std::runtime_error("Keyword not found");
175}
176
177void EditorImpl::updateRecordECC()
178{
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500179 auto itrToRecordData = vpdFile.cbegin();
180 std::advance(itrToRecordData, thisRecord.recOffset);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600181
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500182 auto itrToRecordECC = vpdFile.cbegin();
183 std::advance(itrToRecordECC, thisRecord.recECCoffset);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600184
185 auto l_status = vpdecc_create_ecc(
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500186 const_cast<uint8_t*>(&itrToRecordData[0]), thisRecord.recSize,
187 const_cast<uint8_t*>(&itrToRecordECC[0]), &thisRecord.recECCLength);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600188 if (l_status != VPD_ECC_OK)
189 {
190 throw std::runtime_error("Ecc update failed");
191 }
192
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500193 auto end = itrToRecordECC;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600194 std::advance(end, thisRecord.recECCLength);
195
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500196#ifndef ManagerTest
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500197 vpdFileStream.seekp(startOffset + thisRecord.recECCoffset, std::ios::beg);
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500198 std::copy(itrToRecordECC, end,
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600199 std::ostreambuf_iterator<char>(vpdFileStream));
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500200#endif
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600201}
202
203auto EditorImpl::getValue(offsets::Offsets offset)
204{
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500205 auto itr = vpdFile.cbegin();
206 std::advance(itr, offset);
207 LE2ByteData lowByte = *itr;
208 LE2ByteData highByte = *(itr + 1);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600209 lowByte |= (highByte << 8);
210
211 return lowByte;
212}
213
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500214void EditorImpl::checkECC(Binary::const_iterator& itrToRecData,
215 Binary::const_iterator& itrToECCData,
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600216 RecordLength recLength, ECCLength eccLength)
217{
218 auto l_status =
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500219 vpdecc_check_data(const_cast<uint8_t*>(&itrToRecData[0]), recLength,
220 const_cast<uint8_t*>(&itrToECCData[0]), eccLength);
221
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600222 if (l_status != VPD_ECC_OK)
223 {
224 throw std::runtime_error("Ecc check failed for VTOC");
225 }
226}
227
228void EditorImpl::readVTOC()
229{
230 // read VTOC offset
231 RecordOffset tocOffset = getValue(offsets::VTOC_PTR);
232
233 // read VTOC record length
234 RecordLength tocLength = getValue(offsets::VTOC_REC_LEN);
235
236 // read TOC ecc offset
237 ECCOffset tocECCOffset = getValue(offsets::VTOC_ECC_OFF);
238
239 // read TOC ecc length
240 ECCLength tocECCLength = getValue(offsets::VTOC_ECC_LEN);
241
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500242 auto itrToRecord = vpdFile.cbegin();
243 std::advance(itrToRecord, tocOffset);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600244
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500245 auto iteratorToECC = vpdFile.cbegin();
246 std::advance(iteratorToECC, tocECCOffset);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600247
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500248 // validate ecc for the record
249 checkECC(itrToRecord, iteratorToECC, tocLength, tocECCLength);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600250
251 // to get to the record name.
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500252 std::advance(itrToRecord, sizeof(RecordId) + sizeof(RecordSize) +
253 // Skip past the RT keyword, which contains
254 // the record name.
255 lengths::KW_NAME + sizeof(KwSize));
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600256
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500257 std::string recordName(itrToRecord, itrToRecord + lengths::RECORD_NAME);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600258
259 if ("VTOC" != recordName)
260 {
261 throw std::runtime_error("VTOC record not found");
262 }
263
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600264 // jump to length of PT kwd
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500265 std::advance(itrToRecord, lengths::RECORD_NAME + lengths::KW_NAME);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600266
267 // Note size of PT
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500268 Byte ptLen = *itrToRecord;
269 std::advance(itrToRecord, 1);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600270
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500271 checkPTForRecord(itrToRecord, ptLen);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600272}
273
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600274template <typename T>
275void EditorImpl::makeDbusCall(const std::string& object,
276 const std::string& interface,
277 const std::string& property,
278 const std::variant<T>& data)
279{
280 auto bus = sdbusplus::bus::new_default();
SunnySrivastava1984a7392592020-03-09 10:19:33 -0500281 auto properties =
282 bus.new_method_call(INVENTORY_MANAGER_SERVICE, object.c_str(),
283 "org.freedesktop.DBus.Properties", "Set");
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600284 properties.append(interface);
285 properties.append(property);
286 properties.append(data);
287
288 auto result = bus.call(properties);
289
290 if (result.is_method_error())
291 {
292 throw std::runtime_error("bus call failed");
293 }
294}
295
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600296void EditorImpl::processAndUpdateCI(const std::string& objectPath)
297{
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000298 inventory::ObjectMap objects;
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600299 for (auto& commonInterface : jsonFile["commonInterfaces"].items())
300 {
301 for (auto& ciPropertyList : commonInterface.value().items())
302 {
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600303 if (ciPropertyList.value().type() ==
304 nlohmann::json::value_t::object)
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600305 {
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600306 if ((ciPropertyList.value().value("recordName", "") ==
307 thisRecord.recName) &&
308 (ciPropertyList.value().value("keywordName", "") ==
309 thisRecord.recKWd))
310 {
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000311 inventory::PropertyMap prop;
312 inventory::InterfaceMap interfaces;
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600313 std::string kwdData(thisRecord.kwdUpdatedData.begin(),
314 thisRecord.kwdUpdatedData.end());
315
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500316 prop.emplace(ciPropertyList.key(), std::move(kwdData));
317 interfaces.emplace(commonInterface.key(), std::move(prop));
318 objects.emplace(objectPath, std::move(interfaces));
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600319 }
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600320 }
321 }
322 }
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000323 // Notify PIM
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500324 common::utility::callPIM(std::move(objects));
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600325}
326
327void EditorImpl::processAndUpdateEI(const nlohmann::json& Inventory,
328 const inventory::Path& objPath)
329{
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000330 inventory::ObjectMap objects;
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600331 for (const auto& extraInterface : Inventory["extraInterfaces"].items())
332 {
333 if (extraInterface.value() != NULL)
334 {
335 for (const auto& eiPropertyList : extraInterface.value().items())
336 {
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600337 if (eiPropertyList.value().type() ==
338 nlohmann::json::value_t::object)
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600339 {
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600340 if ((eiPropertyList.value().value("recordName", "") ==
341 thisRecord.recName) &&
342 ((eiPropertyList.value().value("keywordName", "") ==
343 thisRecord.recKWd)))
344 {
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000345 inventory::PropertyMap prop;
346 inventory::InterfaceMap interfaces;
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600347 std::string kwdData(thisRecord.kwdUpdatedData.begin(),
348 thisRecord.kwdUpdatedData.end());
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000349 encodeKeyword(kwdData, eiPropertyList.value().value(
350 "encoding", ""));
351
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500352 prop.emplace(eiPropertyList.key(), std::move(kwdData));
353 interfaces.emplace(extraInterface.key(),
354 std::move(prop));
355 objects.emplace(objPath, std::move(interfaces));
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600356 }
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600357 }
358 }
359 }
360 }
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000361 // Notify PIM
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500362 common::utility::callPIM(std::move(objects));
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600363}
364
365void EditorImpl::updateCache()
366{
367 const std::vector<nlohmann::json>& groupEEPROM =
368 jsonFile["frus"][vpdFilePath].get_ref<const nlohmann::json::array_t&>();
369
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000370 inventory::ObjectMap objects;
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600371 // iterate through all the inventories for this file path
372 for (const auto& singleInventory : groupEEPROM)
373 {
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000374 inventory::PropertyMap prop;
375 inventory::InterfaceMap interfaces;
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600376 // by default inherit property is true
377 bool isInherit = true;
378
379 if (singleInventory.find("inherit") != singleInventory.end())
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600380 {
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600381 isInherit = singleInventory["inherit"].get<bool>();
382 }
383
384 if (isInherit)
385 {
Santosh Puranik32c46502022-02-10 08:55:07 +0530386 prop.emplace(thisRecord.recKWd, thisRecord.kwdUpdatedData);
387 interfaces.emplace(
388 (IPZ_INTERFACE + (std::string) "." + thisRecord.recName),
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500389 std::move(prop));
Santosh Puranik32c46502022-02-10 08:55:07 +0530390 objects.emplace(
391 (singleInventory["inventoryPath"].get<std::string>()),
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500392 std::move(interfaces));
SunnySrivastava1984d076da82020-03-05 05:33:35 -0600393
394 // process Common interface
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600395 processAndUpdateCI(singleInventory["inventoryPath"]
396 .get_ref<const nlohmann::json::string_t&>());
397 }
398
Santosh Puranik32c46502022-02-10 08:55:07 +0530399 // process extra interfaces
400 processAndUpdateEI(singleInventory,
401 singleInventory["inventoryPath"]
402 .get_ref<const nlohmann::json::string_t&>());
Sunny Srivastava26d6c142021-11-03 15:19:02 -0500403
404 // check if we need to copy some specific records in this case.
405 if (singleInventory.find("copyRecords") != singleInventory.end())
406 {
407 if (find(singleInventory["copyRecords"].begin(),
408 singleInventory["copyRecords"].end(),
409 thisRecord.recName) !=
410 singleInventory["copyRecords"].end())
411 {
412 prop.emplace(thisRecord.recKWd, thisRecord.kwdUpdatedData);
413 interfaces.emplace(
414 (IPZ_INTERFACE + std::string{"."} + thisRecord.recName),
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500415 std::move(prop));
Sunny Srivastava26d6c142021-11-03 15:19:02 -0500416 objects.emplace(
417 (singleInventory["inventoryPath"].get<std::string>()),
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500418 std::move(interfaces));
Sunny Srivastava26d6c142021-11-03 15:19:02 -0500419 }
420 }
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600421 }
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000422 // Notify PIM
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500423 common::utility::callPIM(std::move(objects));
SunnySrivastava1984b421bfd2020-03-02 08:59:32 -0600424}
425
SunnySrivastava198443306542020-04-01 02:50:20 -0500426void EditorImpl::expandLocationCode(const std::string& locationCodeType)
427{
428 std::string propertyFCorTM{};
429 std::string propertySE{};
430
431 if (locationCodeType == "fcs")
432 {
433 propertyFCorTM =
434 readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VCEN", "FC");
435 propertySE =
436 readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VCEN", "SE");
437 }
438 else if (locationCodeType == "mts")
439 {
440 propertyFCorTM =
441 readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "TM");
442 propertySE =
443 readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "SE");
444 }
445
446 const nlohmann::json& groupFRUS =
447 jsonFile["frus"].get_ref<const nlohmann::json::object_t&>();
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000448 inventory::ObjectMap objects;
449
SunnySrivastava198443306542020-04-01 02:50:20 -0500450 for (const auto& itemFRUS : groupFRUS.items())
451 {
452 const std::vector<nlohmann::json>& groupEEPROM =
453 itemFRUS.value().get_ref<const nlohmann::json::array_t&>();
454 for (const auto& itemEEPROM : groupEEPROM)
455 {
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000456 inventory::PropertyMap prop;
457 inventory::InterfaceMap interfaces;
458 const auto& objectPath = itemEEPROM["inventoryPath"];
459 sdbusplus::message::object_path object(objectPath);
460
SunnySrivastava198443306542020-04-01 02:50:20 -0500461 // check if the given item implements location code interface
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000462 if (itemEEPROM["extraInterfaces"].find(IBM_LOCATION_CODE_INF) !=
SunnySrivastava198443306542020-04-01 02:50:20 -0500463 itemEEPROM["extraInterfaces"].end())
464 {
465 const std::string& unexpandedLocationCode =
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000466 itemEEPROM["extraInterfaces"][IBM_LOCATION_CODE_INF]
SunnySrivastava198443306542020-04-01 02:50:20 -0500467 ["LocationCode"]
468 .get_ref<const nlohmann::json::string_t&>();
469 std::size_t idx = unexpandedLocationCode.find(locationCodeType);
470 if (idx != std::string::npos)
471 {
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000472 std::string expandedLocationCode(unexpandedLocationCode);
SunnySrivastava198443306542020-04-01 02:50:20 -0500473
474 if (locationCodeType == "fcs")
475 {
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000476 expandedLocationCode.replace(
SunnySrivastava198443306542020-04-01 02:50:20 -0500477 idx, 3,
478 propertyFCorTM.substr(0, 4) + ".ND0." + propertySE);
479 }
480 else if (locationCodeType == "mts")
481 {
482 std::replace(propertyFCorTM.begin(),
483 propertyFCorTM.end(), '-', '.');
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000484 expandedLocationCode.replace(
SunnySrivastava198443306542020-04-01 02:50:20 -0500485 idx, 3, propertyFCorTM + "." + propertySE);
486 }
487
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000488 // update the DBUS interface COM as well as XYZ path
489 prop.emplace("LocationCode", expandedLocationCode);
490 // TODO depricate this com.ibm interface later
491 interfaces.emplace(IBM_LOCATION_CODE_INF, prop);
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500492 interfaces.emplace(XYZ_LOCATION_CODE_INF, std::move(prop));
SunnySrivastava198443306542020-04-01 02:50:20 -0500493 }
494 }
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500495 objects.emplace(std::move(object), std::move(interfaces));
SunnySrivastava198443306542020-04-01 02:50:20 -0500496 }
497 }
Alpana Kumari414d5ae2021-03-04 21:06:35 +0000498 // Notify PIM
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500499 common::utility::callPIM(std::move(objects));
SunnySrivastava198443306542020-04-01 02:50:20 -0500500}
501
Santosh Puranika0b23912022-02-10 13:37:09 +0530502void EditorImpl::updateKeyword(const Binary& kwdData, uint32_t offset,
503 const bool& updCache)
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600504{
Santosh Puranika0b23912022-02-10 13:37:09 +0530505 startOffset = offset;
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500506#ifndef ManagerTest
Alpana Kumari920408d2020-05-14 00:07:03 -0500507 // TODO: Figure out a better way to get max possible VPD size.
508 Binary completeVPDFile;
509 completeVPDFile.resize(65504);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600510 vpdFileStream.open(vpdFilePath,
511 std::ios::in | std::ios::out | std::ios::binary);
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500512
Priyanga Ramasamye0084322022-09-27 06:28:33 -0500513 vpdFileStream.seekg(startOffset, std::ios_base::cur);
Alpana Kumari920408d2020-05-14 00:07:03 -0500514 vpdFileStream.read(reinterpret_cast<char*>(&completeVPDFile[0]), 65504);
515 completeVPDFile.resize(vpdFileStream.gcount());
516 vpdFileStream.clear(std::ios_base::eofbit);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600517
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500518 vpdFile = completeVPDFile;
Alpana Kumari920408d2020-05-14 00:07:03 -0500519
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500520#else
Alpana Kumari920408d2020-05-14 00:07:03 -0500521
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500522 Binary completeVPDFile = vpdFile;
Alpana Kumari920408d2020-05-14 00:07:03 -0500523
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500524#endif
525 if (vpdFile.empty())
526 {
527 throw std::runtime_error("Invalid File");
528 }
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500529 auto iterator = vpdFile.cbegin();
530 std::advance(iterator, IPZ_DATA_START);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600531
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500532 Byte vpdType = *iterator;
533 if (vpdType == KW_VAL_PAIR_START_TAG)
534 {
PriyangaRamasamy33c61c22021-04-06 11:15:57 -0500535 ParserInterface* Iparser = ParserFactory::getParser(completeVPDFile);
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500536 IpzVpdParser* ipzParser = dynamic_cast<IpzVpdParser*>(Iparser);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600537
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500538 try
539 {
540 if (ipzParser == nullptr)
541 {
542 throw std::runtime_error("Invalid cast");
543 }
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500544
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500545 ipzParser->processHeader();
546 delete ipzParser;
547 ipzParser = nullptr;
548 // ParserFactory::freeParser(Iparser);
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500549
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500550 // process VTOC for PTT rkwd
551 readVTOC();
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500552
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500553 // check record for keywrod
554 checkRecordForKwd();
555
556 // update the data to the file
557 updateData(kwdData);
558
559 // update the ECC data for the record once data has been updated
560 updateRecordECC();
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530561
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530562 if (updCache)
563 {
PriyangaRamasamyc0d1c0a2021-04-16 09:45:06 -0500564#ifndef ManagerTest
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530565 // update the cache once data has been updated
566 updateCache();
SunnySrivastava1984a0d460e2020-06-03 07:49:26 -0500567#endif
PriyangaRamasamyc0d1c0a2021-04-16 09:45:06 -0500568 }
SunnySrivastava1984e12b1812020-05-26 02:23:11 -0500569 }
570 catch (const std::exception& e)
571 {
572 if (ipzParser != nullptr)
573 {
574 delete ipzParser;
575 }
576 throw std::runtime_error(e.what());
577 }
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500578 return;
579 }
Priyanga Ramasamyc99a0b02022-06-08 14:53:39 -0500580 else
581 {
582 throw openpower::vpd::exceptions::VpdDataException(
583 "Could not find start tag in VPD " + vpdFilePath);
584 }
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600585}
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600586} // namespace editor
587} // namespace manager
588} // namespace vpd
Santosh Puranik32c46502022-02-10 08:55:07 +0530589} // namespace openpower