xref: /openbmc/phosphor-ipmi-blobs/example/example.cpp (revision c0f499b594b158bdb6c61764c27729fef6837cd3)
1 #include "example/example.hpp"
2 
3 #include <algorithm>
4 #include <string>
5 #include <vector>
6 
7 namespace blobs
8 {
9 
10 constexpr char ExampleBlobHandler::supportedPath[];
11 
12 ExampleBlob* ExampleBlobHandler::getSession(uint16_t id)
13 {
14     auto search = sessions.find(id);
15     if (search == sessions.end())
16     {
17         return nullptr;
18     }
19     /* Not thread-safe, however, the blob handler deliberately assumes serial
20      * execution. */
21     return &search->second;
22 }
23 
24 bool ExampleBlobHandler::canHandleBlob(const std::string& path)
25 {
26     return (path == supportedPath);
27 }
28 
29 std::vector<std::string> ExampleBlobHandler::getBlobIds()
30 {
31     return {supportedPath};
32 }
33 
34 bool ExampleBlobHandler::deleteBlob(const std::string& path)
35 {
36     return false;
37 }
38 
39 bool ExampleBlobHandler::stat(const std::string& path, struct BlobMeta* meta)
40 {
41     return false;
42 }
43 
44 bool ExampleBlobHandler::open(uint16_t session, uint16_t flags,
45                               const std::string& path)
46 {
47     if (!canHandleBlob(path))
48     {
49         return false;
50     }
51 
52     auto findSess = sessions.find(session);
53     if (findSess != sessions.end())
54     {
55         /* This session is already active. */
56         return false;
57     }
58     sessions[session] = ExampleBlob(session, flags);
59     return true;
60 }
61 
62 std::vector<uint8_t> ExampleBlobHandler::read(uint16_t session, uint32_t offset,
63                                               uint32_t requestedSize)
64 {
65     ExampleBlob* sess = getSession(session);
66     if (!sess)
67     {
68         return std::vector<uint8_t>();
69     }
70 
71     /* Is the offset beyond the array? */
72     if (offset >= sizeof(sess->buffer))
73     {
74         return std::vector<uint8_t>();
75     }
76 
77     /* Determine how many bytes we can read from the offset.
78      * In this case, if they read beyond "size" we allow it.
79      */
80     uint32_t remain = sizeof(sess->buffer) - offset;
81     uint32_t numBytes = std::min(remain, requestedSize);
82     /* Copy the bytes! */
83     std::vector<uint8_t> result(numBytes);
84     std::memcpy(result.data(), &sess->buffer[offset], numBytes);
85     return result;
86 }
87 
88 bool ExampleBlobHandler::write(uint16_t session, uint32_t offset,
89                                const std::vector<uint8_t>& data)
90 {
91     ExampleBlob* sess = getSession(session);
92     if (!sess)
93     {
94         return false;
95     }
96     /* Is the offset beyond the array? */
97     if (offset >= sizeof(sess->buffer))
98     {
99         return false;
100     }
101     /* Determine whether all their bytes will fit. */
102     uint32_t remain = sizeof(sess->buffer) - offset;
103     if (data.size() > remain)
104     {
105         return false;
106     }
107     sess->length =
108         std::max(offset + data.size(),
109                  static_cast<std::vector<uint8_t>::size_type>(sess->length));
110     std::memcpy(&sess->buffer[offset], data.data(), data.size());
111     return true;
112 }
113 
114 bool ExampleBlobHandler::commit(uint16_t session,
115                                 const std::vector<uint8_t>& data)
116 {
117     ExampleBlob* sess = getSession(session);
118     if (!sess)
119     {
120         return false;
121     }
122 
123     /* Do something with the staged data!. */
124 
125     return false;
126 }
127 
128 bool ExampleBlobHandler::close(uint16_t session)
129 {
130     ExampleBlob* sess = getSession(session);
131     if (!sess)
132     {
133         return false;
134     }
135 
136     sessions.erase(session);
137     return true;
138 }
139 
140 bool ExampleBlobHandler::stat(uint16_t session, struct BlobMeta* meta)
141 {
142     ExampleBlob* sess = getSession(session);
143     if (!sess)
144     {
145         return false;
146     }
147     if (!meta)
148     {
149         return false;
150     }
151     meta->size = sess->length;
152     meta->blobState = sess->state;
153     return true;
154 }
155 
156 bool ExampleBlobHandler::expire(uint16_t session)
157 {
158     ExampleBlob* sess = getSession(session);
159     if (!sess)
160     {
161         return false;
162     }
163     /* TODO: implement session expiration behavior. */
164     return false;
165 }
166 
167 } // namespace blobs
168