UniRec  3.3.1
bidirectionalInterface.cpp
Go to the documentation of this file.
1 
11 
12 #include <libtrap/trap.h>
13 
14 namespace Nemea {
15 
17  uint8_t inputInterfaceID,
18  uint8_t outputInterfaceID)
19  : m_template(nullptr)
20  , m_inputInterfaceID(inputInterfaceID)
21  , m_outputInterfaceID(outputInterfaceID)
22  , m_sequenceNumber(0)
23  , m_prioritizedDataPointer(nullptr)
24  , m_sendEoFonExit(true)
25  , m_isInitialized(false)
26 {
28 }
29 
31 {
33  sendEoF();
34  }
35 
37 }
38 
39 std::optional<UnirecRecordView> UnirecBidirectionalInterface::receive()
40 {
41  const void* receivedData;
42  uint16_t dataSize = 0;
43 
45  receivedData = m_prioritizedDataPointer;
46  m_prioritizedDataPointer = nullptr;
47  return UnirecRecordView(receivedData, m_template, m_sequenceNumber);
48  }
49 
50  int errorCode = trap_recv_with_seq_number(m_inputInterfaceID, &receivedData, &dataSize, &m_sequenceNumber);
51  if (errorCode == TRAP_E_TIMEOUT) {
52  return std::nullopt;
53  }
54  if (errorCode == TRAP_E_FORMAT_CHANGED) {
55  m_prioritizedDataPointer = receivedData;
56  throw FormatChangeException();
57  }
58  handleReceiveErrorCodes(errorCode);
59 
60  if (dataSize <= 1) {
61  throw EoFException();
62  }
63 
64  return UnirecRecordView(receivedData, m_template, m_sequenceNumber);
65 }
66 
68 {
69  if (errorCode == TRAP_E_OK) {
70  return;
71  }
72  if (errorCode == TRAP_E_NOT_INITIALIZED) {
73  throw std::runtime_error(
74  "UnirecBidirectionalInterface::receive() has failed. Trap interface is not "
75  "initialized.");
76  }
77  if (errorCode == TRAP_E_TERMINATED) {
78  throw std::runtime_error(
79  "UnirecBidirectionalInterface::receive() has failed. Trap interface is terminated.");
80  }
81  if (errorCode == TRAP_E_NOT_SELECTED) {
82  throw std::runtime_error(
83  "UnirecBidirectionalInterface::receive() has failed. Interface ID out of range.");
84  }
85  throw std::runtime_error(
86  "UnirecBidirectionalInterface::receive() has failed. Return code: "
87  + std::to_string(errorCode) + ", msg: " + trap_last_error_msg);
88 }
89 
90 void UnirecBidirectionalInterface::setRequieredFormat(const std::string& templateSpecification)
91 {
92  int ret = trap_set_required_fmt(m_inputInterfaceID, TRAP_FMT_UNIREC, templateSpecification.c_str());
93  if (ret != TRAP_E_OK) {
94  throw std::runtime_error(
95  "UnirecBidirectionalInterface::setRequieredFormat() has failed. Unable to set required "
96  "format.");
97  }
98 
99  if (templateSpecification.empty()) {
100  return;
101  }
102 
103  changeInternalTemplate(templateSpecification);
104 }
105 
106 void UnirecBidirectionalInterface::changeInternalTemplate(const std::string& templateSpecification)
107 {
108  m_template = ur_define_fields_and_update_template(templateSpecification.c_str(), m_template);
109  if (m_template == nullptr) {
110  throw std::runtime_error(
111  "UnirecBidirectionalInterface::changeTemplate() has failed. Template could not be "
112  "edited.");
113  }
114 
115  trap_set_data_fmt(m_outputInterfaceID, TRAP_FMT_UNIREC, templateSpecification.c_str());
116 
118  if (ret != TRAP_E_OK) {
119  throw std::runtime_error("UnirecBidirectionalInterface::changeTemplate() has failed.");
120  }
121 
123  if (ret != TRAP_E_OK) {
124  throw std::runtime_error("UnirecBidirectionalInterface::changeTemplate() has failed.");
125  }
126 
128 
129  m_isInitialized = true;
130 }
131 
133 {
134  uint8_t dataType;
135  const char* spec = nullptr;
136 
137  int ret = trap_get_data_fmt(TRAPIFC_INPUT, m_inputInterfaceID, &dataType, &spec);
138  if (ret != TRAP_E_OK) {
139  throw std::runtime_error(
140  "UnirecBidirectionalInterface::changeTemplate() has failed. Data format was not "
141  "loaded.");
142  }
143 
145 }
146 
148 {
149  trap_ifcctl(TRAPIFC_INPUT, m_inputInterfaceID, TRAPCTL_SETTIMEOUT, timeout);
150 }
151 
153 {
154  return UnirecRecord(m_template, maxVariableFieldsSize);
155 }
156 
158 {
159  int errorCode = trap_send(m_outputInterfaceID, unirecRecord.data(), unirecRecord.size());
160  return handleSendErrorCodes(errorCode);
161 }
162 
164 {
165  int errorCode
166  = trap_send(m_outputInterfaceID, unirecRecordView.data(), unirecRecordView.size());
167  return handleSendErrorCodes(errorCode);
168 }
169 
171 {
172  if (errorCode == TRAP_E_TIMEOUT) {
173  return false;
174  }
175  if (errorCode == TRAP_E_OK) {
176  return true;
177  }
178  if (errorCode == TRAP_E_NOT_INITIALIZED) {
179  throw std::runtime_error(
180  "UnirecBidirectionalInterface::send() has failed. Trap interface is not initialized.");
181  }
182  if (errorCode == TRAP_E_TERMINATED) {
183  throw std::runtime_error(
184  "UnirecBidirectionalInterface::send() has failed. Trap interface is terminated.");
185  }
186  if (errorCode == TRAP_E_BAD_IFC_INDEX) {
187  throw std::runtime_error(
188  "UnirecBidirectionalInterface::send() has failed. Interface ID out of range.");
189  }
190  throw std::runtime_error(
191  "UnirecBidirectionalInterface::send() has failed. Return code: " + std::to_string(errorCode)
192  + ", msg: " + trap_last_error_msg);
193 }
194 
196 {
197  trap_send_flush(m_outputInterfaceID);
198 }
199 
201 {
202  m_sendEoFonExit = false;
203 }
204 
206 {
207  trap_ifcctl(TRAPIFC_OUTPUT, m_outputInterfaceID, TRAPCTL_SETTIMEOUT, timeout);
208 }
209 
211 {
212  trap_ifcctl(TRAPIFC_OUTPUT, m_outputInterfaceID, TRAPCTL_AUTOFLUSH_TIMEOUT, timeout);
213 }
214 
216 {
217  char dummy[1] = { 0 };
218  trap_send(m_outputInterfaceID, dummy, sizeof(dummy));
219 }
220 
222 {
223  InputInteraceStats inputStats;
224 
225  struct input_ifc_stats ifcStats = {};
226  trap_get_input_ifc_stats(m_inputInterfaceID, &ifcStats);
227 
228  inputStats.receivedBytes = ifcStats.received_bytes;
229  inputStats.receivedRecords = ifcStats.received_records;
230  inputStats.missedRecords = ifcStats.missed_records;
231  return inputStats;
232 }
233 
234 } // namespace Nemea
Defines a bidirectional interface for sending and receiving unirec records using the TRAP interface p...
An exception that is thrown when the end of the input stream is reached.
An exception that is thrown when the record format changes.
void setSendAutoflushTimeout(int timeout)
Sets the autoflush timeout for the output Trap interface.
~UnirecBidirectionalInterface()
Destructor for the UnirecBidirectionalInterface class.
bool handleSendErrorCodes(int errorCode) const
void handleReceiveErrorCodes(int errorCode) const
void sendFlush() const
Flushes any pending UniRec records in the Trap interface.
void changeTemplate()
Changes the Unirec template used by the bidirectional interface.
void changeInternalTemplate(const std::string &templateSpecification)
InputInteraceStats getInputInterfaceStats() const
Gets the statistics for the input interface.
void setReceiveTimeout(int timeout)
Sets the receive timeout for the interface. This method sets the timeout for receiving UniRec records...
UnirecRecord createUnirecRecord(size_t maxVariableFieldsSize=UR_MAX_SIZE)
Creates a new UniRec record with the specified maximum variable fields size.
void doNotsendEoFOnExit()
Disables sending an end-of-file marker on exit.
void setSendTimeout(int timeout)
Sets the send timeout for the Trap interface.
std::optional< UnirecRecordView > receive()
Receives data from the interface and returns an optional UnirecRecordView object.
void setRequieredFormat(const std::string &templateSpecification)
Sets the required Unirec format specification.
bool send(UnirecRecord &unirecRecord) const
Sends a UniRec record through the Trap interface.
UnirecBidirectionalInterface(uint8_t inputInterfaceID, uint8_t outputInterfaceID)
Provides a view into a UniRec record.
size_t size() const noexcept
Returns the size of the UniRec record.
const void * data() const noexcept
Returns a const pointer to the data of the UniRec record.
A class for working with UniRec records and their fields.
const void * data() const noexcept
Returns a pointer to the data of the UniRec record.
size_t size() const noexcept
Returns the size of the UniRec record.
ur_template_t * ur_define_fields_and_update_template(const char *ifc_data_fmt, ur_template_t *tmplt)
Defined new fields and expand an UniRec template Define new fields (function ur_define_set_of_fields)...
Definition: unirec.c:616
#define ur_set_output_template(ifc, tmplt)
Set UniRec template to ouput interface.
Definition: unirec.h:847
void ur_free_template(ur_template_t *tmplt)
Destroy UniRec template Free all memory allocated for a template created previously by ur_create_temp...
Definition: unirec.c:1094
#define ur_set_input_template(ifc, tmplt)
Set UniRec template to input interface.
Definition: unirec.h:863
Structure to store statistics related to an input interface.