blob: 929e4d125b7c1c2d877f9fc7f28f1462f541fc34 [file] [log] [blame]
Patrick Venturec0f499b2018-09-14 17:57:42 -07001#include "example/example.hpp"
2
3#include <algorithm>
Patrick Venture5100a382018-09-27 10:40:50 -07004#include <blobs-ipmid/manager.hpp>
Patrick Venturee01c0af2018-09-27 14:56:42 -07005#include <cstring>
Patrick Venture5100a382018-09-27 10:40:50 -07006#include <memory>
7#include <phosphor-logging/log.hpp>
Patrick Venturec0f499b2018-09-14 17:57:42 -07008#include <string>
9#include <vector>
10
11namespace blobs
12{
13
Patrick Venture5100a382018-09-27 10:40:50 -070014using namespace phosphor::logging;
15
Patrick Venturec0f499b2018-09-14 17:57:42 -070016constexpr char ExampleBlobHandler::supportedPath[];
17
18ExampleBlob* ExampleBlobHandler::getSession(uint16_t id)
19{
20 auto search = sessions.find(id);
21 if (search == sessions.end())
22 {
23 return nullptr;
24 }
25 /* Not thread-safe, however, the blob handler deliberately assumes serial
26 * execution. */
27 return &search->second;
28}
29
30bool ExampleBlobHandler::canHandleBlob(const std::string& path)
31{
32 return (path == supportedPath);
33}
34
35std::vector<std::string> ExampleBlobHandler::getBlobIds()
36{
37 return {supportedPath};
38}
39
40bool ExampleBlobHandler::deleteBlob(const std::string& path)
41{
42 return false;
43}
44
45bool ExampleBlobHandler::stat(const std::string& path, struct BlobMeta* meta)
46{
47 return false;
48}
49
50bool ExampleBlobHandler::open(uint16_t session, uint16_t flags,
51 const std::string& path)
52{
53 if (!canHandleBlob(path))
54 {
55 return false;
56 }
57
58 auto findSess = sessions.find(session);
59 if (findSess != sessions.end())
60 {
61 /* This session is already active. */
62 return false;
63 }
64 sessions[session] = ExampleBlob(session, flags);
65 return true;
66}
67
68std::vector<uint8_t> ExampleBlobHandler::read(uint16_t session, uint32_t offset,
69 uint32_t requestedSize)
70{
71 ExampleBlob* sess = getSession(session);
72 if (!sess)
73 {
74 return std::vector<uint8_t>();
75 }
76
77 /* Is the offset beyond the array? */
78 if (offset >= sizeof(sess->buffer))
79 {
80 return std::vector<uint8_t>();
81 }
82
83 /* Determine how many bytes we can read from the offset.
84 * In this case, if they read beyond "size" we allow it.
85 */
86 uint32_t remain = sizeof(sess->buffer) - offset;
87 uint32_t numBytes = std::min(remain, requestedSize);
88 /* Copy the bytes! */
89 std::vector<uint8_t> result(numBytes);
90 std::memcpy(result.data(), &sess->buffer[offset], numBytes);
91 return result;
92}
93
94bool ExampleBlobHandler::write(uint16_t session, uint32_t offset,
95 const std::vector<uint8_t>& data)
96{
97 ExampleBlob* sess = getSession(session);
98 if (!sess)
99 {
100 return false;
101 }
102 /* Is the offset beyond the array? */
103 if (offset >= sizeof(sess->buffer))
104 {
105 return false;
106 }
107 /* Determine whether all their bytes will fit. */
108 uint32_t remain = sizeof(sess->buffer) - offset;
109 if (data.size() > remain)
110 {
111 return false;
112 }
113 sess->length =
114 std::max(offset + data.size(),
115 static_cast<std::vector<uint8_t>::size_type>(sess->length));
116 std::memcpy(&sess->buffer[offset], data.data(), data.size());
117 return true;
118}
119
Patrick Venture5c4b17b2018-10-04 10:32:22 -0700120bool ExampleBlobHandler::writeMeta(uint16_t session, uint32_t offset,
121 const std::vector<uint8_t>& data)
122{
123 /* Not supported. */
124 return false;
125}
126
Patrick Venturec0f499b2018-09-14 17:57:42 -0700127bool ExampleBlobHandler::commit(uint16_t session,
128 const std::vector<uint8_t>& data)
129{
130 ExampleBlob* sess = getSession(session);
131 if (!sess)
132 {
133 return false;
134 }
135
136 /* Do something with the staged data!. */
137
138 return false;
139}
140
141bool ExampleBlobHandler::close(uint16_t session)
142{
143 ExampleBlob* sess = getSession(session);
144 if (!sess)
145 {
146 return false;
147 }
148
149 sessions.erase(session);
150 return true;
151}
152
153bool ExampleBlobHandler::stat(uint16_t session, struct BlobMeta* meta)
154{
155 ExampleBlob* sess = getSession(session);
156 if (!sess)
157 {
158 return false;
159 }
160 if (!meta)
161 {
162 return false;
163 }
164 meta->size = sess->length;
165 meta->blobState = sess->state;
166 return true;
167}
168
169bool ExampleBlobHandler::expire(uint16_t session)
170{
171 ExampleBlob* sess = getSession(session);
172 if (!sess)
173 {
174 return false;
175 }
176 /* TODO: implement session expiration behavior. */
177 return false;
178}
179
Patrick Venture5100a382018-09-27 10:40:50 -0700180void setupExampleHandler() __attribute__((constructor));
181
182void setupExampleHandler()
183{
Patrick Venture73eb6872018-10-01 18:37:34 -0700184 auto* manager = getBlobManager();
Patrick Venture5100a382018-09-27 10:40:50 -0700185 if (!manager->registerHandler(std::make_unique<ExampleBlobHandler>()))
186 {
187 log<level::ERR>("Failed to register Example Handler");
188 }
189}
190
Patrick Venturec0f499b2018-09-14 17:57:42 -0700191} // namespace blobs