1 // Copyright 2021 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "handler.hpp"
16 
17 #include <cstdint>
18 #include <memory>
19 #include <string>
20 #include <string_view>
21 #include <vector>
22 
23 namespace blobs
24 {
25 
26 namespace
27 {
28 constexpr std::string_view metricPath("/metric/snapshot");
29 } // namespace
30 
31 bool MetricBlobHandler::canHandleBlob(const std::string& path)
32 {
33     return path == metricPath;
34 }
35 
36 // A blob handler may have multiple Blobs. For this blob handler, there is only
37 // one blob.
38 std::vector<std::string> MetricBlobHandler::getBlobIds()
39 {
40     return {std::string(metricPath)};
41 }
42 
43 // BmcBlobDelete (7) is not supported.
44 bool MetricBlobHandler::deleteBlob(const std::string&)
45 {
46     return false;
47 }
48 
49 // BmcBlobStat (8) (global stat) is not supported.
50 bool MetricBlobHandler::stat(const std::string&, BlobMeta*)
51 {
52     return false;
53 }
54 
55 // Checks for a read-only flag.
56 bool MetricBlobHandler::isReadOnlyOpenFlags(const uint16_t flags)
57 {
58     if (((flags & blobs::OpenFlags::read) == blobs::OpenFlags::read) &&
59         ((flags & blobs::OpenFlags::write) == 0))
60     {
61         return true;
62     }
63     return false;
64 }
65 
66 // BmcBlobOpen(2) handler.
67 bool MetricBlobHandler::open(uint16_t session, uint16_t flags,
68                              const std::string& path)
69 {
70     if (!isReadOnlyOpenFlags(flags))
71     {
72         return false;
73     }
74     if (!canHandleBlob(path))
75     {
76         return false;
77     }
78     if (path == metricPath)
79     {
80         std::unique_ptr<metric_blob::BmcHealthSnapshot> bhs =
81             std::make_unique<metric_blob::BmcHealthSnapshot>();
82         bhs.get()->doWork();
83         sessions[session] = nullptr;
84         sessions[session] = std::move(bhs);
85         return true;
86     }
87     return false;
88 }
89 
90 // BmcBlobRead(3) handler.
91 std::vector<uint8_t> MetricBlobHandler::read(uint16_t session, uint32_t offset,
92                                              uint32_t requestedSize)
93 {
94     auto it = sessions.find(session);
95     if (it == sessions.end())
96     {
97         return {};
98     }
99 
100     std::string_view result = it->second->read(offset, requestedSize);
101     return std::vector<uint8_t>(result.begin(), result.end());
102 }
103 
104 // BmcBlobWrite(4) is not supported.
105 bool MetricBlobHandler::write(uint16_t, uint32_t, const std::vector<uint8_t>&)
106 {
107     return false;
108 }
109 
110 // BmcBlobWriteMeta(10) is not supported.
111 bool MetricBlobHandler::writeMeta(uint16_t, uint32_t,
112                                   const std::vector<uint8_t>&)
113 {
114     return false;
115 }
116 
117 // BmcBlobCommit(5) is not supported.
118 bool MetricBlobHandler::commit(uint16_t, const std::vector<uint8_t>&)
119 {
120     return false;
121 }
122 
123 // BmcBlobClose(6) handler.
124 bool MetricBlobHandler::close(uint16_t session)
125 {
126     auto itr = sessions.find(session);
127     if (itr == sessions.end())
128     {
129         return false;
130     }
131     sessions.erase(itr);
132     return true;
133 }
134 
135 // BmcBlobSessionStat(9) handler
136 bool MetricBlobHandler::stat(uint16_t session, BlobMeta* meta)
137 {
138     auto it = sessions.find(session);
139     if (it == sessions.end())
140     {
141         return false;
142     }
143     return it->second->stat(*meta);
144 }
145 
146 bool MetricBlobHandler::expire(uint16_t session)
147 {
148     return close(session);
149 }
150 
151 } // namespace blobs
152