1 /* 2 * Copyright (c) 2018-present Facebook. All Rights Reserved. 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 17 #include <ipmid/api.h> 18 #include <stdbool.h> 19 #include <stdio.h> 20 #include <sys/stat.h> 21 22 #include <appcommands.hpp> 23 #include <ipmid/api.hpp> 24 #include <ipmid/utils.hpp> 25 #include <nlohmann/json.hpp> 26 #include <phosphor-logging/lg2.hpp> 27 #include <phosphor-logging/log.hpp> 28 #include <sdbusplus/asio/connection.hpp> 29 #include <sdbusplus/asio/property.hpp> 30 31 #include <fstream> 32 #include <iomanip> 33 #include <iostream> 34 #include <sstream> 35 36 namespace ipmi 37 { 38 39 static constexpr bool DEBUG = false; 40 41 static constexpr auto JSON_POST_DATA_FILE = 42 "/usr/share/lcd-debug/post_desc.json"; 43 static constexpr auto JSON_GPIO_DATA_FILE = 44 "/usr/share/lcd-debug/gpio_desc.json"; 45 static constexpr auto JSON_SENSOR_NAMES_FILE = 46 "/usr/share/lcd-debug/cri_sensors.json"; 47 48 static constexpr auto ETH_INTF_NAME = "eth0"; 49 50 #define ESCAPE "\x1B" 51 #define ESC_BAT ESCAPE "B" 52 #define ESC_MCU_BL_VER ESCAPE "U" 53 #define ESC_MCU_RUN_VER ESCAPE "R" 54 #define ESC_ALT ESCAPE "[5;7m" 55 #define ESC_RST ESCAPE "[m" 56 57 static constexpr char LINE_DELIMITER = '\x1F'; 58 59 static constexpr size_t FRAME_BUFF_SIZE = 4096; 60 static constexpr size_t FRAME_PAGE_BUF_SIZE = 256; 61 62 #define FRU_ALL 0 63 #define BOOT_POSTCODE_SERVICE "xyz.openbmc_project.State.Boot.PostCode" 64 #define BOOT_POSTCODE_OBJECTPATH "/xyz/openbmc_project/State/Boot/PostCode" 65 #define BOOT_POSTCODE_INTERFACE "xyz.openbmc_project.State.Boot.PostCode" 66 67 static constexpr auto DEBUG_GPIO_KEY = "GpioDesc"; 68 static constexpr auto GPIO_ARRAY_SIZE = 4; 69 static constexpr auto GPIO_PIN_INDEX = 0; 70 static constexpr auto GPIO_LEVEL_INDEX = 1; 71 static constexpr auto GPIO_DEF_INDEX = 2; 72 static constexpr auto GPIO_DESC_INDEX = 3; 73 74 static constexpr size_t BMC_POSITION = 0; 75 76 static constexpr uint8_t meAddress = 1; 77 static constexpr uint8_t lun = 0; 78 79 using IpmbMethodType = 80 std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t, std::vector<uint8_t>>; 81 82 struct frame 83 { 84 char title[32]; 85 size_t max_size; 86 size_t max_page; 87 char* buf; 88 size_t idx_head, idx_tail; 89 size_t line_per_page; 90 size_t line_width; 91 size_t lines, pages; 92 uint8_t esc_sts; 93 bool overwrite; 94 time_t mtime; 95 frameipmi::frame96 frame() : buf(nullptr), pages(0), mtime(0) {} 97 98 void init(size_t size = FRAME_BUFF_SIZE); 99 void append(const std::string& str, size_t indent = 0); 100 int getPage(size_t page, char* page_buf, size_t page_buf_size); 101 bool isFull() const; 102 bool isEscSeq(char chr); 103 104 private: 105 auto parse(const std::string& input, size_t indent) -> std::string; 106 }; 107 108 frame frame_info; 109 frame frame_sel; 110 frame frame_snr; 111 frame frame_postcode; 112 113 enum class panel : uint8_t 114 { 115 NONE = 0, 116 MAIN = 1, 117 BOOT_ORDER = 2, 118 POWER_POLICY = 3, 119 }; 120 121 struct ctrl_panel 122 { 123 panel parent; 124 size_t item_num; 125 std::array<std::string, 8> item_str; 126 panel (*select)(size_t item); 127 }; 128 129 static panel panel_main(size_t item); 130 static panel panel_boot_order(size_t item); 131 static panel panel_power_policy(size_t item); 132 133 static ctrl_panel panels[] = { 134 {/* dummy entry for making other to 1-based */}, 135 { 136 .parent = panel::MAIN, 137 .item_num = 2, 138 .item_str = 139 { 140 "User Setting", 141 ">Boot Order", 142 ">Power Policy", 143 }, 144 .select = panel_main, 145 }, 146 { 147 .parent = panel::MAIN, 148 .item_num = 0, 149 .item_str = 150 { 151 "Boot Order", 152 }, 153 .select = panel_boot_order, 154 }, 155 { 156 .parent = panel::MAIN, 157 .item_num = 0, 158 .item_str = 159 { 160 "Power Policy", 161 }, 162 .select = panel_power_policy, 163 }, 164 }; 165 166 } // end of namespace ipmi 167