xref: /openbmc/openpower-occ-control/i2c_occ.cpp (revision b5259a1e7433e997caf9c90565d8b0012a6e5820)
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