mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
fix code formatting
Remove "this->" and add spaces behind commata.
This commit is contained in:
parent
1b253ad43c
commit
2bea88043d
1 changed files with 82 additions and 112 deletions
|
@ -39,7 +39,7 @@ CP56Time2a timespec_to_cp56time2a(timespec time) {
|
|||
time_t time_ms =
|
||||
static_cast<time_t> (time.tv_sec) * 1000
|
||||
+ static_cast<time_t> (time.tv_nsec) / 1000000;
|
||||
return CP56Time2a_createFromMsTimestamp(NULL,time_ms);
|
||||
return CP56Time2a_createFromMsTimestamp(NULL, time_ms);
|
||||
}
|
||||
|
||||
timespec cp56time2a_to_timespec(CP56Time2a cp56time2a) {
|
||||
|
@ -50,10 +50,6 @@ timespec cp56time2a_to_timespec(CP56Time2a cp56time2a) {
|
|||
return time;
|
||||
}
|
||||
|
||||
// ------------------------------------------
|
||||
// ASDUDataType
|
||||
// ------------------------------------------
|
||||
|
||||
ASDUData ASDUData::parse(json_t *signal_json) {
|
||||
json_error_t err;
|
||||
char const *asdu_type_name = nullptr;
|
||||
|
@ -94,7 +90,7 @@ ASDUData ASDUData::parse(json_t *signal_json) {
|
|||
std::optional<ASDUData> ASDUData::lookupTypeId(char const *type_id, int ioa)
|
||||
{
|
||||
auto check = [type_id] (Descriptor descriptor) {
|
||||
return !strcmp(descriptor.type_id,type_id);
|
||||
return !strcmp(descriptor.type_id, type_id);
|
||||
};
|
||||
auto descriptor = std::find_if(begin(descriptors), end(descriptors), check);
|
||||
if (descriptor != end(descriptors)) {
|
||||
|
@ -106,8 +102,8 @@ std::optional<ASDUData> ASDUData::lookupTypeId(char const *type_id, int ioa)
|
|||
|
||||
std::optional<ASDUData> ASDUData::lookupName(char const *name, bool with_timestamp, int ioa)
|
||||
{
|
||||
auto check = [name,with_timestamp] (Descriptor descriptor) {
|
||||
return !strcmp(descriptor.name,name) && descriptor.has_timestamp == with_timestamp;
|
||||
auto check = [name, with_timestamp] (Descriptor descriptor) {
|
||||
return !strcmp(descriptor.name, name) && descriptor.has_timestamp == with_timestamp;
|
||||
};
|
||||
auto descriptor = std::find_if(begin(descriptors), end(descriptors), check);
|
||||
if (descriptor != end(descriptors)) {
|
||||
|
@ -132,52 +128,51 @@ std::optional<ASDUData> ASDUData::lookupType(int type, int ioa)
|
|||
|
||||
bool ASDUData::hasTimestamp() const
|
||||
{
|
||||
return this->descriptor.has_timestamp;
|
||||
return descriptor.has_timestamp;
|
||||
}
|
||||
|
||||
ASDUData::Type ASDUData::type() const
|
||||
{
|
||||
return this->descriptor.type;
|
||||
return descriptor.type;
|
||||
}
|
||||
|
||||
|
||||
char const * ASDUData::name() const {
|
||||
return this->descriptor.name;
|
||||
return descriptor.name;
|
||||
}
|
||||
|
||||
ASDUData::Type ASDUData::typeWithoutTimestamp() const
|
||||
{
|
||||
return this->descriptor.type_without_timestamp;
|
||||
return descriptor.type_without_timestamp;
|
||||
}
|
||||
|
||||
ASDUData ASDUData::withoutTimestamp() const
|
||||
{
|
||||
return ASDUData::lookupType(this->typeWithoutTimestamp(), this->ioa).value();
|
||||
return ASDUData::lookupType(typeWithoutTimestamp(), ioa).value();
|
||||
}
|
||||
|
||||
SignalType ASDUData::signalType() const
|
||||
{
|
||||
return this->descriptor.signal_type;
|
||||
return descriptor.signal_type;
|
||||
}
|
||||
|
||||
std::optional<ASDUData::Sample> ASDUData::checkASDU(CS101_ASDU const &asdu) const
|
||||
{
|
||||
if (CS101_ASDU_getTypeID(asdu) != static_cast<int> (this->descriptor.type)) {
|
||||
if (CS101_ASDU_getTypeID(asdu) != static_cast<int> (descriptor.type)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
for (int i = 0; i < CS101_ASDU_getNumberOfElements(asdu); i++) {
|
||||
InformationObject io = CS101_ASDU_getElement(asdu, i);
|
||||
int ioa = InformationObject_getObjectAddress(io);
|
||||
|
||||
if (ioa != this->ioa) {
|
||||
if (ioa != InformationObject_getObjectAddress(io)) {
|
||||
InformationObject_destroy(io);
|
||||
continue;
|
||||
}
|
||||
|
||||
SignalData signal_data;
|
||||
QualityDescriptor quality;
|
||||
switch (this->typeWithoutTimestamp()) {
|
||||
switch (typeWithoutTimestamp()) {
|
||||
case ASDUData::SCALED_INT: {
|
||||
auto scaled = reinterpret_cast<MeasuredValueScaled> (io);
|
||||
int value = MeasuredValueScaled_getValue(scaled);
|
||||
|
@ -212,7 +207,7 @@ std::optional<ASDUData::Sample> ASDUData::checkASDU(CS101_ASDU const &asdu) cons
|
|||
}
|
||||
|
||||
std::optional<CP56Time2a> time_cp56;
|
||||
switch (this->type()) {
|
||||
switch (type()) {
|
||||
case ASDUData::SCALED_INT_WITH_TIMESTAMP: {
|
||||
auto scaled = reinterpret_cast<MeasuredValueScaledWithCP56Time2a> (io);
|
||||
time_cp56 = MeasuredValueScaledWithCP56Time2a_getTimestamp(scaled);
|
||||
|
@ -255,55 +250,55 @@ bool ASDUData::addSampleToASDU(CS101_ASDU &asdu, ASDUData::Sample sample) const
|
|||
: std::nullopt;
|
||||
|
||||
InformationObject io;
|
||||
switch (this->descriptor.type) {
|
||||
switch (descriptor.type) {
|
||||
case ASDUData::SCALED_INT: {
|
||||
auto value = static_cast<int16_t> (sample.signal_data.i & 0xFFFF);
|
||||
auto scaled = MeasuredValueScaled_create(NULL,this->ioa,value,sample.quality);
|
||||
auto scaled = MeasuredValueScaled_create(NULL, ioa, value, sample.quality);
|
||||
io = reinterpret_cast<InformationObject> (scaled);
|
||||
} break;
|
||||
case ASDUData::NORMALIZED_FLOAT: {
|
||||
auto value = static_cast<float> (sample.signal_data.f);
|
||||
auto normalized = MeasuredValueNormalized_create(NULL,this->ioa,value,sample.quality);
|
||||
auto normalized = MeasuredValueNormalized_create(NULL, ioa, value, sample.quality);
|
||||
io = reinterpret_cast<InformationObject> (normalized);
|
||||
} break;
|
||||
case ASDUData::DOUBLE_POINT: {
|
||||
auto value = static_cast<DoublePointValue> (sample.signal_data.i & 0x3);
|
||||
auto double_point = DoublePointInformation_create(NULL,this->ioa,value,sample.quality);
|
||||
auto double_point = DoublePointInformation_create(NULL, ioa, value, sample.quality);
|
||||
io = reinterpret_cast<InformationObject> (double_point);
|
||||
} break;
|
||||
case ASDUData::SINGLE_POINT: {
|
||||
auto value = sample.signal_data.b;
|
||||
auto single_point = SinglePointInformation_create(NULL,this->ioa,value,sample.quality);
|
||||
auto single_point = SinglePointInformation_create(NULL, ioa, value, sample.quality);
|
||||
io = reinterpret_cast<InformationObject> (single_point);
|
||||
} break;
|
||||
case ASDUData::SHORT_FLOAT: {
|
||||
auto value = static_cast<float> (sample.signal_data.f);
|
||||
auto short_float = MeasuredValueShort_create(NULL,this->ioa,value,sample.quality);
|
||||
auto short_float = MeasuredValueShort_create(NULL, ioa, value, sample.quality);
|
||||
io = reinterpret_cast<InformationObject> (short_float);
|
||||
} break;
|
||||
case ASDUData::SCALED_INT_WITH_TIMESTAMP: {
|
||||
auto value = static_cast<int16_t> (sample.signal_data.i & 0xFFFF);
|
||||
auto scaled = MeasuredValueScaledWithCP56Time2a_create(NULL,this->ioa,value,sample.quality,timestamp.value());
|
||||
auto scaled = MeasuredValueScaledWithCP56Time2a_create(NULL, ioa, value, sample.quality, timestamp.value());
|
||||
io = reinterpret_cast<InformationObject> (scaled);
|
||||
} break;
|
||||
case ASDUData::NORMALIZED_FLOAT_WITH_TIMESTAMP: {
|
||||
auto value = static_cast<float> (sample.signal_data.f);
|
||||
auto normalized = MeasuredValueNormalizedWithCP56Time2a_create(NULL,this->ioa,value,sample.quality,timestamp.value());
|
||||
auto normalized = MeasuredValueNormalizedWithCP56Time2a_create(NULL, ioa, value, sample.quality, timestamp.value());
|
||||
io = reinterpret_cast<InformationObject> (normalized);
|
||||
} break;
|
||||
case ASDUData::DOUBLE_POINT_WITH_TIMESTAMP: {
|
||||
auto value = static_cast<DoublePointValue> (sample.signal_data.i & 0x3);
|
||||
auto double_point = DoublePointWithCP56Time2a_create(NULL,this->ioa,value,sample.quality,timestamp.value());
|
||||
auto double_point = DoublePointWithCP56Time2a_create(NULL, ioa, value, sample.quality, timestamp.value());
|
||||
io = reinterpret_cast<InformationObject> (double_point);
|
||||
} break;
|
||||
case ASDUData::SINGLE_POINT_WITH_TIMESTAMP: {
|
||||
auto value = sample.signal_data.b;
|
||||
auto single_point = SinglePointWithCP56Time2a_create(NULL,this->ioa,value,sample.quality,timestamp.value());
|
||||
auto single_point = SinglePointWithCP56Time2a_create(NULL, ioa, value, sample.quality, timestamp.value());
|
||||
io = reinterpret_cast<InformationObject> (single_point);
|
||||
} break;
|
||||
case ASDUData::SHORT_FLOAT_WITH_TIMESTAMP: {
|
||||
auto value = static_cast<float> (sample.signal_data.f);
|
||||
auto short_float = MeasuredValueShortWithCP56Time2a_create(NULL,this->ioa,value,sample.quality,timestamp.value());
|
||||
auto short_float = MeasuredValueShortWithCP56Time2a_create(NULL, ioa, value, sample.quality, timestamp.value());
|
||||
io = reinterpret_cast<InformationObject> (short_float);
|
||||
} break;
|
||||
default: assert(!"unreachable");
|
||||
|
@ -316,19 +311,13 @@ bool ASDUData::addSampleToASDU(CS101_ASDU &asdu, ASDUData::Sample sample) const
|
|||
ASDUData::ASDUData(ASDUData::Descriptor const &descriptor, int ioa) : ioa(ioa), descriptor(descriptor)
|
||||
{}
|
||||
|
||||
// ------------------------------------------
|
||||
// SlaveNode
|
||||
// ------------------------------------------
|
||||
|
||||
void SlaveNode::createSlave() noexcept
|
||||
{
|
||||
auto &server = this->server;
|
||||
|
||||
// destroy slave id it was already created
|
||||
this->destroySlave();
|
||||
destroySlave();
|
||||
|
||||
// create the slave object
|
||||
server.slave = CS104_Slave_create(server.low_priority_queue,server.high_priority_queue);
|
||||
server.slave = CS104_Slave_create(server.low_priority_queue, server.high_priority_queue);
|
||||
CS104_Slave_setServerMode(server.slave, CS104_MODE_SINGLE_REDUNDANCY_GROUP);
|
||||
|
||||
// configure the slave according to config
|
||||
|
@ -348,27 +337,27 @@ void SlaveNode::createSlave() noexcept
|
|||
// setup callbacks into the class
|
||||
CS104_Slave_setClockSyncHandler(server.slave, [] (void *tcp_node, IMasterConnection connection, CS101_ASDU asdu, CP56Time2a new_time) {
|
||||
auto self = static_cast<SlaveNode const *> (tcp_node);
|
||||
return self->onClockSync(connection,asdu,new_time);
|
||||
return self->onClockSync(connection, asdu, new_time);
|
||||
}, this);
|
||||
|
||||
CS104_Slave_setInterrogationHandler(server.slave, [] (void *tcp_node, IMasterConnection connection, CS101_ASDU asdu, QualifierOfInterrogation qoi) {
|
||||
auto self = static_cast<SlaveNode const *> (tcp_node);
|
||||
return self->onInterrogation(connection,asdu,qoi);
|
||||
return self->onInterrogation(connection, asdu, qoi);
|
||||
}, this);
|
||||
|
||||
CS104_Slave_setASDUHandler(server.slave, [] (void *tcp_node, IMasterConnection connection, CS101_ASDU asdu) {
|
||||
auto self = static_cast<SlaveNode const *> (tcp_node);
|
||||
return self->onASDU(connection,asdu);
|
||||
return self->onASDU(connection, asdu);
|
||||
}, this);
|
||||
|
||||
CS104_Slave_setConnectionEventHandler(server.slave, [](void *tcp_node, IMasterConnection connection, CS104_PeerConnectionEvent event){
|
||||
auto self = static_cast<SlaveNode const *> (tcp_node);
|
||||
self->debugPrintConnection(connection,event);
|
||||
self->debugPrintConnection(connection, event);
|
||||
}, this);
|
||||
|
||||
CS104_Slave_setRawMessageHandler(server.slave, [](void *tcp_node, IMasterConnection connection, uint8_t *message, int message_size, bool sent){
|
||||
auto self = static_cast<SlaveNode const *> (tcp_node);
|
||||
self->debugPrintMessage(connection,message,message_size,sent);
|
||||
self->debugPrintMessage(connection, message, message_size, sent);
|
||||
}, this);
|
||||
|
||||
server.state = SlaveNode::Server::READY;
|
||||
|
@ -376,13 +365,11 @@ void SlaveNode::createSlave() noexcept
|
|||
|
||||
void SlaveNode::destroySlave() noexcept
|
||||
{
|
||||
auto &server = this->server;
|
||||
|
||||
if (server.state == SlaveNode::Server::NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->stopSlave();
|
||||
stopSlave();
|
||||
|
||||
CS104_Slave_destroy(server.slave);
|
||||
server.state = SlaveNode::Server::NONE;
|
||||
|
@ -390,12 +377,10 @@ void SlaveNode::destroySlave() noexcept
|
|||
|
||||
void SlaveNode::startSlave() noexcept(false)
|
||||
{
|
||||
auto &server = this->server;
|
||||
|
||||
if (server.state == SlaveNode::Server::NONE) {
|
||||
this->createSlave();
|
||||
createSlave();
|
||||
} else {
|
||||
this->stopSlave();
|
||||
stopSlave();
|
||||
}
|
||||
|
||||
server.state = SlaveNode::Server::READY;
|
||||
|
@ -409,8 +394,6 @@ void SlaveNode::startSlave() noexcept(false)
|
|||
|
||||
void SlaveNode::stopSlave() noexcept
|
||||
{
|
||||
auto &server = this->server;
|
||||
|
||||
if (server.state != SlaveNode::Server::READY || !CS104_Slave_isRunning(server.slave)) {
|
||||
return;
|
||||
}
|
||||
|
@ -418,7 +401,7 @@ void SlaveNode::stopSlave() noexcept
|
|||
server.state = SlaveNode::Server::STOPPED;
|
||||
|
||||
if (CS104_Slave_getNumberOfQueueEntries(server.slave, NULL) != 0)
|
||||
this->logger->info("waiting for last messages in queue");
|
||||
logger->info("waiting for last messages in queue");
|
||||
// wait for all messages to be send before really stopping
|
||||
while ( (CS104_Slave_getNumberOfQueueEntries(server.slave, NULL) != 0) &&
|
||||
(CS104_Slave_getOpenConnections(server.slave) != 0)) {
|
||||
|
@ -437,56 +420,52 @@ void SlaveNode::debugPrintConnection(IMasterConnection connection, CS104_PeerCon
|
|||
{
|
||||
switch (event) {
|
||||
case CS104_CON_EVENT_CONNECTION_OPENED: {
|
||||
this->logger->info("client connected");
|
||||
logger->info("client connected");
|
||||
} break;
|
||||
case CS104_CON_EVENT_CONNECTION_CLOSED: {
|
||||
this->logger->info("client disconnected");
|
||||
logger->info("client disconnected");
|
||||
} break;
|
||||
case CS104_CON_EVENT_ACTIVATED: {
|
||||
this->logger->info("connection activated");
|
||||
logger->info("connection activated");
|
||||
} break;
|
||||
case CS104_CON_EVENT_DEACTIVATED: {
|
||||
this->logger->info("connection closed");
|
||||
logger->info("connection closed");
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
bool SlaveNode::onClockSync(IMasterConnection connection, CS101_ASDU asdu, CP56Time2a new_time) const noexcept
|
||||
{
|
||||
this->logger->warn("received clock sync command (unimplemented)");
|
||||
logger->warn("received clock sync command (unimplemented)");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SlaveNode::onInterrogation(IMasterConnection connection, CS101_ASDU asdu, QualifierOfInterrogation qoi) const noexcept
|
||||
{
|
||||
auto &mapping = this->output.mapping;
|
||||
auto &last_values = this->output.last_values;
|
||||
auto &asdu_types = this->output.asdu_types;
|
||||
|
||||
switch (qoi) {
|
||||
// send last values without timestamps
|
||||
case IEC60870_QOI_STATION: {
|
||||
IMasterConnection_sendACT_CON(connection, asdu, false);
|
||||
|
||||
this->logger->debug("received general interrogation");
|
||||
logger->debug("received general interrogation");
|
||||
|
||||
auto guard = std::lock_guard { this->output.last_values_mutex };
|
||||
auto guard = std::lock_guard { output.last_values_mutex };
|
||||
|
||||
for(auto asdu_type : asdu_types) {
|
||||
for (unsigned i = 0; i < mapping.size();) {
|
||||
for(auto const &asdu_type : output.asdu_types) {
|
||||
for (unsigned i = 0; i < output.mapping.size();) {
|
||||
auto signal_asdu = CS101_ASDU_create(
|
||||
IMasterConnection_getApplicationLayerParameters(connection),
|
||||
false,
|
||||
CS101_COT_INTERROGATED_BY_STATION,
|
||||
0,
|
||||
this->server.common_address,
|
||||
server.common_address,
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
do {
|
||||
auto asdu_data = mapping[i].withoutTimestamp();
|
||||
auto last_value = last_values[i];
|
||||
auto asdu_data = output.mapping[i].withoutTimestamp();
|
||||
auto last_value = output.last_values[i];
|
||||
|
||||
if (asdu_data.type() != asdu_type)
|
||||
continue;
|
||||
|
@ -497,7 +476,7 @@ bool SlaveNode::onInterrogation(IMasterConnection connection, CS101_ASDU asdu, Q
|
|||
std::nullopt
|
||||
}) == false)
|
||||
break;
|
||||
} while (++i < mapping.size());
|
||||
} while (++i < output.mapping.size());
|
||||
|
||||
IMasterConnection_sendASDU(connection, signal_asdu);
|
||||
|
||||
|
@ -510,7 +489,7 @@ bool SlaveNode::onInterrogation(IMasterConnection connection, CS101_ASDU asdu, Q
|
|||
// negative acknowledgement
|
||||
default:
|
||||
IMasterConnection_sendACT_CON(connection, asdu, true);
|
||||
this->logger->warn("ignoring interrogation type {}", qoi);
|
||||
logger->warn("ignoring interrogation type {}", qoi);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -518,31 +497,29 @@ bool SlaveNode::onInterrogation(IMasterConnection connection, CS101_ASDU asdu, Q
|
|||
|
||||
bool SlaveNode::onASDU(IMasterConnection connection, CS101_ASDU asdu) const noexcept
|
||||
{
|
||||
this->logger->warn("ignoring asdu type {}", CS101_ASDU_getTypeID(asdu));
|
||||
logger->warn("ignoring asdu type {}", CS101_ASDU_getTypeID(asdu));
|
||||
return true;
|
||||
}
|
||||
|
||||
void SlaveNode::sendPeriodicASDUsForSample(Sample const *sample) const noexcept(false)
|
||||
{
|
||||
auto &mapping = this->output.mapping;
|
||||
|
||||
// ASDUs may only carry one type of asdu
|
||||
for (auto& type : this->output.asdu_types) {
|
||||
for (auto const &type : output.asdu_types) {
|
||||
// search all occurences of this ASDU type
|
||||
for (unsigned signal = 0; signal < MIN(sample->length, mapping.size());) {
|
||||
for (unsigned signal = 0; signal < MIN(sample->length, output.mapping.size());) {
|
||||
// create an ASDU for periodic transimission
|
||||
CS101_ASDU asdu = CS101_ASDU_create(
|
||||
this->server.asdu_app_layer_parameters,
|
||||
server.asdu_app_layer_parameters,
|
||||
0,
|
||||
CS101_COT_PERIODIC,
|
||||
0,
|
||||
this->server.common_address,
|
||||
server.common_address,
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
do {
|
||||
auto &asdu_data = mapping[signal];
|
||||
auto &asdu_data = output.mapping[signal];
|
||||
|
||||
// this signal_data does not belong in this ASDU
|
||||
if (asdu_data.type() != type)
|
||||
|
@ -555,10 +532,10 @@ void SlaveNode::sendPeriodicASDUsForSample(Sample const *sample) const noexcept(
|
|||
if (asdu_data.hasTimestamp() && !timestamp.has_value())
|
||||
throw RuntimeError("Received sample without timestamp for ASDU type with mandatory timestamp");
|
||||
|
||||
if (asdu_data.signalType() != sample_format(sample,signal))
|
||||
if (asdu_data.signalType() != sample_format(sample, signal))
|
||||
throw RuntimeError("Expected signal type {}, but received {}",
|
||||
signalTypeToString(asdu_data.signalType()),
|
||||
signalTypeToString(sample_format(sample,signal))
|
||||
signalTypeToString(sample_format(sample, signal))
|
||||
);
|
||||
|
||||
if (asdu_data.addSampleToASDU(asdu, ASDUData::Sample {
|
||||
|
@ -568,10 +545,10 @@ void SlaveNode::sendPeriodicASDUsForSample(Sample const *sample) const noexcept(
|
|||
}) == false)
|
||||
// ASDU is full -> dispatch -> create a new one
|
||||
break;
|
||||
} while (++signal < MIN(sample->length, mapping.size()));
|
||||
} while (++signal < MIN(sample->length, output.mapping.size()));
|
||||
|
||||
if (CS101_ASDU_getNumberOfElements(asdu) != 0)
|
||||
CS104_Slave_enqueueASDU(this->server.slave, asdu);
|
||||
CS104_Slave_enqueueASDU(server.slave, asdu);
|
||||
|
||||
CS101_ASDU_destroy(asdu);
|
||||
}
|
||||
|
@ -580,20 +557,20 @@ void SlaveNode::sendPeriodicASDUsForSample(Sample const *sample) const noexcept(
|
|||
|
||||
int SlaveNode::_write(Sample *samples[], unsigned sample_count)
|
||||
{
|
||||
if (this->server.state != SlaveNode::Server::READY)
|
||||
if (server.state != SlaveNode::Server::READY)
|
||||
return -1;
|
||||
|
||||
for (unsigned sample_index = 0; sample_index < sample_count; sample_index++) {
|
||||
Sample const *sample = samples[sample_index];
|
||||
|
||||
// update last_values
|
||||
this->output.last_values_mutex.lock();
|
||||
for (unsigned i = 0; i < MIN(sample->length, this->output.last_values.size()); i++) {
|
||||
this->output.last_values[i] = sample->data[i];
|
||||
output.last_values_mutex.lock();
|
||||
for (unsigned i = 0; i < MIN(sample->length, output.last_values.size()); i++) {
|
||||
output.last_values[i] = sample->data[i];
|
||||
}
|
||||
this->output.last_values_mutex.unlock();
|
||||
output.last_values_mutex.unlock();
|
||||
|
||||
this->sendPeriodicASDUsForSample(sample);
|
||||
sendPeriodicASDUsForSample(sample);
|
||||
}
|
||||
|
||||
return sample_count;
|
||||
|
@ -606,45 +583,43 @@ SlaveNode::SlaveNode(const std::string &name) :
|
|||
|
||||
SlaveNode::~SlaveNode()
|
||||
{
|
||||
this->destroySlave();
|
||||
destroySlave();
|
||||
}
|
||||
|
||||
int SlaveNode::parse(json_t *json, const uuid_t sn_uuid)
|
||||
{
|
||||
{
|
||||
int ret = Node::parse(json,sn_uuid);
|
||||
int ret = Node::parse(json, sn_uuid);
|
||||
if (ret) return ret;
|
||||
}
|
||||
|
||||
json_error_t err;
|
||||
auto signals = this->getOutputSignals();
|
||||
auto signals = getOutputSignals();
|
||||
|
||||
json_t *out_json = nullptr;
|
||||
char const *address = nullptr;
|
||||
if(json_unpack_ex(json, &err, 0, "{ s?: o, s?: s, s?: i, s?: i, s?: i, s?: i }",
|
||||
"out", &out_json,
|
||||
"address", &address,
|
||||
"port", &this->server.local_port,
|
||||
"ca", &this->server.common_address,
|
||||
"low_priority_queue", &this->server.low_priority_queue,
|
||||
"high_priority_queue", &this->server.high_priority_queue
|
||||
"port", &server.local_port,
|
||||
"ca", &server.common_address,
|
||||
"low_priority_queue", &server.low_priority_queue,
|
||||
"high_priority_queue", &server.high_priority_queue
|
||||
))
|
||||
throw ConfigError(json, err, "node-config-node-iec60870-5-104");
|
||||
|
||||
if (address)
|
||||
this->server.local_address = address;
|
||||
server.local_address = address;
|
||||
|
||||
json_t *signals_json = nullptr;
|
||||
if (out_json) {
|
||||
this->output.enabled = true;
|
||||
output.enabled = true;
|
||||
if(json_unpack_ex(out_json, &err, 0, "{ s: o }",
|
||||
"signals", &signals_json
|
||||
))
|
||||
throw ConfigError(out_json, err, "node-config-node-iec60870-5-104");
|
||||
}
|
||||
|
||||
auto &mapping = this->output.mapping;
|
||||
auto &last_values = this->output.last_values;
|
||||
if (signals_json) {
|
||||
json_t *signal_json;
|
||||
size_t i;
|
||||
|
@ -674,15 +649,14 @@ int SlaveNode::parse(json_t *json, const uuid_t sn_uuid)
|
|||
} else {
|
||||
initial_value.f = 0.0;
|
||||
}
|
||||
mapping.push_back(asdu_data);
|
||||
last_values.push_back(initial_value);
|
||||
output.mapping.push_back(asdu_data);
|
||||
output.last_values.push_back(initial_value);
|
||||
}
|
||||
}
|
||||
|
||||
auto& asdu_types = this->output.asdu_types;
|
||||
for (auto& asdu_data : mapping) {
|
||||
if (std::find(begin(asdu_types),end(asdu_types),asdu_data.type()) == end(asdu_types))
|
||||
asdu_types.push_back(asdu_data.type());
|
||||
for (auto const &asdu_data : output.mapping) {
|
||||
if (std::find(begin(output.asdu_types), end(output.asdu_types), asdu_data.type()) == end(output.asdu_types))
|
||||
output.asdu_types.push_back(asdu_data.type());
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -690,20 +664,16 @@ int SlaveNode::parse(json_t *json, const uuid_t sn_uuid)
|
|||
|
||||
int SlaveNode::start()
|
||||
{
|
||||
this->startSlave();
|
||||
startSlave();
|
||||
return Node::start();
|
||||
}
|
||||
|
||||
int SlaveNode::stop()
|
||||
{
|
||||
this->stopSlave();
|
||||
stopSlave();
|
||||
return Node::stop();
|
||||
}
|
||||
|
||||
// ------------------------------------------
|
||||
// Plugin
|
||||
// ------------------------------------------
|
||||
|
||||
static char name[] = "iec60870-5-104";
|
||||
static char description[] = "Provide values as protocol slave";
|
||||
static NodePlugin<SlaveNode, name, description, (int) NodeFactory::Flags::SUPPORTS_WRITE> p;
|
||||
|
|
Loading…
Add table
Reference in a new issue