1 /** 2 * Copyright © 2019 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include "ascii_string.hpp" 17 18 #include "pel_types.hpp" 19 20 namespace openpower 21 { 22 namespace pels 23 { 24 namespace src 25 { 26 27 AsciiString::AsciiString(Stream& stream) 28 { 29 unflatten(stream); 30 } 31 32 AsciiString::AsciiString(const message::Entry& entry) 33 { 34 // Power Error: 1100RRRR 35 // BMC Error: BDSSRRRR 36 // where: 37 // RRRR = reason code 38 // SS = subsystem ID 39 40 // First is type, like 'BD' 41 setByte(0, entry.src.type); 42 43 // Next is '00', or subsystem ID 44 if (entry.src.type == static_cast<uint8_t>(SRCType::powerError)) 45 { 46 setByte(2, 0x00); 47 } 48 else // BMC Error 49 { 50 // If subsystem wasn't specified, it should get set later in 51 // the SRC constructor. Default to 'other' in case it doesn't. 52 setByte(2, entry.subsystem ? entry.subsystem.value() : 0x70); 53 } 54 55 // Then the reason code 56 setByte(4, entry.src.reasonCode >> 8); 57 setByte(6, entry.src.reasonCode & 0xFF); 58 59 // Padded with spaces 60 for (size_t offset = 8; offset < asciiStringSize; offset++) 61 { 62 _string[offset] = ' '; 63 } 64 } 65 66 void AsciiString::flatten(Stream& stream) const 67 { 68 stream.write(_string.data(), _string.size()); 69 } 70 71 void AsciiString::unflatten(Stream& stream) 72 { 73 stream.read(_string.data(), _string.size()); 74 75 // Only allow certain ASCII characters as other entities will 76 // eventually want to display this. 77 std::for_each(_string.begin(), _string.end(), [](auto& c) { 78 if (!isalnum(c) && (c != ' ') && (c != '.') && (c != ':') && (c != '/')) 79 { 80 c = ' '; 81 } 82 }); 83 } 84 85 std::string AsciiString::get() const 86 { 87 std::string string{_string.begin(), _string.begin() + _string.size()}; 88 return string; 89 } 90 91 void AsciiString::setByte(size_t byteOffset, uint8_t value) 92 { 93 assert(byteOffset < asciiStringSize); 94 95 char characters[3]; 96 sprintf(characters, "%02X", value); 97 98 auto writeOffset = byteOffset; 99 _string[writeOffset++] = characters[0]; 100 _string[writeOffset] = characters[1]; 101 } 102 103 } // namespace src 104 } // namespace pels 105 } // namespace openpower 106