blob: f5a797b6f685eb8587eb0603be85f18f2c808df3 [file] [log] [blame]
Tom Joseph75356c12021-06-20 03:52:40 -07001#include "inventory_manager.hpp"
2
Tom Joseph75356c12021-06-20 03:52:40 -07003#include "common/utils.hpp"
4#include "xyz/openbmc_project/Software/Version/server.hpp"
5
George Liuc453e162022-12-21 17:16:23 +08006#include <libpldm/firmware_update.h>
7
Riya Dixit49cfb132023-03-02 04:26:53 -06008#include <phosphor-logging/lg2.hpp>
9
Tom Joseph75356c12021-06-20 03:52:40 -070010#include <functional>
11
Riya Dixit49cfb132023-03-02 04:26:53 -060012PHOSPHOR_LOG2_USING;
13
Tom Joseph75356c12021-06-20 03:52:40 -070014namespace pldm
15{
Tom Joseph75356c12021-06-20 03:52:40 -070016namespace fw_update
17{
Tom Joseph75356c12021-06-20 03:52:40 -070018void InventoryManager::discoverFDs(const std::vector<mctp_eid_t>& eids)
19{
20 for (const auto& eid : eids)
21 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +093022 auto instanceId = instanceIdDb.next(eid);
Tom Joseph75356c12021-06-20 03:52:40 -070023 Request requestMsg(sizeof(pldm_msg_hdr) +
24 PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES);
25 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
26 auto rc = encode_query_device_identifiers_req(
27 instanceId, PLDM_QUERY_DEVICE_IDENTIFIERS_REQ_BYTES, request);
28 if (rc)
29 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +093030 instanceIdDb.free(eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -060031 error(
32 "encode_query_device_identifiers_req failed, EID={EID}, RC = {RC}",
33 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -070034 continue;
35 }
36
37 rc = handler.registerRequest(
38 eid, instanceId, PLDM_FWUP, PLDM_QUERY_DEVICE_IDENTIFIERS,
39 std::move(requestMsg),
40 std::move(std::bind_front(&InventoryManager::queryDeviceIdentifiers,
41 this)));
42 if (rc)
43 {
Riya Dixit49cfb132023-03-02 04:26:53 -060044 error(
45 "Failed to send QueryDeviceIdentifiers request, EID={EID}, RC = {RC}",
46 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -070047 }
48 }
49}
50
51void InventoryManager::queryDeviceIdentifiers(mctp_eid_t eid,
52 const pldm_msg* response,
53 size_t respMsgLen)
54{
55 if (response == nullptr || !respMsgLen)
56 {
Riya Dixit49cfb132023-03-02 04:26:53 -060057 error("No response received for QueryDeviceIdentifiers, EID={EID}",
58 "EID", unsigned(eid));
Tom Joseph75356c12021-06-20 03:52:40 -070059 return;
60 }
61
62 uint8_t completionCode = PLDM_SUCCESS;
63 uint32_t deviceIdentifiersLen = 0;
64 uint8_t descriptorCount = 0;
65 uint8_t* descriptorPtr = nullptr;
66
67 auto rc = decode_query_device_identifiers_resp(
68 response, respMsgLen, &completionCode, &deviceIdentifiersLen,
69 &descriptorCount, &descriptorPtr);
70 if (rc)
71 {
Riya Dixit49cfb132023-03-02 04:26:53 -060072 error(
73 "Decoding QueryDeviceIdentifiers response failed, EID={EID}, RC = {RC}",
74 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -070075 return;
76 }
77
78 if (completionCode)
79 {
Riya Dixit49cfb132023-03-02 04:26:53 -060080 error(
81 "QueryDeviceIdentifiers response failed with error completion code, EID={EID}, CC = {CC}",
82 "EID", unsigned(eid), "CC", unsigned(completionCode));
Tom Joseph75356c12021-06-20 03:52:40 -070083 return;
84 }
85
86 Descriptors descriptors{};
87 while (descriptorCount-- && (deviceIdentifiersLen > 0))
88 {
89 uint16_t descriptorType = 0;
90 variable_field descriptorData{};
91
92 rc = decode_descriptor_type_length_value(
93 descriptorPtr, deviceIdentifiersLen, &descriptorType,
94 &descriptorData);
95 if (rc)
96 {
Riya Dixit49cfb132023-03-02 04:26:53 -060097 error(
98 "Decoding descriptor type, length and value failed, EID={EID}, RC = {RC}",
99 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700100 return;
101 }
102
103 if (descriptorType != PLDM_FWUP_VENDOR_DEFINED)
104 {
105 std::vector<uint8_t> descData(
106 descriptorData.ptr, descriptorData.ptr + descriptorData.length);
107 descriptors.emplace(descriptorType, std::move(descData));
108 }
109 else
110 {
111 uint8_t descriptorTitleStrType = 0;
112 variable_field descriptorTitleStr{};
113 variable_field vendorDefinedDescriptorData{};
114
115 rc = decode_vendor_defined_descriptor_value(
116 descriptorData.ptr, descriptorData.length,
117 &descriptorTitleStrType, &descriptorTitleStr,
118 &vendorDefinedDescriptorData);
119 if (rc)
120 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600121 error(
122 "Decoding Vendor-defined descriptor value failed, EID={EID}, RC = {RC}",
123 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700124 return;
125 }
126
127 auto vendorDefinedDescriptorTitleStr =
128 utils::toString(descriptorTitleStr);
129 std::vector<uint8_t> vendorDescData(
130 vendorDefinedDescriptorData.ptr,
131 vendorDefinedDescriptorData.ptr +
132 vendorDefinedDescriptorData.length);
133 descriptors.emplace(descriptorType,
134 std::make_tuple(vendorDefinedDescriptorTitleStr,
135 vendorDescData));
136 }
137 auto nextDescriptorOffset =
138 sizeof(pldm_descriptor_tlv().descriptor_type) +
139 sizeof(pldm_descriptor_tlv().descriptor_length) +
140 descriptorData.length;
141 descriptorPtr += nextDescriptorOffset;
142 deviceIdentifiersLen -= nextDescriptorOffset;
143 }
144
145 descriptorMap.emplace(eid, std::move(descriptors));
146
147 // Send GetFirmwareParameters request
148 sendGetFirmwareParametersRequest(eid);
149}
150
151void InventoryManager::sendGetFirmwareParametersRequest(mctp_eid_t eid)
152{
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930153 auto instanceId = instanceIdDb.next(eid);
Tom Joseph75356c12021-06-20 03:52:40 -0700154 Request requestMsg(sizeof(pldm_msg_hdr) +
155 PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES);
156 auto request = reinterpret_cast<pldm_msg*>(requestMsg.data());
157 auto rc = encode_get_firmware_parameters_req(
158 instanceId, PLDM_GET_FIRMWARE_PARAMETERS_REQ_BYTES, request);
159 if (rc)
160 {
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930161 instanceIdDb.free(eid, instanceId);
Riya Dixit49cfb132023-03-02 04:26:53 -0600162 error("encode_get_firmware_parameters_req failed, EID={EID}, RC = {RC}",
163 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700164 return;
165 }
166
167 rc = handler.registerRequest(
168 eid, instanceId, PLDM_FWUP, PLDM_GET_FIRMWARE_PARAMETERS,
169 std::move(requestMsg),
170 std::move(
171 std::bind_front(&InventoryManager::getFirmwareParameters, this)));
172 if (rc)
173 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600174 error(
175 "Failed to send GetFirmwareParameters request, EID={EID}, RC = {RC}",
176 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700177 }
178}
179
180void InventoryManager::getFirmwareParameters(mctp_eid_t eid,
181 const pldm_msg* response,
182 size_t respMsgLen)
183{
184 if (response == nullptr || !respMsgLen)
185 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600186 error("No response received for GetFirmwareParameters, EID={EID}",
187 "EID", unsigned(eid));
Tom Joseph75356c12021-06-20 03:52:40 -0700188 descriptorMap.erase(eid);
189 return;
190 }
191
192 pldm_get_firmware_parameters_resp fwParams{};
193 variable_field activeCompImageSetVerStr{};
194 variable_field pendingCompImageSetVerStr{};
195 variable_field compParamTable{};
196
197 auto rc = decode_get_firmware_parameters_resp(
198 response, respMsgLen, &fwParams, &activeCompImageSetVerStr,
199 &pendingCompImageSetVerStr, &compParamTable);
200 if (rc)
201 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600202 error(
203 "Decoding GetFirmwareParameters response failed, EID={EID}, RC = {RC}",
204 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700205 return;
206 }
207
208 if (fwParams.completion_code)
209 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600210 error(
211 "GetFirmwareParameters response failed with error completion code, EID={EID}, CC = {CC}",
212 "EID", unsigned(eid), "CC", unsigned(fwParams.completion_code));
Tom Joseph75356c12021-06-20 03:52:40 -0700213 return;
214 }
215
216 auto compParamPtr = compParamTable.ptr;
217 auto compParamTableLen = compParamTable.length;
218 pldm_component_parameter_entry compEntry{};
219 variable_field activeCompVerStr{};
220 variable_field pendingCompVerStr{};
221
222 ComponentInfo componentInfo{};
223 while (fwParams.comp_count-- && (compParamTableLen > 0))
224 {
225 auto rc = decode_get_firmware_parameters_resp_comp_entry(
226 compParamPtr, compParamTableLen, &compEntry, &activeCompVerStr,
227 &pendingCompVerStr);
228 if (rc)
229 {
Riya Dixit49cfb132023-03-02 04:26:53 -0600230 error(
231 "Decoding component parameter table entry failed, EID={EID}, RC = {RC}",
232 "EID", unsigned(eid), "RC", rc);
Tom Joseph75356c12021-06-20 03:52:40 -0700233 return;
234 }
235
236 auto compClassification = compEntry.comp_classification;
237 auto compIdentifier = compEntry.comp_identifier;
238 componentInfo.emplace(
239 std::make_pair(compClassification, compIdentifier),
240 compEntry.comp_classification_index);
241 compParamPtr += sizeof(pldm_component_parameter_entry) +
242 activeCompVerStr.length + pendingCompVerStr.length;
243 compParamTableLen -= sizeof(pldm_component_parameter_entry) +
244 activeCompVerStr.length + pendingCompVerStr.length;
245 }
246 componentInfoMap.emplace(eid, std::move(componentInfo));
247}
248
249} // namespace fw_update
250
Riya Dixit49cfb132023-03-02 04:26:53 -0600251} // namespace pldm