1 #pragma once
2 
3 #include <fstream>
4 #include <experimental/filesystem>
5 #include "occ_events.hpp"
6 #include "occ_errors.hpp"
7 #include "config.h"
8 
9 
10 namespace open_power
11 {
12 namespace occ
13 {
14 
15 namespace fs = std::experimental::filesystem;
16 
17 /** @class Device
18  *  @brief Binds and unbinds the OCC driver upon request
19  */
20 class Device
21 {
22     public:
23         Device() = delete;
24         ~Device() = default;
25         Device(const Device&) = delete;
26         Device& operator=(const Device&) = delete;
27         Device(Device&&) = default;
28         Device& operator=(Device&&) = default;
29 
30         /** @brief Constructs the Device object
31          *
32          *  @param[in] event    - Unique ptr reference to sd_event
33          *  @param[in] name     - OCC instance name
34          *  @param[in] callback - Optional callback on errors
35          */
36         Device(EventPtr& event,
37                const std::string& name,
38                std::function<void()> callBack = nullptr) :
39 #ifdef I2C_OCC
40             config(name),
41 #else
42             config(name + '-' + "dev0"),
43 #endif
44             errorFile(fs::path(config) / "occ_error"),
45             error(event, errorFile, callBack)
46         {
47             // Nothing to do here
48         }
49 
50         /** @brief Binds device to the OCC driver */
51         inline void bind()
52         {
53             // Bind the device
54             return write(bindPath, config);
55         }
56 
57         /** @brief Un-binds device from the OCC driver */
58         inline void unBind()
59         {
60            // Unbind the device
61            return write(unBindPath, config);
62         }
63 
64         /** @brief Starts to monitor for errors */
65         inline void addErrorWatch()
66         {
67             return error.addWatch();
68         }
69 
70         /** @brief stops monitoring for errors */
71         inline void removeErrorWatch()
72         {
73            return error.removeWatch();
74         }
75 
76     private:
77         /** @brief Config value to be used to do bind and unbind */
78         const std::string config;
79 
80         /** @brief This file contains 0 for success, non-zero for errors */
81         const fs::path errorFile;
82 
83         /**  @brief To bind the device to the OCC driver, do:
84          *
85          *    Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/bind
86          */
87         static fs::path bindPath;
88 
89         /**  @brief To un-bind the device from the OCC driver, do:
90          *    Write occ<#>-dev0 to: /sys/bus/platform/drivers/occ-hwmon/unbind
91          */
92         static fs::path unBindPath;
93 
94         /** Abstraction of error monitoring */
95         Error error;
96 
97         /** @brief file writer to achieve bind and unbind
98          *
99          *  @param[in] filename - Name of file to be written
100          *  @param[in] data     - Data to be written to
101          *  @return             - None
102          */
103         void write(const fs::path& fileName, const std::string& data)
104         {
105             // If there is an error, move the exception all the way up
106             std::ofstream file(fileName, std::ios::out);
107             file << data;
108             file.close();
109             return;
110         }
111 };
112 
113 } // namespace occ
114 } // namespace open_power
115