1 #include <algorithm> 2 #include <cassert> 3 #include <fstream> 4 5 #include "config.h" 6 #include "i2c_occ.hpp" 7 8 #ifdef I2C_OCC 9 10 namespace i2c_occ 11 { 12 13 namespace fs = std::experimental::filesystem; 14 15 // The device name's length, e.g. "p8-occ-hwmon" 16 constexpr auto DEVICE_NAME_LENGTH = 12; 17 // The occ name's length, e.g. "occ" 18 constexpr auto OCC_NAME_LENGTH = 3; 19 20 // static assert to make sure the i2c occ device name is expected 21 static_assert(sizeof(I2C_OCC_DEVICE_NAME) -1 == DEVICE_NAME_LENGTH); 22 static_assert(sizeof(OCC_NAME) -1 == OCC_NAME_LENGTH); 23 24 std::string getFileContent(const fs::path& f) 25 { 26 std::string ret(DEVICE_NAME_LENGTH, 0); 27 std::ifstream ifs(f.c_str(), std::ios::binary); 28 if (ifs.is_open()) 29 { 30 ifs.read(&ret[0], DEVICE_NAME_LENGTH); 31 ret.resize(ifs.gcount()); 32 } 33 return ret; 34 } 35 36 std::vector<std::string> getOccHwmonDevices(const char* path) 37 { 38 std::vector<std::string> result{}; 39 40 if (fs::is_directory(path)) 41 { 42 for (auto & p : fs::directory_iterator(path)) 43 { 44 // Check if a device's name is "p8-occ-hwmon" 45 auto f = p / "name"; 46 auto str = getFileContent(f); 47 if (str == I2C_OCC_DEVICE_NAME) 48 { 49 result.emplace_back(p.path().filename()); 50 } 51 } 52 std::sort(result.begin(), result.end()); 53 } 54 return result; 55 } 56 57 void i2cToDbus(std::string& path) 58 { 59 std::replace(path.begin(), path.end(), '-', '_'); 60 } 61 62 void dbusToI2c(std::string& path) 63 { 64 std::replace(path.begin(), path.end(), '_', '-'); 65 } 66 67 std::string getI2cDeviceName(const std::string& dbusPath) 68 { 69 auto name = fs::path(dbusPath).filename().string(); 70 71 // Need to make sure the name starts with "occ" 72 assert(name.compare(0, OCC_NAME_LENGTH, OCC_NAME) == 0); 73 74 // Change name like occ_3_0050 to 3_0050 75 name.erase(0, OCC_NAME_LENGTH + 1); 76 77 dbusToI2c(name); 78 return name; 79 } 80 81 } // namespace i2c_occ 82 83 #endif 84 85