MeshProtocolSimulator  1.0.0
JSON_helper.h
1 #pragma once
2 #include <iostream>
3 #include <fstream>
4 #include <ctime>
5 #include <chrono>
6 #include "rapidjson/rapidjson.h"
7 #include "rapidjson/reader.h"
8 #include "rapidjson/filereadstream.h"
9 #include "rapidjson/schema.h"
10 #include "rapidjson/error/en.h"
11 #include "JSONScenarioSchemaHelper.h"
12 #include <Emulator_helpers.h>
13 
14 
15 struct JSONSettings {
16  bool auto_pause = false;
17  std::chrono::seconds simulation_limit;
18  std::vector<NodeConnections> node_connections;
19  std::vector<NodeSettings> node_settings;
20 
24  void reset();
25 
33  void validateAndSort();
34 };
35 
36 
38 {
39 public:
40  inline std::string getVersion() {
41  return version;
42  }
43 
44  inline JSONSettings getSettings() {
45  return settings;
46  }
47 
48  bool parse(std::string path);
49 
50  inline rapidjson::ParseResult getLastParseResult() {
51  return lastParseResult;
52  }
53 
54  inline rapidjson::ParseResult getLastSchemaParseResult() {
55  return lastSchemaParseResult;
56  }
57 
58  static bool pathExists(const char* path);
59 
60  void clear() {
61  settings.reset();
62  }
63 
64 protected:
68  std::string version = "0.0.1";
69 
70  bool verified = false;
71 
72  JSONSettings settings;
73 
74  rapidjson::ParseResult lastParseResult;
75  rapidjson::ParseResult lastSchemaParseResult;
76 
77  bool ParseJSON(std::string filePath);
78 
79  struct JSONReaderHandler : public rapidjson::BaseReaderHandler<rapidjson::UTF8<>, JSONReaderHandler> {
80  void init(JSONScenarioReader* reader_) {
81  reader = reader_;
82  reader->version = "";
83  reader->verified = false;
84  reader->settings.reset();
85  }
86 
87  bool Null() {
88  return true;
89  }
90  bool Bool(bool b) {
91  if (lastKeys.size() == 2 && lastKeys[1] == "settings") {
92  if (currentKey == "auto_pause") {
93  reader->settings.auto_pause = b;
94  }
95  }
96  else if (lastKeys.size() == 4 && lastKeys[1] == "settings" && lastKeys[2] == "node_settings" && currentKey == "is_gateway") {
97  currentNodeSettings.isGateway = b;
98  }
99  return true;
100  }
101 
102  bool Int(int i) {
103  return AnyNumber(i, i, false);
104  }
105  bool Uint(unsigned u) {
106  return AnyNumber(u, u, true);
107  }
108  bool Int64(int64_t i) {
109  return AnyNumber(i, i, false);
110  }
111  bool Uint64(uint64_t u) {
112  return AnyNumber(u, u, true);
113  }
114 
115  bool Double(double d) {
116  if (lastKeys.size() == 4 && lastKeys[1] == "settings" && lastKeys[2] == "node_connections") {
117  if (currentKey == "RSSI") {
118  if (d >= -120.00f && d <= 0.00f) {
119  currentNodeConnection.RSSI = d;
120  }
121  }
122  else if (currentKey == "RSSI_tolerance") {
123  if (d >= 0.00f && d <= 120.00f) {
124  currentNodeConnection.RSSI_tolerance = d;
125  }
126  }
127  else if (currentKey == "quality") {
128  if (d >= 0.00f && d <= 1.00f) {
129  currentNodeConnection.Quality = d;
130  }
131  }
132  }
133  return true;
134  }
135 
136  bool String(const char* str, rapidjson::SizeType length, bool copy) {
137  std::string value = std::string(str, length);
138  if (lastKeys.size() == 1) {
139  if (currentKey == "type") {
140  if (value == "Simulation scenario") {
141  reader->verified = true;
142  }
143  else return false;
144  }
145  else if (currentKey == "version") {
146  reader->version = value;
147  }
148  }
149  else if (lastKeys.size() == 4 && lastKeys[1] == "settings" && lastKeys[2] == "node_settings" && currentKey == "SSID") {
150  currentNodeSettings.SSID = std::string(str, length);
151  }
152  //TODO decode scenario
153  return true;
154  }
155 
156  bool StartObject() {
157  lastKeys.push_back(currentKey);
158  if (lastKeys.size() == 4) {
159  currentNodeConnection = NodeConnections(); //Clearing
160  currentNodeSettings.clear();
161  }
162  return true;
163  }
164  bool Key(const char* str, rapidjson::SizeType length, bool copy) {
165  currentKey = std::string(str, length);
166  return true;
167  }
168  bool EndObject(rapidjson::SizeType memberCount) {
169  lastKeys.pop_back();
170  if (lastKeys.size() == 3 && lastKeys[1] == "settings" && lastKeys[2] == "node_connections") {
171  reader->settings.node_connections.push_back(currentNodeConnection);
172  }
173  else if (lastKeys.size() == 3 && lastKeys[1] == "settings" && lastKeys[2] == "node_settings" && currentNodeSettings.MACAddress != 0) {
174  reader->settings.node_settings.push_back(currentNodeSettings);
175  }
176  return true;
177  }
178 
179  bool StartArray(){
180  lastKeys.push_back(currentKey);
181  currentKey = "";
182  return true;
183  }
184  bool EndArray(rapidjson::SizeType elementCount) {
185  lastKeys.pop_back();
186  return true;
187  }
188 
189  bool AnyNumber(uint64_t valu, int64_t val, bool isUnsinged) {
190  if (lastKeys.size() == 2 && lastKeys[1] == "settings") {
191  if (currentKey == "simulation_limit") {
192  reader->settings.simulation_limit = std::chrono::seconds(valu);
193  }
194  }
195  else if (lastKeys.size() == 4 && lastKeys[1] == "settings" && lastKeys[2] == "node_connections") {
196  if (currentKey == "node1") {
197  if (valu > 0 && valu <= UINT32_MAX) {
198  currentNodeConnection.Node1 = valu;
199  }
200  }
201  else if (currentKey == "node2") {
202  if (valu > 0 && valu <= UINT32_MAX) {
203  currentNodeConnection.Node2 = valu;
204  }
205  }
206  }
207  else if (lastKeys.size() == 4 && lastKeys[1] == "settings" && lastKeys[2] == "node_settings") {
208  if (currentKey == "node") {
209  currentNodeSettings.MACAddress = (uint32_t)valu;
210  }
211  else if (currentKey == "MCU_frequency") {
212  currentNodeSettings.MCUFrequency = (uint32_t)valu;
213  }
214  else if (currentKey == "pre_send_cycles_delay") {
215  currentNodeSettings.preSendCyclesDelay = (uint32_t)valu;
216  }
217  else if (currentKey == "pre_send_delay") {
218  currentNodeSettings.preSendDelay = std::chrono::nanoseconds(valu);
219  }
220  else if (currentKey == "sending_speed") {
221  currentNodeSettings.sendingSpeed = (uint32_t)valu;
222  }
223  else if (currentKey == "extra_bits_sent_count") {
224  currentNodeSettings.extraBitsSentCount = (uint32_t)valu;
225  }
226  else if (currentKey == "post_send_cycles_delay") {
227  currentNodeSettings.postSendCyclesDelay = (uint32_t)valu;
228  }
229  else if (currentKey == "post_send_delay") {
230  currentNodeSettings.postSendDelay = std::chrono::nanoseconds(valu);
231  }
232  else if (currentKey == "pre_receive_cycles_delay") {
233  currentNodeSettings.preReceiveCyclesDelay = (uint32_t)valu;
234  }
235  else if (currentKey == "pre_receive_delay") {
236  currentNodeSettings.preReceiveDelay = std::chrono::nanoseconds(valu);
237  }
238  else if (currentKey == "post_receive_cycles_delay") {
239  currentNodeSettings.postReceiveCyclesDelay = (uint32_t)valu;
240  }
241  else if (currentKey == "post_receive_delay") {
242  currentNodeSettings.postReceiveDelay = std::chrono::nanoseconds(valu);
243  }
244  else if (currentKey == "available_cycles_delay") {
245  currentNodeSettings.availableCyclesDelay = (uint32_t)valu;
246  }
247  else if (currentKey == "available_delay") {
248  currentNodeSettings.availableDelay = std::chrono::nanoseconds(valu);
249  }
250  else if (currentKey == "interference_check_cycles_delay") {
251  currentNodeSettings.interferenceCheckCyclesDelay = (uint32_t)valu;
252  }
253  else if (currentKey == "interference_check_delay") {
254  currentNodeSettings.interferenceCheckDelay = std::chrono::nanoseconds(valu);
255  }
256  else if (currentKey == "max_frame_size") {
257  if (valu > 255) valu = 255; //overflow protection
258  currentNodeSettings.maxFrameSize = (uint8_t)valu;
259  }
260  else if (currentKey == "input_fifo_size") {
261  currentNodeSettings.InputFiFoSize = (int)valu;
262  }
263  else if (currentKey == "start_delay") {
264  currentNodeSettings.simulationOffset = std::chrono::nanoseconds(valu);
265  }
266  }
267  return true;
268  }
269 
270  private:
271  std::string currentKey;
272  std::vector<std::string> lastKeys;
273  NodeConnections currentNodeConnection;
274  NodeSettings currentNodeSettings;
275  JSONScenarioReader* reader;
276  };
277 
278 };
279 
281 {
282 public:
283 
284  ~JSONLogsWriter() {
285  terminate();
286  }
287 
291  std::string version = "0.0.1";
292 
299  bool begin(const JSONSettings& settings, std::string path);
300 
306  void terminate();
307 
315  void end(int errorCode, std::string errorText);
316 
324  void exceptionEnd(int errorCode, std::string errorText);
325 
331  void end();
332 
338  void logMessageTransmit(RawMessage &message);
339 
348  void logMessageReceive(MeshMAC node, std::chrono::nanoseconds receiveTime, RawMessage& message, float RSSI);
349 
362  void logReceiveInterference(MeshMAC node, std::chrono::nanoseconds simulationTime, MeshMAC sender_node1, uint64_t sender_node1_UID, float rssi1, MeshMAC sender_node2, uint64_t sender_node2_UID, float rssi2);
363 
374  void logTransmitInterference(MeshMAC node, uint64_t node_UID, std::chrono::nanoseconds simulationTime, MeshMAC sender_node, uint64_t sender_node_UID, float RSSI);
375 
385  void logMessageLost(MeshMAC sender, MeshMAC receiver, uint64_t node_UID, std::chrono::nanoseconds simulationTime, float RSSI);
386 
396  void logAPLReceived(MeshMAC node, MeshMAC sender_node, std::chrono::nanoseconds simulationTime, char* messageData, size_t length);
397 
408  void logTableChange(MeshMAC node, std::string& descriptor, TableChangeType changeType, std::chrono::nanoseconds simulationTime, const char* data, size_t length);
409 
417  static std::string EncodeSpecialCharacters(const char* text, size_t inLength);
418 
425  static std::string EncodeSpecialCharacters(std::string& text) {
426  return EncodeSpecialCharacters(text.c_str(), text.length());
427  }
428 
433  static std::string GetCurrentTimeISO8601();
434 
435 protected:
436 
437  bool beginCalled = false;
438  std::chrono::steady_clock::time_point simulationStartTime;
439  std::ofstream outFile;
440  bool anyLogWritten = false;
441 };
JSONSettings::validateAndSort
void validateAndSort()
Removes extra settings or duplicate settings and sorts them by MAC address. If settings for some node...
Definition: JSON_helper.cpp:11
JSONScenarioReader::version
std::string version
Emulator version.
Definition: JSON_helper.h:68
JSONLogsWriter::logAPLReceived
void logAPLReceived(MeshMAC node, MeshMAC sender_node, std::chrono::nanoseconds simulationTime, char *messageData, size_t length)
Logs application layer received message to output log file.
Definition: JSON_helper.cpp:413
NodeSettings
Settings for each node in simulation. Those settings can be get from scenario file.
Definition: Emulator_helpers.h:124
NodeConnections::Node2
MeshMAC Node2
Second node.
Definition: Emulator_helpers.h:71
NodeSettings::MCUFrequency
uint32_t MCUFrequency
Simulation MCU frequency in Hz. Defaultly set to 16 MHz.
Definition: Emulator_helpers.h:148
JSONLogsWriter::EncodeSpecialCharacters
static std::string EncodeSpecialCharacters(const char *text, size_t inLength)
Encodes special characters in json string value. Escaped characters are '', '\f', ' ',...
Definition: JSON_helper.cpp:462
JSONLogsWriter::logTableChange
void logTableChange(MeshMAC node, std::string &descriptor, TableChangeType changeType, std::chrono::nanoseconds simulationTime, const char *data, size_t length)
Logs application layer received message to output log file.
Definition: JSON_helper.cpp:433
NodeSettings::preReceiveDelay
std::chrono::nanoseconds preReceiveDelay
Delay before message is received in nanoseconds. Defaultly set to 5µs.
Definition: Emulator_helpers.h:188
NodeSettings::availableDelay
std::chrono::nanoseconds availableDelay
Delay when checking message avaiability in nanoseconds. Defaultly set to 5µs.
Definition: Emulator_helpers.h:208
JSONLogsWriter::EncodeSpecialCharacters
static std::string EncodeSpecialCharacters(std::string &text)
Encodes special characters in json string value. Escaped characters are '', '\f', ' ',...
Definition: JSON_helper.h:425
JSONLogsWriter::terminate
void terminate()
Terminates logging and closes file. Output file "status" property will be set to "terminated".
Definition: JSON_helper.cpp:232
NodeSettings::sendingSpeed
uint32_t sendingSpeed
Speed of send in bits per second. Defaultly set to 1 Mbps.
Definition: Emulator_helpers.h:163
NodeSettings::clear
void clear()
Clears settings.
Definition: Emulator_helpers.h:233
rapidjson.h
common definitions and configuration
JSONSettings
Definition: JSON_helper.h:15
Emulator_helpers.h
This file contains helper classes or structured for Emulator class.
NodeSettings::preSendCyclesDelay
uint32_t preSendCyclesDelay
Delay before message sending in cycles. Defaultly set to 50.
Definition: Emulator_helpers.h:153
SizeType
RAPIDJSON_NAMESPACE_BEGIN typedef unsigned SizeType
Size type (for string lengths, array sizes, etc.)
Definition: rapidjson.h:380
NodeSettings::InputFiFoSize
int InputFiFoSize
Size of input FiFo on specified radio. Defaultly set to 3.
Definition: Emulator_helpers.h:228
JSONLogsWriter::logMessageReceive
void logMessageReceive(MeshMAC node, std::chrono::nanoseconds receiveTime, RawMessage &message, float RSSI)
Logs message receiving to output log file.
Definition: JSON_helper.cpp:330
JSONLogsWriter::logMessageLost
void logMessageLost(MeshMAC sender, MeshMAC receiver, uint64_t node_UID, std::chrono::nanoseconds simulationTime, float RSSI)
Logs lost message due to bad link quality to output log file.
Definition: JSON_helper.cpp:392
NodeSettings::postReceiveCyclesDelay
uint32_t postReceiveCyclesDelay
Delay after message is received in cycles. Defaultly set to 10.
Definition: Emulator_helpers.h:193
NodeSettings::postSendCyclesDelay
uint32_t postSendCyclesDelay
Delay after message sending in cycles. Defaultly set to 50.
Definition: Emulator_helpers.h:173
NodeSettings::availableCyclesDelay
uint32_t availableCyclesDelay
Delay when checking message avaiability in cycles. Defaultly set to 10.
Definition: Emulator_helpers.h:203
NodeConnections::RSSI
float RSSI
RSSI of current link connection in dBm. This value has to be negative and in range from 0dBm to -120d...
Definition: Emulator_helpers.h:76
NodeSettings::preReceiveCyclesDelay
uint32_t preReceiveCyclesDelay
Delay before message is received in cycles. Defaultly set to 10.
Definition: Emulator_helpers.h:183
JSONLogsWriter::logMessageTransmit
void logMessageTransmit(RawMessage &message)
Logs message transmission to output log file.
Definition: JSON_helper.cpp:310
String
Definition: Simulation.h:220
NodeConnections::RSSI_tolerance
float RSSI_tolerance
Absolute value, that can be added or subtracted from RSSI during simulation. When set to 0,...
Definition: Emulator_helpers.h:83
NodeSettings::postReceiveDelay
std::chrono::nanoseconds postReceiveDelay
Delay after message is received in nanoseconds. Defaultly set to 5µs.
Definition: Emulator_helpers.h:198
reader.h
RawMessage
This structure represents raw message, that was sent between two virtual radios. It has no header and...
Definition: Emulator_helpers.h:262
JSONLogsWriter::version
std::string version
Emulator version.
Definition: JSON_helper.h:291
JSONLogsWriter::logTransmitInterference
void logTransmitInterference(MeshMAC node, uint64_t node_UID, std::chrono::nanoseconds simulationTime, MeshMAC sender_node, uint64_t sender_node_UID, float RSSI)
Logs transmit interference (one node is sending message and another wants to send him message) to out...
Definition: JSON_helper.cpp:371
JSONLogsWriter::end
void end()
Ends logging and closes file. Output file "status" property will be set to "success".
Definition: JSON_helper.cpp:295
JSONLogsWriter::GetCurrentTimeISO8601
static std::string GetCurrentTimeISO8601()
Gets current pc time and converts it to ISO 8601.
Definition: JSON_helper.cpp:504
JSONScenarioReader::JSONReaderHandler
Definition: JSON_helper.h:79
NodeSettings::simulationOffset
std::chrono::nanoseconds simulationOffset
Simulation start offset.
Definition: Emulator_helpers.h:143
JSONLogsWriter::logReceiveInterference
void logReceiveInterference(MeshMAC node, std::chrono::nanoseconds simulationTime, MeshMAC sender_node1, uint64_t sender_node1_UID, float rssi1, MeshMAC sender_node2, uint64_t sender_node2_UID, float rssi2)
Logs receive interference (two nodes sends simultaneously and message cannot be received by "node") t...
Definition: JSON_helper.cpp:350
NodeSettings::maxFrameSize
uint8_t maxFrameSize
Maximum size of frame, that can be sent. Value can be from 24 to 255.
Definition: Emulator_helpers.h:223
NodeConnections::Node1
MeshMAC Node1
First node.
Definition: Emulator_helpers.h:66
NodeSettings::interferenceCheckCyclesDelay
uint32_t interferenceCheckCyclesDelay
Delay when checking interference in cycles. Defaultly set to 10.
Definition: Emulator_helpers.h:213
JSONScenarioReader
Definition: JSON_helper.h:37
JSONLogsWriter
Definition: JSON_helper.h:280
NodeConnections
This structure represents link connection between two nodes. Nodes are indentified by it's MeshMAC ad...
Definition: Emulator_helpers.h:47
NodeSettings::preSendDelay
std::chrono::nanoseconds preSendDelay
Delay before message sending in nanoseconds. Defaultly set to 13µs.
Definition: Emulator_helpers.h:158
JSONLogsWriter::begin
bool begin(const JSONSettings &settings, std::string path)
Begins simulation logging.
Definition: JSON_helper.cpp:146
NodeConnections::Quality
float Quality
Link quality, represented as probability, that sent packet through this link will be received....
Definition: Emulator_helpers.h:94
NodeSettings::postSendDelay
std::chrono::nanoseconds postSendDelay
Delay after message sending in nanoseconds. Defaultly set to 13µs.
Definition: Emulator_helpers.h:178
JSONSettings::reset
void reset()
Completelly clears settings to it's default state.
Definition: JSON_helper.cpp:4
NodeSettings::interferenceCheckDelay
std::chrono::nanoseconds interferenceCheckDelay
Delay when checking interference in nanoseconds. Defaultly set to 5µs.
Definition: Emulator_helpers.h:218
JSONLogsWriter::exceptionEnd
void exceptionEnd(int errorCode, std::string errorText)
Ends logging and closes file. Output file "status" property will be set to "success" or "exception" d...
Definition: JSON_helper.cpp:271
NodeSettings::extraBitsSentCount
uint32_t extraBitsSentCount
Count of extra bits sent with message (preamble, CRC, ...)
Definition: Emulator_helpers.h:168