1711d51d8SMatt Spinler /** 2711d51d8SMatt Spinler * Copyright © 2019 IBM Corporation 3711d51d8SMatt Spinler * 4711d51d8SMatt Spinler * Licensed under the Apache License, Version 2.0 (the "License"); 5711d51d8SMatt Spinler * you may not use this file except in compliance with the License. 6711d51d8SMatt Spinler * You may obtain a copy of the License at 7711d51d8SMatt Spinler * 8711d51d8SMatt Spinler * http://www.apache.org/licenses/LICENSE-2.0 9711d51d8SMatt Spinler * 10711d51d8SMatt Spinler * Unless required by applicable law or agreed to in writing, software 11711d51d8SMatt Spinler * distributed under the License is distributed on an "AS IS" BASIS, 12711d51d8SMatt Spinler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13711d51d8SMatt Spinler * See the License for the specific language governing permissions and 14711d51d8SMatt Spinler * limitations under the License. 15711d51d8SMatt Spinler */ 16a906c940SMatt Spinler #include "fru_identity.hpp" 17a906c940SMatt Spinler 18*ba0ee002SMatt Spinler #include "pel_values.hpp" 19*ba0ee002SMatt Spinler 20a906c940SMatt Spinler namespace openpower 21a906c940SMatt Spinler { 22a906c940SMatt Spinler namespace pels 23a906c940SMatt Spinler { 24a906c940SMatt Spinler namespace src 25a906c940SMatt Spinler { 26a906c940SMatt Spinler 27a906c940SMatt Spinler FRUIdentity::FRUIdentity(Stream& pel) 28a906c940SMatt Spinler { 29a906c940SMatt Spinler pel >> _type >> _size >> _flags; 30a906c940SMatt Spinler 31*ba0ee002SMatt Spinler if (hasPN() || hasMP()) 32a906c940SMatt Spinler { 33a906c940SMatt Spinler pel.read(_pnOrProcedureID.data(), _pnOrProcedureID.size()); 34a906c940SMatt Spinler } 35a906c940SMatt Spinler 36*ba0ee002SMatt Spinler if (hasCCIN()) 37a906c940SMatt Spinler { 38a906c940SMatt Spinler pel.read(_ccin.data(), _ccin.size()); 39a906c940SMatt Spinler } 40a906c940SMatt Spinler 41*ba0ee002SMatt Spinler if (hasSN()) 42a906c940SMatt Spinler { 43a906c940SMatt Spinler pel.read(_sn.data(), _sn.size()); 44a906c940SMatt Spinler } 45a906c940SMatt Spinler } 46a906c940SMatt Spinler 47a09354b7SMatt Spinler size_t FRUIdentity::flattenedSize() const 48a09354b7SMatt Spinler { 49a09354b7SMatt Spinler size_t size = sizeof(_type) + sizeof(_size) + sizeof(_flags); 50a09354b7SMatt Spinler 51a09354b7SMatt Spinler if (hasPN() || hasMP()) 52a09354b7SMatt Spinler { 53a09354b7SMatt Spinler size += _pnOrProcedureID.size(); 54a09354b7SMatt Spinler } 55a09354b7SMatt Spinler 56a09354b7SMatt Spinler if (hasCCIN()) 57a09354b7SMatt Spinler { 58a09354b7SMatt Spinler size += _ccin.size(); 59a09354b7SMatt Spinler } 60a09354b7SMatt Spinler 61a09354b7SMatt Spinler if (hasSN()) 62a09354b7SMatt Spinler { 63a09354b7SMatt Spinler size += _sn.size(); 64a09354b7SMatt Spinler } 65a09354b7SMatt Spinler 66a09354b7SMatt Spinler return size; 67a09354b7SMatt Spinler } 68a09354b7SMatt Spinler 69*ba0ee002SMatt Spinler FRUIdentity::FRUIdentity(const std::string& partNumber, const std::string& ccin, 70*ba0ee002SMatt Spinler const std::string& serialNumber) 71*ba0ee002SMatt Spinler { 72*ba0ee002SMatt Spinler _type = substructureType; 73*ba0ee002SMatt Spinler _flags = hardwareFRU; 74*ba0ee002SMatt Spinler 75*ba0ee002SMatt Spinler setPartNumber(partNumber); 76*ba0ee002SMatt Spinler setCCIN(ccin); 77*ba0ee002SMatt Spinler setSerialNumber(serialNumber); 78*ba0ee002SMatt Spinler 79*ba0ee002SMatt Spinler _size = flattenedSize(); 80*ba0ee002SMatt Spinler } 81*ba0ee002SMatt Spinler 82*ba0ee002SMatt Spinler FRUIdentity::FRUIdentity(MaintProcedure procedure) 83*ba0ee002SMatt Spinler { 84*ba0ee002SMatt Spinler _type = substructureType; 85*ba0ee002SMatt Spinler _flags = maintenanceProc; 86*ba0ee002SMatt Spinler 87*ba0ee002SMatt Spinler setMaintenanceProcedure(procedure); 88*ba0ee002SMatt Spinler 89*ba0ee002SMatt Spinler _size = flattenedSize(); 90*ba0ee002SMatt Spinler } 91*ba0ee002SMatt Spinler 92a906c940SMatt Spinler std::optional<std::string> FRUIdentity::getPN() const 93a906c940SMatt Spinler { 94a906c940SMatt Spinler if (hasPN()) 95a906c940SMatt Spinler { 96a906c940SMatt Spinler // NULL terminated 97a906c940SMatt Spinler std::string pn{_pnOrProcedureID.data()}; 98a906c940SMatt Spinler return pn; 99a906c940SMatt Spinler } 100a906c940SMatt Spinler 101a906c940SMatt Spinler return std::nullopt; 102a906c940SMatt Spinler } 103a906c940SMatt Spinler 104a906c940SMatt Spinler std::optional<std::string> FRUIdentity::getMaintProc() const 105a906c940SMatt Spinler { 106a906c940SMatt Spinler if (hasMP()) 107a906c940SMatt Spinler { 108a906c940SMatt Spinler // NULL terminated 109a906c940SMatt Spinler std::string mp{_pnOrProcedureID.data()}; 110a906c940SMatt Spinler return mp; 111a906c940SMatt Spinler } 112a906c940SMatt Spinler 113a906c940SMatt Spinler return std::nullopt; 114a906c940SMatt Spinler } 115a906c940SMatt Spinler 116a906c940SMatt Spinler std::optional<std::string> FRUIdentity::getCCIN() const 117a906c940SMatt Spinler { 118a906c940SMatt Spinler if (hasCCIN()) 119a906c940SMatt Spinler { 120a906c940SMatt Spinler std::string ccin{_ccin.begin(), _ccin.begin() + _ccin.size()}; 121*ba0ee002SMatt Spinler 122*ba0ee002SMatt Spinler // Don't leave any NULLs in the string (not there usually) 123*ba0ee002SMatt Spinler if (auto pos = ccin.find('\0'); pos != std::string::npos) 124*ba0ee002SMatt Spinler { 125*ba0ee002SMatt Spinler ccin.resize(pos); 126*ba0ee002SMatt Spinler } 127a906c940SMatt Spinler return ccin; 128a906c940SMatt Spinler } 129a906c940SMatt Spinler 130a906c940SMatt Spinler return std::nullopt; 131a906c940SMatt Spinler } 132a906c940SMatt Spinler 133a906c940SMatt Spinler std::optional<std::string> FRUIdentity::getSN() const 134a906c940SMatt Spinler { 135a906c940SMatt Spinler if (hasSN()) 136a906c940SMatt Spinler { 137a906c940SMatt Spinler std::string sn{_sn.begin(), _sn.begin() + _sn.size()}; 138*ba0ee002SMatt Spinler 139*ba0ee002SMatt Spinler // Don't leave any NULLs in the string (not there usually) 140*ba0ee002SMatt Spinler if (auto pos = sn.find('\0'); pos != std::string::npos) 141*ba0ee002SMatt Spinler { 142*ba0ee002SMatt Spinler sn.resize(pos); 143*ba0ee002SMatt Spinler } 144a906c940SMatt Spinler return sn; 145a906c940SMatt Spinler } 146a906c940SMatt Spinler 147a906c940SMatt Spinler return std::nullopt; 148a906c940SMatt Spinler } 149a906c940SMatt Spinler 150724d0d8cSMatt Spinler void FRUIdentity::flatten(Stream& pel) const 151a906c940SMatt Spinler { 152a906c940SMatt Spinler pel << _type << _size << _flags; 153a906c940SMatt Spinler 154a906c940SMatt Spinler if (hasPN() || hasMP()) 155a906c940SMatt Spinler { 156a906c940SMatt Spinler pel.write(_pnOrProcedureID.data(), _pnOrProcedureID.size()); 157a906c940SMatt Spinler } 158a906c940SMatt Spinler 159a906c940SMatt Spinler if (hasCCIN()) 160a906c940SMatt Spinler { 161a906c940SMatt Spinler pel.write(_ccin.data(), _ccin.size()); 162a906c940SMatt Spinler } 163a906c940SMatt Spinler 164a906c940SMatt Spinler if (hasSN()) 165a906c940SMatt Spinler { 166a906c940SMatt Spinler pel.write(_sn.data(), _sn.size()); 167a906c940SMatt Spinler } 168a906c940SMatt Spinler } 169a906c940SMatt Spinler 170*ba0ee002SMatt Spinler void FRUIdentity::setPartNumber(const std::string& partNumber) 171*ba0ee002SMatt Spinler { 172*ba0ee002SMatt Spinler _flags |= pnSupplied; 173*ba0ee002SMatt Spinler _flags &= ~maintProcSupplied; 174*ba0ee002SMatt Spinler 175*ba0ee002SMatt Spinler auto pn = partNumber; 176*ba0ee002SMatt Spinler 177*ba0ee002SMatt Spinler // Strip leading whitespace on this one. 178*ba0ee002SMatt Spinler while (' ' == pn.front()) 179*ba0ee002SMatt Spinler { 180*ba0ee002SMatt Spinler pn = pn.substr(1); 181*ba0ee002SMatt Spinler } 182*ba0ee002SMatt Spinler 183*ba0ee002SMatt Spinler // Note: strncpy only writes NULLs if pn short 184*ba0ee002SMatt Spinler strncpy(_pnOrProcedureID.data(), pn.c_str(), _pnOrProcedureID.size()); 185*ba0ee002SMatt Spinler 186*ba0ee002SMatt Spinler // ensure null terminated 187*ba0ee002SMatt Spinler _pnOrProcedureID.back() = 0; 188*ba0ee002SMatt Spinler } 189*ba0ee002SMatt Spinler 190*ba0ee002SMatt Spinler void FRUIdentity::setCCIN(const std::string& ccin) 191*ba0ee002SMatt Spinler { 192*ba0ee002SMatt Spinler _flags |= ccinSupplied; 193*ba0ee002SMatt Spinler 194*ba0ee002SMatt Spinler // Note: _ccin not null terminated, though strncpy writes NULLs if short 195*ba0ee002SMatt Spinler strncpy(_ccin.data(), ccin.c_str(), _ccin.size()); 196*ba0ee002SMatt Spinler } 197*ba0ee002SMatt Spinler 198*ba0ee002SMatt Spinler void FRUIdentity::setSerialNumber(const std::string& serialNumber) 199*ba0ee002SMatt Spinler { 200*ba0ee002SMatt Spinler _flags |= snSupplied; 201*ba0ee002SMatt Spinler 202*ba0ee002SMatt Spinler // Note: _sn not null terminated, though strncpy writes NULLs if short 203*ba0ee002SMatt Spinler strncpy(_sn.data(), serialNumber.c_str(), _sn.size()); 204*ba0ee002SMatt Spinler } 205*ba0ee002SMatt Spinler 206*ba0ee002SMatt Spinler void FRUIdentity::setMaintenanceProcedure(MaintProcedure procedure) 207*ba0ee002SMatt Spinler { 208*ba0ee002SMatt Spinler _flags |= maintProcSupplied; 209*ba0ee002SMatt Spinler _flags &= ~pnSupplied; 210*ba0ee002SMatt Spinler 211*ba0ee002SMatt Spinler auto proc = pel_values::getMaintProcedure(procedure); 212*ba0ee002SMatt Spinler 213*ba0ee002SMatt Spinler strncpy(_pnOrProcedureID.data(), std::get<pel_values::mpNamePos>(*proc), 214*ba0ee002SMatt Spinler _pnOrProcedureID.size()); 215*ba0ee002SMatt Spinler 216*ba0ee002SMatt Spinler // ensure null terminated 217*ba0ee002SMatt Spinler _pnOrProcedureID.back() = 0; 218*ba0ee002SMatt Spinler } 219*ba0ee002SMatt Spinler 220a906c940SMatt Spinler } // namespace src 221a906c940SMatt Spinler } // namespace pels 222a906c940SMatt Spinler } // namespace openpower 223