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