blob: 4ee3f5d9ea45acb275faa1ddc9aa83038fcc749b [file] [log] [blame]
Enrico Granata51cdb942019-06-18 16:40:17 -07001// Copyright 2019 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Enrico Granata9bb17522019-06-28 17:22:42 -07005#ifndef LIBMEMS_TEST_FAKES_H_
6#define LIBMEMS_TEST_FAKES_H_
Enrico Granata51cdb942019-06-18 16:40:17 -07007
8#include <algorithm>
9#include <functional>
10#include <map>
11#include <memory>
12#include <optional>
Harvey Yang3dfaed62020-05-19 17:29:02 +080013#include <queue>
Enrico Granata51cdb942019-06-18 16:40:17 -070014#include <string>
15#include <utility>
16#include <vector>
17
Harvey Yange5e98a82020-06-01 17:31:41 +080018#include <base/callback.h>
Harvey Yang3dfaed62020-05-19 17:29:02 +080019#include <base/files/scoped_file.h>
20
Enrico Granata51cdb942019-06-18 16:40:17 -070021#include "libmems/export.h"
22#include "libmems/iio_channel.h"
23#include "libmems/iio_context.h"
24#include "libmems/iio_device.h"
25
26namespace libmems {
Harvey Yang3dfaed62020-05-19 17:29:02 +080027
Enrico Granata9bb17522019-06-28 17:22:42 -070028namespace fakes {
Harvey Yang3dfaed62020-05-19 17:29:02 +080029
30constexpr double kFakeSamplingFrequency = 20.0;
31
32constexpr char kFakeAccelChns[][10] = {"accel_x", "accel_y", "accel_z",
33 "timestamp"};
34
35constexpr int64_t kFakeAccelSamples[][4] = {
36 {-35, 7273, -4507, 1576146547637646757LL},
37 {-38, 7272, -4508, 1576146547686105167LL},
38 {-33, 7268, -4512, 1576146547734874023LL},
39 {-34, 7269, -4504, 1576146547786726064LL},
40 {-34, 7268, -4507, 1576146547833537914LL},
41 {-31, 7273, -4505, 1576146547883362585LL},
42 {-37, 7268, -4513, 1576146547934823156LL},
43 {-38, 7275, -4508, 1576146547983531441LL},
44 {-33, 7275, -4505, 1576146548033991396LL},
45 {-38, 7267, -4507, 1576146548088318767LL},
46 {-31, 7267, -4510, 1576146548134533603LL},
47 {-36, 7274, -4506, 1576146548186771158LL},
48 {-34, 7269, -4513, 1576146548238155689LL},
49 {-37, 7272, -4513, 1576146548286133465LL},
50 {-39, 7272, -4513, 1576146548336164236LL},
51 {-33, 7270, -4508, 1576146548385059679LL},
52 {-31, 7272, -4508, 1576146548436017710LL},
53 {-35, 7270, -4506, 1576146548484018687LL},
54 {-33, 7270, -4508, 1576146548538176956LL},
55 {-40, 7269, -4509, 1576146548583872808LL},
56 {-32, 7272, -4505, 1576146548635528461LL},
57 {-39, 7269, -4509, 1576146548684053162LL},
58 {-40, 7268, -4504, 1576146548735750128LL},
59 {-38, 7275, -4505, 1576146548784907050LL},
60 {-31, 7270, -4507, 1576146548833993600LL},
61 {-32, 7270, -4513, 1576146548884498169LL},
62 {-38, 7273, -4512, 1576146548935454841LL},
63 {-34, 7268, -4511, 1576146548983930691LL},
64 {-39, 7272, -4513, 1576146549038354675LL},
65 {-31, 7270, -4504, 1576146549088311239LL},
66 {-33, 7267, -4504, 1576146549134915814LL},
67 {-35, 7267, -4512, 1576146549188095471LL},
68 {-34, 7273, -4506, 1576146549233478083LL},
69 {-35, 7272, -4510, 1576146549283536871LL},
70 {-36, 7275, -4510, 1576146549337812680LL},
71 {-31, 7268, -4512, 1576146549383408902LL},
72 {-32, 7266, -4504, 1576146549436766877LL},
73 {-31, 7266, -4508, 1576146549488317082LL},
74 {-35, 7274, -4510, 1576146549534105170LL},
75 {-35, 7267, -4512, 1576146549583480220LL},
76 {-32, 7270, -4505, 1576146549634549753LL},
77 {-40, 7269, -4513, 1576146549685827215LL},
78 {-36, 7270, -4509, 1576146549736114408LL},
79 {-39, 7269, -4507, 1576146549787294361LL},
80 {-34, 7275, -4508, 1576146549833679601LL},
81 {-32, 7273, -4512, 1576146549884508806LL},
82 {-39, 7270, -4506, 1576146549934510649LL},
83 {-33, 7275, -4508, 1576146549986826232LL},
84 {-32, 7274, -4510, 1576146550034265609LL},
85 {-31, 7274, -4512, 1576146550087723517LL},
86 {-37, 7269, -4509, 1576146550136676150LL},
87 {-40, 7272, -4505, 1576146550185471987LL},
88 {-32, 7274, -4505, 1576146550237360278LL},
89 {-34, 7273, -4506, 1576146550285154743LL},
90 {-37, 7266, -4510, 1576146550334400698LL},
91 {-35, 7268, -4504, 1576146550383655864LL},
92 {-31, 7271, -4513, 1576146550434743018LL},
93 {-38, 7275, -4507, 1576146550485860328LL},
94 {-33, 7273, -4509, 1576146550535665916LL},
95 {-39, 7274, -4509, 1576146550584116729LL},
96 {-37, 7275, -4505, 1576146550633930996LL},
97 {-38, 7266, -4505, 1576146550687553120LL},
98 {-39, 7271, -4513, 1576146550737380685LL},
99 {-35, 7274, -4513, 1576146550783783035LL},
100 {-34, 7270, -4507, 1576146550837586694LL},
101 {-34, 7274, -4508, 1576146550886005896LL},
102 {-33, 7270, -4505, 1576146550936765656LL},
103 {-34, 7266, -4509, 1576146550986799436LL},
104 {-40, 7275, -4504, 1576146551036790826LL},
105 {-39, 7269, -4512, 1576146551084304842LL},
106 {-36, 7269, -4513, 1576146551137261255LL},
107 {-39, 7275, -4510, 1576146551187516034LL},
108 {-37, 7275, -4507, 1576146551235906273LL},
109 {-35, 7266, -4505, 1576146551287630187LL},
110 {-40, 7270, -4507, 1576146551334310300LL},
111 {-38, 7272, -4509, 1576146551386779464LL},
112 {-34, 7271, -4506, 1576146551438113310LL},
113 {-38, 7273, -4505, 1576146551485026553LL},
114 {-31, 7275, -4511, 1576146551533460722LL},
115 {-33, 7268, -4513, 1576146551585759710LL},
116 {-38, 7269, -4512, 1576146551638235580LL},
117 {-31, 7275, -4508, 1576146551683932695LL},
118 {-39, 7275, -4509, 1576146551735875095LL},
119 {-32, 7271, -4506, 1576146551785431314LL},
120 {-32, 7270, -4513, 1576146551835168501LL},
121 {-31, 7268, -4509, 1576146551888121294LL},
122 {-36, 7266, -4512, 1576146551934178770LL},
123 {-40, 7268, -4511, 1576146551986036666LL},
124 {-31, 7268, -4508, 1576146552038004999LL},
125 {-37, 7274, -4511, 1576146552084664014LL},
126 {-40, 7270, -4513, 1576146552135709672LL},
127 {-34, 7275, -4512, 1576146552188045583LL},
128 {-36, 7270, -4508, 1576146552238295106LL},
129 {-34, 7269, -4504, 1576146552285517753LL},
130 {-38, 7266, -4508, 1576146552334026224LL},
131 {-35, 7269, -4509, 1576146552383932953LL},
132 {-37, 7270, -4506, 1576146552436224995LL},
133 {-31, 7272, -4509, 1576146552487159335LL},
134 {-34, 7268, -4511, 1576146552535876318LL},
135 {-32, 7268, -4512, 1576146552586294158LL}};
136
Enrico Granata9bb17522019-06-28 17:22:42 -0700137class LIBMEMS_EXPORT FakeIioChannel : public IioChannel {
Enrico Granata51cdb942019-06-18 16:40:17 -0700138 public:
Enrico Granata9bb17522019-06-28 17:22:42 -0700139 FakeIioChannel(const std::string& id, bool enabled);
Enrico Granata51cdb942019-06-18 16:40:17 -0700140
141 const char* GetId() const override { return id_.c_str(); }
142
143 bool IsEnabled() const override { return enabled_; }
Harvey Yang2c08cf72020-09-24 12:36:23 +0800144 void SetEnabled(bool en) override;
145
146 bool IsScanElementsEnabled() { return scan_elements_enabled_; }
147 bool SetScanElementsEnabled(bool en) override;
Enrico Granata51cdb942019-06-18 16:40:17 -0700148
Enrico Granata064a25c2019-07-15 15:48:03 -0700149 base::Optional<std::string> ReadStringAttribute(
150 const std::string& name) const override;
Enrico Granata064a25c2019-07-15 15:48:03 -0700151 base::Optional<int64_t> ReadNumberAttribute(
152 const std::string& name) const override;
Harvey Yang9903fc22020-03-16 14:22:53 +0800153 base::Optional<double> ReadDoubleAttribute(
154 const std::string& name) const override;
Enrico Granata064a25c2019-07-15 15:48:03 -0700155
Harvey Yang9903fc22020-03-16 14:22:53 +0800156 bool WriteStringAttribute(const std::string& name,
157 const std::string& value) override;
158 bool WriteNumberAttribute(const std::string& name, int64_t value) override;
159 bool WriteDoubleAttribute(const std::string& name, double value) override;
Enrico Granata064a25c2019-07-15 15:48:03 -0700160
Harvey Yang3dfaed62020-05-19 17:29:02 +0800161 // |index| should be within [0, |base::size(kFakeAccelSamples)|). If the raw
162 // attribute exists, the value is returned; otherwise, if the channel's id is
163 // within kFakeAccelChns, the corresponding value in |kFakeAccelSamples| is
164 // returned.
165 // Returns base::nullopt if none of the above is true.
166 base::Optional<int64_t> GetData(int index);
167
Enrico Granata51cdb942019-06-18 16:40:17 -0700168 private:
169 std::string id_;
170 bool enabled_;
Harvey Yang2c08cf72020-09-24 12:36:23 +0800171 bool scan_elements_enabled_ = false;
Enrico Granata064a25c2019-07-15 15:48:03 -0700172 std::map<std::string, std::string> text_attributes_;
Harvey Yang9903fc22020-03-16 14:22:53 +0800173 std::map<std::string, int64_t> numeric_attributes_;
174 std::map<std::string, double> double_attributes_;
Enrico Granata51cdb942019-06-18 16:40:17 -0700175};
176
Enrico Granata9bb17522019-06-28 17:22:42 -0700177class FakeIioContext;
Enrico Granata51cdb942019-06-18 16:40:17 -0700178
Enrico Granata9bb17522019-06-28 17:22:42 -0700179class LIBMEMS_EXPORT FakeIioDevice : public IioDevice {
Enrico Granata51cdb942019-06-18 16:40:17 -0700180 public:
Harvey Yang9260b662019-08-12 15:48:03 +0800181 FakeIioDevice(FakeIioContext* ctx, const std::string& name, int id);
Enrico Granata51cdb942019-06-18 16:40:17 -0700182
183 IioContext* GetContext() const override {
184 return reinterpret_cast<IioContext*>(context_);
185 }
186
Harvey Yang9260b662019-08-12 15:48:03 +0800187 base::FilePath GetPath() const override;
Enrico Granata51cdb942019-06-18 16:40:17 -0700188 iio_device* GetUnderlyingIioDevice() const override { return nullptr; }
189
190 const char* GetName() const override { return name_.c_str(); }
Harvey Yang9260b662019-08-12 15:48:03 +0800191 int GetId() const override { return id_; }
Enrico Granata51cdb942019-06-18 16:40:17 -0700192
193 base::Optional<std::string> ReadStringAttribute(
194 const std::string& name) const override;
195 base::Optional<int64_t> ReadNumberAttribute(
196 const std::string& name) const override;
Enrico Granatad2e57f42019-07-31 10:46:03 -0700197 base::Optional<double> ReadDoubleAttribute(
198 const std::string& name) const override;
Enrico Granata51cdb942019-06-18 16:40:17 -0700199
200 bool WriteStringAttribute(const std::string& name,
201 const std::string& value) override;
202 bool WriteNumberAttribute(const std::string& name, int64_t value) override;
Enrico Granatad2e57f42019-07-31 10:46:03 -0700203 bool WriteDoubleAttribute(const std::string& name, double value) override;
Enrico Granata51cdb942019-06-18 16:40:17 -0700204
Harvey Yangee5a26d2021-03-23 17:19:27 +0800205 bool HasFifo() const override { return !hrtimer_; }
Harvey Yangcbfe75e2021-01-21 09:35:25 +0800206
Enrico Granata51cdb942019-06-18 16:40:17 -0700207 bool SetTrigger(IioDevice* trigger) override;
208 IioDevice* GetTrigger() override { return trigger_; }
209
Harvey Yangee5a26d2021-03-23 17:19:27 +0800210 void SetHrtimer(IioDevice* hrtimer) { hrtimer_ = hrtimer; }
211 IioDevice* GetHrtimer() override { return hrtimer_; }
212
Gwendal Grignoua1446472020-06-30 18:00:05 -0700213 void AddChannel(std::unique_ptr<FakeIioChannel> chn) {
214 channels_.push_back({chn->GetId(), std::move(chn)});
Harvey Yang3dfaed62020-05-19 17:29:02 +0800215 }
Enrico Granata51cdb942019-06-18 16:40:17 -0700216
Enrico Granata51cdb942019-06-18 16:40:17 -0700217 bool EnableBuffer(size_t n) override;
218 bool DisableBuffer() override;
219 bool IsBufferEnabled(size_t* n = nullptr) const override;
220
Enrico Granataf6fde6d2019-07-17 11:44:16 -0700221 base::Optional<size_t> GetSampleSize() const override {
222 return base::nullopt;
223 }
224
Harvey Yangdf365182021-01-16 23:43:45 +0800225 bool CreateBuffer() override;
Harvey Yang3dfaed62020-05-19 17:29:02 +0800226 base::Optional<int32_t> GetBufferFd() override;
227 base::Optional<IioSample> ReadSample() override;
Harvey Yangdf365182021-01-16 23:43:45 +0800228 void FreeBuffer() override;
Harvey Yang3dfaed62020-05-19 17:29:02 +0800229
230 // Simulates a bad device: not readable fd and fails all reads.
231 void DisableFd();
232 // Simulates some failures when reading the kth sample. Can be called multiple
233 // times. The user should make sure the kth sample hasn't been read.
234 void AddFailedReadAtKthSample(int k);
Enrico Granataf6fde6d2019-07-17 11:44:16 -0700235
Harvey Yange5e98a82020-06-01 17:31:41 +0800236 // Pauses at kth sample. |callback| is run when (k-1)th sample is retrieved or
237 // when this function is called and |k| == |sample_index_|.
238 // The user should make sure that there wasn't a pause set and not occurred
239 // yet, |k| doesn't exceeds fake data's size, and the kth sample hasn't been
240 // read.
241 void SetPauseCallbackAtKthSamples(int k, base::OnceCallback<void()> callback);
242 // Resumes reading after being paused.
243 // The user should make sure this device is paused.
244 void ResumeReadingSamples();
245
Enrico Granata51cdb942019-06-18 16:40:17 -0700246 private:
Harvey Yang9f48d812020-06-30 16:24:30 +0800247 struct ChannelData {
248 std::string chn_id;
Harvey Yang7f5c89f2020-12-03 14:42:37 +0800249 FakeIioChannel* chn = nullptr;
Harvey Yang9f48d812020-06-30 16:24:30 +0800250 };
251
Harvey Yang3dfaed62020-05-19 17:29:02 +0800252 bool WriteByte();
253 bool ReadByte();
Harvey Yange5e98a82020-06-01 17:31:41 +0800254 void ClosePipe();
255 void SetPause();
Harvey Yang3dfaed62020-05-19 17:29:02 +0800256
Harvey Yang7f5c89f2020-12-03 14:42:37 +0800257 FakeIioContext* context_ = nullptr;
Enrico Granata51cdb942019-06-18 16:40:17 -0700258 std::string name_;
Harvey Yang9260b662019-08-12 15:48:03 +0800259 int id_;
Enrico Granata51cdb942019-06-18 16:40:17 -0700260 std::map<std::string, std::string> text_attributes_;
Harvey Yang9903fc22020-03-16 14:22:53 +0800261 std::map<std::string, int64_t> numeric_attributes_;
Enrico Granatad2e57f42019-07-31 10:46:03 -0700262 std::map<std::string, double> double_attributes_;
Harvey Yang7f5c89f2020-12-03 14:42:37 +0800263 IioDevice* trigger_ = nullptr;
Harvey Yangee5a26d2021-03-23 17:19:27 +0800264 IioDevice* hrtimer_ = nullptr;
Harvey Yang3dfaed62020-05-19 17:29:02 +0800265
266 // For |EnableBuffer|, |DisableBuffer|, and |IsBufferEnabled|.
Enrico Granata51cdb942019-06-18 16:40:17 -0700267 size_t buffer_length_ = 0;
268 bool buffer_enabled_ = false;
Harvey Yang3dfaed62020-05-19 17:29:02 +0800269
270 // For |CreateBuffer|, |GetBufferFd|, and |ReadSample|.
271 base::ScopedFD sample_fd_;
272 bool readable_fd_ = false;
273 int sample_index_ = 0;
274
Harvey Yangae4d5992020-06-16 17:00:39 +0800275 // Pops from the failure with the smallest sample index.
276 std::priority_queue<int, std::vector<int>, std::greater<int>>
277 failed_read_queue_;
Harvey Yange5e98a82020-06-01 17:31:41 +0800278
Harvey Yangae4d5992020-06-16 17:00:39 +0800279 bool disabled_fd_ = false;
Harvey Yange5e98a82020-06-01 17:31:41 +0800280 bool is_paused_ = false;
281 base::Optional<int> pause_index_;
282 base::OnceCallback<void()> pause_callback_;
Enrico Granata51cdb942019-06-18 16:40:17 -0700283};
284
Enrico Granata9bb17522019-06-28 17:22:42 -0700285class LIBMEMS_EXPORT FakeIioContext : public IioContext {
Enrico Granata51cdb942019-06-18 16:40:17 -0700286 public:
Enrico Granata9bb17522019-06-28 17:22:42 -0700287 FakeIioContext() = default;
Enrico Granata51cdb942019-06-18 16:40:17 -0700288
Gwendal Grignoua1446472020-06-30 18:00:05 -0700289 void AddDevice(std::unique_ptr<FakeIioDevice> device);
290 void AddTrigger(std::unique_ptr<FakeIioDevice> trigger);
Enrico Granata51cdb942019-06-18 16:40:17 -0700291
Harvey Yang9260b662019-08-12 15:48:03 +0800292 iio_context* GetCurrentContext() const override { return nullptr; };
Enrico Granata51cdb942019-06-18 16:40:17 -0700293 void Reload() override {}
Harvey Yang6698c862019-09-16 17:24:38 +0800294 bool SetTimeout(uint32_t timeout) override {
295 timeout_ = timeout;
296 return true;
297 }
Enrico Granata51cdb942019-06-18 16:40:17 -0700298
Harvey Yang9260b662019-08-12 15:48:03 +0800299 std::vector<IioDevice*> GetDevicesByName(const std::string& name) override;
300 IioDevice* GetDeviceById(int id) override;
301 std::vector<IioDevice*> GetAllDevices() override;
302
303 std::vector<IioDevice*> GetTriggersByName(const std::string& name) override;
304 IioDevice* GetTriggerById(int id) override;
305 std::vector<IioDevice*> GetAllTriggers() override;
Enrico Granata51cdb942019-06-18 16:40:17 -0700306
307 private:
Gwendal Grignoua1446472020-06-30 18:00:05 -0700308 IioDevice* GetFakeById(
309 int id, const std::map<int, std::unique_ptr<FakeIioDevice>>& devices_map);
Harvey Yang9260b662019-08-12 15:48:03 +0800310 std::vector<IioDevice*> GetFakeByName(
311 const std::string& name,
Gwendal Grignoua1446472020-06-30 18:00:05 -0700312 const std::map<int, std::unique_ptr<FakeIioDevice>>& devices_map);
Harvey Yang9260b662019-08-12 15:48:03 +0800313 std::vector<IioDevice*> GetFakeAll(
Gwendal Grignoua1446472020-06-30 18:00:05 -0700314 const std::map<int, std::unique_ptr<FakeIioDevice>>& devices_map);
Harvey Yang9260b662019-08-12 15:48:03 +0800315
Gwendal Grignoua1446472020-06-30 18:00:05 -0700316 std::map<int, std::unique_ptr<FakeIioDevice>> devices_;
317 std::map<int, std::unique_ptr<FakeIioDevice>> triggers_;
Harvey Yang9260b662019-08-12 15:48:03 +0800318
Harvey Yang6698c862019-09-16 17:24:38 +0800319 uint32_t timeout_;
Enrico Granata51cdb942019-06-18 16:40:17 -0700320};
321
Enrico Granata9bb17522019-06-28 17:22:42 -0700322} // namespace fakes
Enrico Granata51cdb942019-06-18 16:40:17 -0700323
324} // namespace libmems
325
Enrico Granata9bb17522019-06-28 17:22:42 -0700326#endif // LIBMEMS_TEST_FAKES_H_