Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • bias/packets/astri-packet
1 result
Show changes
Commits on Source (3)
Subproject commit 8a0ea2d0e699863df5fe1c91caf2d7b0855957be
Subproject commit a00f9a27afbf5f75dab7db2368b9b9b6fcb395e1
......@@ -4,15 +4,61 @@
namespace inaf::oasbo::Packets {
class AstriHornGeneric : public inaf::oasbo::PacketLib::BasePacket {
/**
* @brief Represents a generic ASTRI horn packet.
* @note the "magic numbers" in the implementation of this class derived from the ASTRI Camera BEE – Camera Camera Data Acquisition
* Interface Control Document.
* If the document is updated, be sure to update the magic numbers appropriately.
* This class inherits from the BasePacket class and provides
* functionality specific to ASTRI horn packets.
*/
class AstriHornGeneric: public inaf::oasbo::Packets::BasePacket {
public:
AstriHornGeneric(inaf::oasbo::PacketLib::BasePacketStructure &structure) : BasePacket(structure){}
/**
* @brief Constructs an AstriHornGeneric object with the given packet structure.
*
* @param structure The packet structure to be used.
*/
AstriHornGeneric(inaf::oasbo::Packets::BasePacketStructure &structure) :
BasePacket(structure) {
}
/**
* @brief Gets the size of the header in bytes.
*
* @return The size of the header.
*/
uint getHeaderSize() const override;
/**
* @brief Gets the size of the payload in bytes.
*
* @return The size of the payload.
*/
uint getPayloadSize() const override;
/**
* @brief Gets the size of the tail in bytes.
*
* @return The size of the tail.
*/
uint getTailSize() const override;
/**
* @brief Checks if the packet has a recognized header.
*
* @return True if the packet has a recognized header, false otherwise.
*/
bool hasRecognizedHeader() const override;
/**
* @brief Checks if the given buffer contains a recognized header.
*
* @param buff The buffer to check.
* @return True if the buffer contains a recognized header, false otherwise.
*/
bool isRecognizedHeader(std::vector<uint8_t> buff) const override;
};
}
}
/*
*
* Created on: Mar 1, 2021
* Author: astrisw
/**
* @brief This file contains the definition of the recognizedPackets for Astri Horn.
*
* The recognizedPackets vector is a static member of the inaf::oasbo::Packets::AstriHorn namespace.
* It stores tuples representing recognized packets, where each tuple contains three values:
* - The first value represents the packet type.
* - The second value represents the packet subtype.
* - The third value represents the packet length.
*
*/
#pragma once
#include <vector>
......@@ -16,6 +20,5 @@ static std::vector<std::tuple<size_t, size_t, size_t>> recognizedPackets = {
std::make_tuple(1, 3, 13268), std::make_tuple(1, 4, 13268),
std::make_tuple(2, 1, 9568), std::make_tuple(2, 2, 10900),
std::make_tuple(10, 1, 4526), std::make_tuple(10, 2, 19040),
std::make_tuple(15, 1, 12)
};
std::make_tuple(15, 1, 12) };
}
......@@ -4,39 +4,211 @@
namespace inaf::oasbo::Packets {
class AstriMaGeneric : public inaf::oasbo::PacketLib::BasePacket {
/**
* @brief The AstriMaGeneric class represents a generic packet used in the ASTRI DAQ system.
*
* @note the "magic numbers" in the implementation of this class derived from the ASTRI Camera BEE – Camera Camera Data Acquisition
* Interface Control Document.
* If the document is updated, be sure to update the magic numbers appropriately.
* This class inherits from the BasePacket class in the inaf::oasbo::Packets namespace.
* It provides methods to retrieve various properties of the packet, such as header size, payload size, tail size,
* telescope ID, type, subtype, SSC, packet length, date and time information, event counter, and various flags.
*/
class AstriMaGeneric: public inaf::oasbo::Packets::BasePacket {
public:
AstriMaGeneric(inaf::oasbo::PacketLib::BasePacketStructure &structure) : BasePacket(structure){}
AstriMaGeneric(inaf::oasbo::PacketLib::BasePacket &other) : BasePacket(other){}
/**
* @brief Constructs an AstriMaGeneric object with the given packet structure.
*
* @param structure The packet structure.
*/
AstriMaGeneric(inaf::oasbo::Packets::BasePacketStructure &structure) :
BasePacket(structure) {
}
/**
* @brief Constructs an AstriMaGeneric object by copying another BasePacket object.
*
* @param other The other BasePacket object to copy.
*/
AstriMaGeneric(inaf::oasbo::Packets::BasePacket &other) :
BasePacket(other) {
}
/**
* @brief Gets the size of the header in bytes.
*
* @return The size of the header.
*/
uint getHeaderSize() const override;
/**
* @brief Gets the size of the payload in bytes.
*
* @return The size of the payload.
*/
uint getPayloadSize() const override;
/**
* @brief Gets the size of the tail in bytes.
*
* @return The size of the tail.
*/
uint getTailSize() const override;
/**
* @brief Checks if the packet has a recognized header.
*
* @return True if the packet has a recognized header, false otherwise.
*/
bool hasRecognizedHeader() const override;
/**
* @brief Checks if the given buffer contains a recognized header.
*
* @param buff The buffer to check.
* @return True if the buffer contains a recognized header, false otherwise.
*/
bool isRecognizedHeader(std::vector<uint8_t> buff) const override;
/**
* @brief Gets the telescope ID field value.
*
* @return The telescope ID value.
*/
uint getTelescopeID() const;
/**
* @brief Gets the type of the packet.
*
* @return The packet type.
*/
uint getType() const;
/**
* @brief Gets the subtype of the packet.
*
* @return The packet subtype.
*/
uint getSubType() const;
/**
* @brief Gets the SSC field value.
*
* @return The SSC value.
*/
uint getSSC() const;
/**
* @brief Gets the packetlength field value.
*
* @return The packet length.
*/
uint getPacketLength() const;
/**
* @brief Gets the year field value.
*
* @return The year.
*/
uint getYear() const;
/**
* @brief Gets the month field value.
*
* @return The month.
*/
uint getMonth() const;
/**
* @brief Gets the day field value.
*
* @return The day.
*/
uint getDay() const;
/**
* @brief Gets the hour field value.
*
* @return The hour.
*/
uint getHour() const;
/**
* @brief Gets the minutes field value.
*
* @return The minutes.
*/
uint getMinutes() const;
/**
* @brief Gets the seconds field value.
*
* @return The seconds.
*/
uint getSeconds() const;
/**
* @brief get the validtime field value
*
* @return validtime
*/
bool getValidTime() const;
/**
* @brief Gets the time tag nanoseconds field value
*
* @return time tag nanoseconds.
*/
uint getTimeTagNanoseconds() const;
/**
* @brief Gets the event counter field value.
*
* @return The event counter.
*/
uint getEventCounter() const;
/**
* @brief get the lif field value.
*
* @return lid value
*/
bool getLid() const;
/**
* @brief get the fibst field value.
*
* @return fibst value.
*/
bool fibSt() const;
/**
* @brief get the fibCont field value.
*
* @return fibCont value.
*/
bool fibCont() const;
bool fibPuls() const;
uint rgbCont() const;
uint rgbPuls() const;
/**
* @brief get the fibPuls field value.
*
* @return fibPuls value.
*/
bool fibPuls() const;
/**
* @brief get the rgbCont field value.
*
* @return rgbCont value.
*/
uint rgbCont() const;
/**
* @brief get the rgbPuls field value.
*
* @return rgbPuls value.
*/
uint rgbPuls() const;
};
}
/*
*
* Created on: Mar 1, 2021
* Author: astrisw
/**
* @brief This file contains the definition of the recognizedPackets for Astri MA.
*
* The recognizedPackets vector is a static member of the inaf::oasbo::Packets::AstriMa namespace.
* It stores tuples representing recognized packets, where each tuple contains three values:
* - The first value represents the packet type.
* - The second value represents the packet subtype.
* - The third value represents the packet length.
*
*/
#pragma once
#include <vector>
......@@ -15,6 +19,5 @@ static std::vector<std::tuple<size_t, size_t, size_t>> recognizedPackets = {
std::make_tuple(1, 1, 10014), std::make_tuple(1, 4, 12980),
std::make_tuple(2, 2, 12976), std::make_tuple(10, 1, 11098),
std::make_tuple(10, 2, 9566), std::make_tuple(10, 3, 9566),
std::make_tuple(15, 1, 10)
};
std::make_tuple(15, 1, 10) };
}
/*
* PacketLib.h
*
* Created on: Nov 24, 2022
* Author: valerio
*/
#ifndef INCLUDE_INAF_OAS_PACKET_STRUCTURE_JSON_H_
#define INCLUDE_INAF_OAS_PACKET_STRUCTURE_JSON_H_
#pragma once
#include <Base_Packet.h>
#include <fstream>
......@@ -20,21 +12,53 @@ template<class K, class V, class dummy_compare, class A>
using my_workaround_fifo_map = fifo_map<K, V, fifo_map_compare<K>, A>;
using my_json = basic_json<my_workaround_fifo_map>;
namespace inaf::oasbo::Packets {
class PacketStructureJson : public inaf::oasbo::PacketLib::BasePacketStructure {
/**
* @brief Represents a JSON packet structure for ASTRI DAQ.
*
* This class extends the BasePacketStructure class and provides functionality
* to convert JSON data into a tuple vector and read the structure from a source.
* The compatible json files are in config folder.
*/
class PacketStructureJson: public inaf::oasbo::Packets::BasePacketStructure {
protected:
static std::optional<Structure> convertToTupleVector(const my_json &data, uint &count);
/**
* @brief Converts JSON data into a tuple vector.
*
* @param data The JSON data to convert.
* @param count The count of tuples in the vector.
* @return An optional structure representing the tuple vector.
*/
static std::optional<Structure> convertToTupleVector(const my_json &data,
uint &count);
/**
* @brief Reads the packet structure from a source.
*
* @param source The source from which to read the structure.
* @return The structure read from the source.
*/
static Structure readStructureFromSource(std::string source);
public:
PacketStructureJson(std::string source) : BasePacketStructure(source, &readStructureFromSource){
/**
* @brief Constructs a PacketStructureJson object with the specified source.
*
* @param source The source from which to read the structure.
*/
PacketStructureJson(std::string source) :
BasePacketStructure(source, &readStructureFromSource) {
}
PacketStructureJson(const BasePacketStructure &other) : BasePacketStructure(other){
/**
* @brief Constructs a PacketStructureJson object from another BasePacketStructure object.
*
* @param other The BasePacketStructure object to copy from.
*/
PacketStructureJson(const BasePacketStructure &other) :
BasePacketStructure(other) {
}
};
}
#endif /* INCLUDE_INAF_OAS_PACKET_STRUCTURE_JSON_H_ */
#include <Astri_Horn_Generic.h>
#include <Astri_Horn_Recognized_Packet.h>
......
#include <Astri_MA_Generic.h>
#include <Astri_MA_Recognized_Packet.h>
......@@ -21,9 +20,10 @@ uint AstriMaGeneric::getTelescopeID() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.0 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.0 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -56,9 +56,10 @@ uint AstriMaGeneric::getSSC() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.3 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.3 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -67,9 +68,10 @@ uint AstriMaGeneric::getPacketLength() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.4 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.4 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -78,9 +80,10 @@ uint AstriMaGeneric::getYear() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.5 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.5 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -89,9 +92,10 @@ uint AstriMaGeneric::getMonth() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.6 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.6 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -100,9 +104,10 @@ uint AstriMaGeneric::getDay() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.7 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.7 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -111,9 +116,10 @@ uint AstriMaGeneric::getHour() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.8 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.8 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -122,9 +128,10 @@ uint AstriMaGeneric::getMinutes() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.9 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.9 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -133,9 +140,10 @@ uint AstriMaGeneric::getSeconds() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.10 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.10 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -144,9 +152,10 @@ bool AstriMaGeneric::getValidTime() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.11 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.11 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -155,9 +164,10 @@ uint AstriMaGeneric::getTimeTagNanoseconds() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.12 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.12 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -166,9 +176,10 @@ uint AstriMaGeneric::getEventCounter() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.13 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.13 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -177,9 +188,10 @@ bool AstriMaGeneric::getLid() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.14 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.14 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -188,9 +200,10 @@ bool AstriMaGeneric::fibSt() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.15 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.15 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -199,9 +212,10 @@ bool AstriMaGeneric::fibCont() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.16 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.16 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -210,9 +224,10 @@ bool AstriMaGeneric::fibPuls() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.17 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.17 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -221,9 +236,10 @@ uint AstriMaGeneric::rgbCont() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.18 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.18 to get TelescopeID." << std::endl;
return -1;
}
}
......@@ -232,9 +248,10 @@ uint AstriMaGeneric::rgbPuls() const {
if (val.has_value())
return val.value();
else {
time_t now = time(nullptr);
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[AstriMA Packet]\t" << "Cannot access field n.19 to get TelescopeID." << std::endl;
<< "]\t[AstriMA Packet]\t"
<< "Cannot access field n.19 to get TelescopeID." << std::endl;
return -1;
}
}
......
......@@ -8,9 +8,10 @@ Structure PacketStructureJson::readStructureFromSource(std::string source) {
Structure s_empty;
std::ifstream file;
file.open(source, std::ios::in);
if (!file.is_open()) {
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") <<"]\t[PacketStructure Json]\t" << "Could not open file: "
if (!file.is_open()) { // error handling
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[PacketStructure Json]\t" << "Could not open file: "
<< source << std::endl;
std::cerr << "\t Returning empty structure" << std::endl;
return s_empty;
......@@ -20,16 +21,20 @@ Structure PacketStructureJson::readStructureFromSource(std::string source) {
try {
file >> data;
} catch (nlohmann::detail::parse_error &ex) {
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") <<"]\t[PacketStructure Json]\t" << ex.what() << "\n\t\tReturning empty structure" << std::endl;
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[PacketStructure Json]\t" << ex.what()
<< "\n\t\tReturning empty structure" << std::endl;
return s_empty;
}
std::optional<Structure> s_tmp = convertToTupleVector(data, count);
file.close();
if (s_tmp.has_value())
return s_tmp.value();
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") <<"]\t[PacketStructure Json]\t" << "Returning empty structure" << std::endl;
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[PacketStructure Json]\t" << "Returning empty structure"
<< std::endl;
return s_empty;
}
......@@ -37,16 +42,18 @@ std::optional<Structure> PacketStructureJson::convertToTupleVector(
const my_json &data, uint &count) {
std::optional<Structure> out = Structure();
for (auto it = data.begin(); it != data.end(); ++it) {
if (it.value().is_object()) {
if (it.value().find("size") == it.value().end()
|| it.value().find("fields") == it.value().end()
if (it.value().is_object()) { // array found
if (it.value().find("size") == it.value().end() // error handling
|| it.value().find("fields") == it.value().end()
|| it.value().size() != 2) {
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") <<"]\t[PacketStructure Json]\t" << "Error in file: "
time_t now = time(nullptr);
std::cerr << "["
<< std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[PacketStructure Json]\t" << "Error in file: "
<< it.value().dump() << std::endl;
return std::nullopt;
}
for (uint i = 0; i < it.value()["size"]; i++) {
for (uint i = 0; i < it.value()["size"]; i++) { // convert to tuple vector the json array
std::optional<Structure> subArray = convertToTupleVector(
it.value()["fields"], count).value();
if (!subArray.has_value())
......@@ -59,10 +66,12 @@ std::optional<Structure> PacketStructureJson::convertToTupleVector(
out.value().insert(out.value().end(), subArray.value().begin(),
subArray.value().end());
}
} else {
if (!it.value().is_number_integer()) {
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S") <<"]\t[PacketStructure Json]\t" << "Not an int: "
} else { // single field found
if (!it.value().is_number_integer()) { // error handling
time_t now = time(nullptr);
std::cerr << "["
<< std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[PacketStructure Json]\t" << "Not an int: "
<< it.value().dump() << std::endl;
return std::nullopt;
}
......