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