1 /**
2  * Copyright © 2021 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include "action_environment.hpp"
19 #include "i2c_action.hpp"
20 
21 #include <cstdint>
22 #include <stdexcept>
23 #include <string>
24 
25 namespace phosphor::power::regulators
26 {
27 
28 /**
29  * @class I2CCaptureBytesAction
30  *
31  * Captures device register bytes to be stored in an error log.  Communicates
32  * with the device directly using the I2C interface.
33  *
34  * Implements the i2c_capture_bytes action in the JSON config file.
35  */
36 class I2CCaptureBytesAction : public I2CAction
37 {
38   public:
39     // Specify which compiler-generated methods we want
40     I2CCaptureBytesAction() = delete;
41     I2CCaptureBytesAction(const I2CCaptureBytesAction&) = delete;
42     I2CCaptureBytesAction(I2CCaptureBytesAction&&) = delete;
43     I2CCaptureBytesAction& operator=(const I2CCaptureBytesAction&) = delete;
44     I2CCaptureBytesAction& operator=(I2CCaptureBytesAction&&) = delete;
45     virtual ~I2CCaptureBytesAction() = default;
46 
47     /**
48      * Constructor.
49      *
50      * Throws an exception if the count parameter is invalid.
51      *
52      * @param reg Device register address.  Note: named 'reg' because 'register'
53      *            is a reserved keyword.
54      * @param count Number of bytes to read from the device register.
55      */
I2CCaptureBytesAction(uint8_t reg,uint8_t count)56     explicit I2CCaptureBytesAction(uint8_t reg, uint8_t count) :
57         reg{reg}, count{count}
58     {
59         if (count < 1)
60         {
61             throw std::invalid_argument{"Invalid byte count: Less than 1"};
62         }
63     }
64 
65     /**
66      * Executes this action.
67      *
68      * Reads one or more bytes from a device register using the I2C interface.
69      * The resulting values are stored as additional error data in the specified
70      * action environment.
71      *
72      * All of the bytes will be read in a single I2C operation.
73      *
74      * The device register was specified in the constructor.
75      *
76      * The device is obtained from the action environment.
77      *
78      * Throws an exception if an error occurs.
79      *
80      * @param environment action execution environment
81      * @return true
82      */
83     virtual bool execute(ActionEnvironment& environment) override;
84 
85     /**
86      * Returns the number of bytes to read from the device register.
87      *
88      * @return byte count
89      */
getCount() const90     uint8_t getCount() const
91     {
92         return count;
93     }
94 
95     /**
96      * Returns the device register address.
97      *
98      * @return register address
99      */
getRegister() const100     uint8_t getRegister() const
101     {
102         return reg;
103     }
104 
105     /**
106      * Returns a string description of this action.
107      *
108      * @return description of action
109      */
110     virtual std::string toString() const override;
111 
112   private:
113     /**
114      * Returns the key for storing additional error data as a key/value pair in
115      * the action environment.
116      *
117      * @param environment action execution environment
118      * @return error data key
119      */
120     std::string getErrorDataKey(ActionEnvironment& environment) const;
121 
122     /**
123      * Returns the value for storing additional error data as a key/value pair
124      * in the action environment.
125      *
126      * @param values Array of byte values read from the device.  The count data
127      *               member specifies the number of bytes that were read.
128      * @return error data value
129      */
130     std::string getErrorDataValue(const uint8_t* values) const;
131 
132     /**
133      * Device register address.  Note: named 'reg' because 'register' is a
134      * reserved keyword.
135      */
136     const uint8_t reg;
137 
138     /**
139      * Number of bytes to read from the device register.
140      */
141     const uint8_t count;
142 };
143 
144 } // namespace phosphor::power::regulators
145