supla-device
Loading...
Searching...
No Matches
storage.h
1// SPDX-FileCopyrightText: AC SOFTWARE SP. Z O.O.
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#ifndef SRC_SUPLA_SUPLET_STORAGE_H_
5#define SRC_SUPLA_SUPLET_STORAGE_H_
6
7#include <stdint.h>
8#include <stddef.h>
9#include <supla/suplet/channel_map.h>
10#include <supla/suplet/config.h>
11
12namespace Supla {
13
14class Config;
15
16namespace Suplet {
17
19 public:
20 virtual ~ArtifactReader() = default;
21 virtual bool readArtifact(uint8_t instanceId,
22 uint32_t offset,
23 uint8_t *data,
24 uint16_t size) const = 0;
25};
26
28 bool valid = false;
29 uint8_t instanceId = 0;
30 uint8_t variant = 0;
31 uint16_t chunkIndex = 0;
32 uint32_t artifactSize = 0;
33 uint32_t receivedSize = 0;
34 uint32_t crc32State = 0xFFFFFFFF;
35};
36
39 InstanceRecord(const InstanceRecord &other);
40 InstanceRecord &operator=(const InstanceRecord &other);
42
43 bool setConfig(const uint8_t *data, uint16_t size);
44 void clearConfig();
45
46 uint8_t instanceId = 0;
47 uint32_t definitionId = 0;
48 uint16_t definitionVersion = 0;
49 uint32_t revision = 0;
50 uint8_t subDeviceId = 0;
51 uint16_t configSize = 0;
52 uint32_t artifactSize = 0;
53 uint32_t artifactCrc32 = 0;
54 ChannelMap channelMap = {};
55 uint8_t *config = nullptr;
56 const ArtifactReader *artifactReader = nullptr;
57};
58
60 public:
62 InstanceTable(const InstanceTable &) = delete;
63 InstanceTable &operator=(const InstanceTable &) = delete;
65
66 uint8_t getCount() const;
67 void clear();
68
69 bool add(const InstanceRecord &record);
70 bool removeByInstanceId(uint8_t instanceId);
71 InstanceRecord *findByInstanceId(uint8_t instanceId);
72 const InstanceRecord *findByInstanceId(uint8_t instanceId) const;
73 InstanceRecord *findBySubDeviceId(uint8_t subDeviceId);
74 const InstanceRecord *findBySubDeviceId(uint8_t subDeviceId) const;
75 InstanceRecord *getRecord(uint8_t index);
76 const InstanceRecord *getRecord(uint8_t index) const;
77
78 private:
79 bool resize(uint8_t newCount);
80
81 InstanceRecord *records = nullptr;
82 uint8_t count = 0;
83};
84
85class Storage : public ArtifactReader {
86 public:
87 explicit Storage(Supla::Config *config);
88
89 bool load(InstanceTable *table);
90 bool loadIndex(InstanceTable *table);
91 bool loadInstance(uint8_t instanceId, InstanceRecord *record);
92 bool save(const InstanceTable &table,
93 const ArtifactStorageHandle *stagedArtifact = nullptr);
94 bool erase();
95 bool beginStagedArtifact(uint8_t instanceId,
96 uint32_t artifactSize,
97 ArtifactStorageHandle *handle);
98 bool writeStagedArtifactChunk(ArtifactStorageHandle *handle,
99 const uint8_t *data,
100 uint16_t size);
101 bool abortStagedArtifact(ArtifactStorageHandle *handle);
102 bool readArtifact(uint8_t instanceId,
103 uint32_t offset,
104 uint8_t *data,
105 uint16_t size) const override;
106 static uint32_t stagedArtifactCrc32(
107 const ArtifactStorageHandle &handle);
108
109 private:
110#pragma pack(push, 1)
111 struct StoredInstanceHeader {
112 uint8_t version = 0;
113 uint8_t reserved = 0;
114 uint32_t definitionId = 0;
115 uint16_t definitionVersion = 0;
116 uint8_t channelCount = 0;
117 uint16_t configSize = 0;
118 uint32_t revision = 0;
119 uint32_t artifactSize = 0;
120 uint32_t artifactCrc32 = 0;
121 };
122
123 struct StoredInstanceHeaderV3 {
124 uint8_t version = 0;
125 uint8_t reserved = 0;
126 uint32_t definitionId = 0;
127 uint16_t definitionVersion = 0;
128 uint8_t channelCount = 0;
129 uint16_t configSize = 0;
130 };
131
132 struct StoredChannelMapping {
133 uint8_t channelId = 0;
134 uint8_t channelNumber = 0;
135 };
136#pragma pack(pop)
137
138 bool loadVariant(uint8_t instanceId, uint8_t variant, InstanceRecord *record)
139 const;
140 bool loadVariant(uint8_t instanceId,
141 uint8_t variant,
142 InstanceRecord *record,
143 bool loadConfig) const;
144 bool loadVariantMetadata(uint8_t instanceId,
145 uint8_t variant,
146 InstanceRecord *record,
147 bool loadConfig) const;
148 bool loadActiveVariant(uint8_t instanceId,
149 uint8_t *activeVariant,
150 InstanceRecord *record,
151 bool loadConfig,
152 bool cleanup);
153 bool saveVariant(const InstanceRecord &record,
154 uint8_t variant,
155 const ArtifactStorageHandle *stagedArtifact);
156 bool copyActiveArtifact(const InstanceRecord &record, uint8_t targetVariant);
157 bool validateArtifact(uint8_t instanceId,
158 uint8_t variant,
159 uint32_t artifactSize,
160 uint32_t expectedCrc32) const;
161 bool getActiveVariant(uint8_t instanceId, uint8_t *variant) const;
162 bool readArtifactFromVariant(uint8_t instanceId,
163 uint8_t variant,
164 const InstanceRecord &record,
165 uint32_t offset,
166 uint8_t *data,
167 uint16_t size) const;
168 bool eraseArtifactChunks(uint8_t instanceId, uint8_t variant);
169 bool eraseVariant(uint8_t instanceId, uint8_t variant);
170 bool eraseInstance(uint8_t instanceId);
171 bool cleanupLoadedInstance(uint8_t instanceId,
172 uint8_t activeVariant,
173 uint8_t loadedVariant);
174 bool slotExists(uint8_t instanceId) const;
175 void makeActKey(uint8_t instanceId, char *output) const;
176 void makeHeaderKey(uint8_t instanceId, uint8_t variant, char *output) const;
177 void makeChannelMapKey(uint8_t instanceId,
178 uint8_t variant,
179 char *output) const;
180 void makeConfigKey(uint8_t instanceId, uint8_t variant, char *output) const;
181 void makeArtifactChunkKey(uint8_t instanceId,
182 uint8_t variant,
183 uint16_t chunkIndex,
184 char *output) const;
185 bool readBlobExact(const char *key, char *output, size_t expectedSize) const;
186
187 Supla::Config *config = nullptr;
188};
189
190} // namespace Suplet
191} // namespace Supla
192
193#endif // SRC_SUPLA_SUPLET_STORAGE_H_
Definition config.h:44
Definition storage.h:18
Definition channel_map.h:25
Definition storage.h:59
Definition storage.h:85
Definition storage.h:37