1 #include "handler.hpp"
2 
3 #include <cstdint>
4 #include <memory>
5 #include <string>
6 #include <string_view>
7 #include <vector>
8 
9 namespace blobs
10 {
11 
12 namespace
13 {
14 constexpr std::string_view metricPath("/metric/snapshot");
15 } // namespace
16 
17 bool MetricBlobHandler::canHandleBlob(const std::string& path)
18 {
19     return path == metricPath;
20 }
21 
22 // A blob handler may have multiple Blobs. For this blob handler, there is only
23 // one blob.
24 std::vector<std::string> MetricBlobHandler::getBlobIds()
25 {
26     return {std::string(metricPath)};
27 }
28 
29 // BmcBlobDelete (7) is not supported.
30 bool MetricBlobHandler::deleteBlob(const std::string& path)
31 {
32     return false;
33 }
34 
35 // BmcBlobStat (8) (global stat) is not supported.
36 bool MetricBlobHandler::stat(const std::string& path, BlobMeta* meta)
37 {
38     return false;
39 }
40 
41 // Checks for a read-only flag.
42 bool MetricBlobHandler::isReadOnlyOpenFlags(const uint16_t flags)
43 {
44     if (((flags & blobs::OpenFlags::read) == blobs::OpenFlags::read) &&
45         ((flags & blobs::OpenFlags::write) == 0))
46     {
47         return true;
48     }
49     return false;
50 }
51 
52 // BmcBlobOpen(2) handler.
53 bool MetricBlobHandler::open(uint16_t session, uint16_t flags,
54                              const std::string& path)
55 {
56     if (!isReadOnlyOpenFlags(flags))
57     {
58         return false;
59     }
60     if (!canHandleBlob(path))
61     {
62         return false;
63     }
64     if (path == metricPath)
65     {
66         std::unique_ptr<metric_blob::BmcHealthSnapshot> bhs =
67             std::make_unique<metric_blob::BmcHealthSnapshot>();
68         bhs.get()->doWork();
69         sessions[session] = nullptr;
70         sessions[session] = std::move(bhs);
71         return true;
72     }
73     return false;
74 }
75 
76 // BmcBlobRead(3) handler.
77 std::vector<uint8_t> MetricBlobHandler::read(uint16_t session, uint32_t offset,
78                                              uint32_t requestedSize)
79 {
80     auto it = sessions.find(session);
81     if (it == sessions.end())
82     {
83         return {};
84     }
85 
86     std::string_view result = it->second->read(offset, requestedSize);
87     return std::vector<uint8_t>(result.begin(), result.end());
88 }
89 
90 // BmcBlobWrite(4) is not supported.
91 bool MetricBlobHandler::write(uint16_t session, uint32_t offset,
92                               const std::vector<uint8_t>& data)
93 {
94     return false;
95 }
96 
97 // BmcBlobWriteMeta(10) is not supported.
98 bool MetricBlobHandler::writeMeta(uint16_t session, uint32_t offset,
99                                   const std::vector<uint8_t>& data)
100 {
101     return false;
102 }
103 
104 // BmcBlobCommit(5) is not supported.
105 bool MetricBlobHandler::commit(uint16_t session,
106                                const std::vector<uint8_t>& data)
107 {
108     return false;
109 }
110 
111 // BmcBlobClose(6) handler.
112 bool MetricBlobHandler::close(uint16_t session)
113 {
114     auto itr = sessions.find(session);
115     if (itr == sessions.end())
116     {
117         return false;
118     }
119     sessions.erase(itr);
120     return true;
121 }
122 
123 // BmcBlobSessionStat(9) handler
124 bool MetricBlobHandler::stat(uint16_t session, BlobMeta* meta)
125 {
126     auto it = sessions.find(session);
127     if (it == sessions.end())
128     {
129         return false;
130     }
131     return it->second->stat(*meta);
132 }
133 
134 bool MetricBlobHandler::expire(uint16_t session)
135 {
136     return close(session);
137 }
138 
139 } // namespace blobs
140