1 #pragma once
2 
3 #include "types.hpp"
4 
5 #include <fstream>
6 #include <phosphor-logging/log.hpp>
7 #include <sdbusplus/bus.hpp>
8 
9 namespace phosphor
10 {
11 namespace time
12 {
13 namespace utils
14 {
15 
16 using namespace phosphor::logging;
17 
18 /** @brief Read data with type T from file
19  *
20  * @param[in] fileName - The name of file to read from
21  *
22  * @return The data with type T
23  */
24 template <typename T>
25 T readData(const char* fileName)
26 {
27     T data{};
28     std::ifstream fs(fileName);
29     if (fs.is_open())
30     {
31         fs >> data;
32     }
33     return data;
34 }
35 
36 /** @brief Write data with type T to file
37  *
38  * @param[in] fileName - The name of file to write to
39  * @param[in] data - The data with type T to write to file
40  */
41 template <typename T>
42 void writeData(const char* fileName, T&& data)
43 {
44     std::ofstream fs(fileName, std::ios::out);
45     if (fs.is_open())
46     {
47         fs << std::forward<T>(data);
48     }
49 }
50 
51 /** @brief The template function to get property from the requested dbus path
52  *
53  * @param[in] bus          - The Dbus bus object
54  * @param[in] service      - The Dbus service name
55  * @param[in] path         - The Dbus object path
56  * @param[in] interface    - The Dbus interface
57  * @param[in] propertyName - The property name to get
58  *
59  * @return The value of the property
60  */
61 template <typename T>
62 T getProperty(sdbusplus::bus::bus& bus, const char* service, const char* path,
63               const char* interface, const char* propertyName)
64 {
65     auto method = bus.new_method_call(service, path,
66                                       "org.freedesktop.DBus.Properties", "Get");
67     method.append(interface, propertyName);
68     try
69     {
70         std::variant<T> value{};
71         auto reply = bus.call(method);
72         reply.read(value);
73         return std::get<T>(value);
74     }
75     catch (const sdbusplus::exception::SdBusError& ex)
76     {
77         log<level::ERR>("GetProperty call failed", entry("PATH=%s", path),
78                         entry("INTERFACE=%s", interface),
79                         entry("PROPERTY=%s", propertyName));
80         throw std::runtime_error("GetProperty call failed");
81     }
82 }
83 
84 /** @brief Get service name from object path and interface
85  *
86  * @param[in] bus          - The Dbus bus object
87  * @param[in] path         - The Dbus object path
88  * @param[in] interface    - The Dbus interface
89  *
90  * @return The name of the service
91  */
92 std::string getService(sdbusplus::bus::bus& bus, const char* path,
93                        const char* interface);
94 
95 /** @brief Convert a string to enum Mode
96  *
97  * Convert the time mode string to enum.
98  * Valid strings are
99  *   "xyz.openbmc_project.Time.Synchronization.Method.NTP"
100  *   "xyz.openbmc_project.Time.Synchronization.Method.Manual"
101  * If it's not a valid time mode string, it means something
102  * goes wrong so raise exception.
103  *
104  * @param[in] mode - The string of time mode
105  *
106  * @return The Mode enum
107  */
108 Mode strToMode(const std::string& mode);
109 
110 /** @brief Convert a mode enum to mode string
111  *
112  * @param[in] mode - The Mode enum
113  *
114  * @return The string of the mode
115  */
116 std::string modeToStr(Mode mode);
117 
118 } // namespace utils
119 } // namespace time
120 } // namespace phosphor
121