Skip to content

Commit

Permalink
Merge pull request #30 from fledge-power/develop_mz
Browse files Browse the repository at this point in the history
Develop mz
  • Loading branch information
aklira authored Jan 23, 2024
2 parents d87d163 + bfa1855 commit ee8dd70
Show file tree
Hide file tree
Showing 13 changed files with 3,935 additions and 1,551 deletions.
35 changes: 33 additions & 2 deletions include/iec61850_client_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
FRIEND_TEST (ControlTest, DoubleCommandDirectNormal); \
FRIEND_TEST (ControlTest, SingleCommandDirectEnhanced); \
FRIEND_TEST (ControlTest, SingleCommandSetValue); \
FRIEND_TEST (ControlTest, WriteOperations); \
FRIEND_TEST (ReportingTest, ReportingWithStaticDataset); \
FRIEND_TEST (ReportingTest, ReportingWithDynamicDataset); \
FRIEND_TEST (ReportingTest, ReportingUpdateQuality); \
Expand All @@ -29,7 +30,26 @@
FRIEND_TEST (SpontDataTest, Polling); \
FRIEND_TEST (SpontDataTest, PollingAllCDC); \
FRIEND_TEST (ControlTest, AnalogueCommandDirectNormal); \
FRIEND_TEST (ControlTest, StepCommandDirectNormal);
FRIEND_TEST (ControlTest, StepCommandDirectNormal); \
FRIEND_TEST (ConfigTest, ProtocolConfigParseError); \
FRIEND_TEST (ConfigTest, ProtocolConfigNoJsonProtocolStack); \
FRIEND_TEST (ConfigTest, ProtocolConfigNoTransportLayer); \
FRIEND_TEST (ConfigTest, ProtocolConfigNoConnections); \
FRIEND_TEST (ConfigTest, ProtocolConfigNoConnectionIP); \
FRIEND_TEST (ConfigTest, ProtocolConfigInvalidConnectionPort); \
FRIEND_TEST (ConfigTest, ProtocolConfigWithOsi); \
FRIEND_TEST (ConfigTest, ProtocolConfigTlsNotBoolean); \
FRIEND_TEST (ConfigTest, ProtocolConfigNoAppLayer); \
FRIEND_TEST (ConfigTest, ProtocolConfigPollingIntervalNotInt); \
FRIEND_TEST (ConfigTest, ProtocolConfigWrongPollingInterval); \
FRIEND_TEST (ConfigTest, ProtocolConfigNoDatasets); \
FRIEND_TEST (ConfigTest, ProtocolConfigNoDynamicValue); \
FRIEND_TEST (ConfigTest, ProtocolConfigReportSubscriptionsNotString); \
FRIEND_TEST (ConfigTest, ProtocolConfigReportSubscriptionsNotObject); \
FRIEND_TEST (ConfigTest, ProtocolConfigReportNoDataref); \
FRIEND_TEST (ConfigTest, ProtocolConfigNoTrgroups); \
FRIEND_TEST (ConfigTest, ProtocolConfigBuftmIntgpd); \
FRIEND_TEST (ConnectionHandlingTest, TwoConnectionsBackup);

typedef enum
{
Expand All @@ -49,7 +69,10 @@ typedef enum
DPC,
APC,
INC,
BSC
BSC,
SPG,
ASG,
ING
} CDCTYPE;

class ConfigurationException : public std::logic_error
Expand Down Expand Up @@ -212,6 +235,12 @@ class IEC61850ClientConfig
return pollingInterval;
}

uint64_t
backupConnectionTimeout ()
{
return m_backupConnectionTimeout;
};

private:
static bool isMessageTypeMatching (int expectedType, int rcvdType);

Expand Down Expand Up @@ -240,6 +269,8 @@ class IEC61850ClientConfig
std::vector<std::string> m_remoteCertificates;
std::vector<std::string> m_caCertificates;

uint64_t m_backupConnectionTimeout = 5000;

long pollingInterval = 0;
FRIEND_TESTS
};
Expand Down
21 changes: 21 additions & 0 deletions include/iec61850_client_connection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,23 @@ class IEC61850ClientConnection

bool operate (const std::string& objRef, DatapointValue value);

static void writeHandler (uint32_t invokeId, void* parameter,
IedClientError err);

bool writeValue (Datapoint* operation, const std::string& objRef, DatapointValue value,
CDCTYPE type);

const std::string&
IP ()
{
return m_serverIp;
};
int
Port ()
{
return m_tcpPort;
};

private:
bool prepareConnection ();
bool
Expand All @@ -80,6 +97,10 @@ class IEC61850ClientConnection

static void reportCallbackFunction (void* parameter, ClientReport report);

static void writeVariableHandler (uint32_t invokeId, void* parameter,
MmsError err,
MmsDataAccessError accessError);

using ConState = enum {
CON_STATE_IDLE,
CON_STATE_CONNECTING,
Expand Down
211 changes: 119 additions & 92 deletions src/iec61850.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,160 +2,187 @@
#include "plugin_api.h"
#include <iec61850.hpp>

bool
isCommandType(CDCTYPE type){
return type>=SPC;
static bool
isCommandType (CDCTYPE type)
{
return type >= SPC && type < SPG;
}


IEC61850::~IEC61850(){
delete m_config;
static bool
isWriteType (CDCTYPE type)
{
return type >= SPG;
}

IEC61850::~IEC61850 () { delete m_config; }

void
IEC61850::registerIngest(void* data, INGEST_CB cb)
IEC61850::registerIngest (void* data, INGEST_CB cb)
{
m_ingest = cb;
m_data = data;
}


void
IEC61850::setJsonConfig(const std::string& protocol_stack,
const std::string& exchanged_data,
const std::string& tls_configuration)
IEC61850::setJsonConfig (const std::string& protocol_stack,
const std::string& exchanged_data,
const std::string& tls_configuration)
{
if(m_config) delete m_config;
if (m_config)
delete m_config;

m_config = new IEC61850ClientConfig();
m_config->importExchangeConfig(exchanged_data);
m_config->importProtocolConfig(protocol_stack);
m_config->importTlsConfig(tls_configuration);
}
m_config = new IEC61850ClientConfig ();
m_config->importExchangeConfig (exchanged_data);
m_config->importProtocolConfig (protocol_stack);
m_config->importTlsConfig (tls_configuration);
}

void
IEC61850::start()
void
IEC61850::start ()
{
Iec61850Utility::log_info("Starting iec61850");
//LCOV_EXCL_START
switch (m_config->LogLevel())
Iec61850Utility::log_info ("Starting iec61850");
// LCOV_EXCL_START
switch (m_config->LogLevel ())
{
case 1:
Logger::getLogger()->setMinLevel("debug");
break;
case 2:
Logger::getLogger()->setMinLevel("info");
break;
case 3:
Logger::getLogger()->setMinLevel("warning");
break;
default:
Logger::getLogger()->setMinLevel("error");
break;
case 1:
Logger::getLogger ()->setMinLevel ("debug");
break;
case 2:
Logger::getLogger ()->setMinLevel ("info");
break;
case 3:
Logger::getLogger ()->setMinLevel ("warning");
break;
default:
Logger::getLogger ()->setMinLevel ("error");
break;
}
//LCOV_EXCL_STOP
// LCOV_EXCL_STOP

m_client = new IEC61850Client(this, m_config);
m_client = new IEC61850Client (this, m_config);

//LCOV_EXCL_START
if(!m_client){
Iec61850Utility::log_error("Can't start, client is null");
// LCOV_EXCL_START
if (!m_client)
{
Iec61850Utility::log_error ("Can't start, client is null");
return;
}
//LCOV_EXCL_STOP
// LCOV_EXCL_STOP

m_client->start();
m_client->start ();
}

void IEC61850::stop()
void
IEC61850::stop ()
{
if(!m_client) return;
if (!m_client)
return;

m_client->stop();
m_client->stop ();

delete m_client;
m_client = nullptr;
delete m_client;
m_client = nullptr;
}

void IEC61850::ingest(const std::string& assetName, const std::vector<Datapoint*>& points)
void
IEC61850::ingest (const std::string& assetName,
const std::vector<Datapoint*>& points)
{
if (m_ingest){
m_ingest(m_data, Reading(assetName, points));
}
if (m_ingest)
{
m_ingest (m_data, Reading (assetName, points));
}
}

static Datapoint*
getCdc(Datapoint* dp)
getCdc (Datapoint* dp)
{
DatapointValue& dpv = dp->getData();
DatapointValue& dpv = dp->getData ();

if (dpv.getType() != DatapointValue::T_DP_DICT) {
Iec61850Utility::log_error("Datapoint is not a dictionary %s", dp->getName().c_str());
if (dpv.getType () != DatapointValue::T_DP_DICT)
{
Iec61850Utility::log_error ("Datapoint is not a dictionary %s",
dp->getName ().c_str ());
}

std::vector<Datapoint*> const* datapoints = dpv.getDpVec();
std::vector<Datapoint*> const* datapoints = dpv.getDpVec ();

for (Datapoint* child : *datapoints) {
if(IEC61850ClientConfig::getCdcTypeFromString(child->getName()) != -1){
return child;
}
for (Datapoint* child : *datapoints)
{
if (IEC61850ClientConfig::getCdcTypeFromString (child->getName ())
!= -1)
{
return child;
}
}

return nullptr;
}

bool
IEC61850::operation(const std::string& operation, int count,
PLUGIN_PARAMETER** params)
IEC61850::operation (const std::string& operation, int count,
PLUGIN_PARAMETER** params)
{
if (m_client == nullptr) {
Iec61850Utility::log_error("operation called but plugin is not yet initialized");
if (m_client == nullptr)
{
Iec61850Utility::log_error (
"operation called but plugin is not yet initialized");

return false;
}

if (operation == "PivotCommand"){
if (operation == "PivotCommand")
{
std::string commandContentJSON = params[0]->value;
Datapoint* commandContent = nullptr;

DatapointValue temp((long)1);
std::unique_ptr<Datapoint> parserDp (new Datapoint("Parser", temp));

std::vector<Datapoint *>* jsonValues = parserDp->parseJson(commandContentJSON);
DatapointValue temp ((long)1);
std::unique_ptr<Datapoint> parserDp (new Datapoint ("Parser", temp));

std::vector<Datapoint*>* jsonValues
= parserDp->parseJson (commandContentJSON);

if(jsonValues){
commandContent = jsonValues->at(0);
jsonValues->clear();
if (jsonValues)
{
commandContent = jsonValues->at (0);
jsonValues->clear ();
delete jsonValues;
}
}

if(!commandContent) {
Iec61850Utility::log_error("Failed to parse command content");
return false;
if (!commandContent)
{
Iec61850Utility::log_error ("Failed to parse command content");
return false;
}

Iec61850Utility::log_debug("Received command: %s", commandContent->toJSONProperty().c_str());

Datapoint* cdc = getCdc(commandContent);

if(!cdc){
Iec61850Utility::log_warn("Received pivot object has no cdc");
return false;

Iec61850Utility::log_debug (
"Received command: %s",
commandContent->toJSONProperty ().c_str ());

Datapoint* cdc = getCdc (commandContent);

if (!cdc)
{
Iec61850Utility::log_warn ("Received pivot object has no cdc");
return false;
}

int type = IEC61850ClientConfig::getCdcTypeFromString(cdc->getName());
int type
= IEC61850ClientConfig::getCdcTypeFromString (cdc->getName ());

if(type == -1 || !isCommandType((CDCTYPE)type)){
Iec61850Utility::log_warn("Not a command object %s -> ignore", cdc->toJSONProperty().c_str());
return false;
if (type == -1 || !isCommandType ((CDCTYPE)type) && !isWriteType((CDCTYPE)type))
{
Iec61850Utility::log_warn ("Not a command object %s -> ignore",
cdc->toJSONProperty ().c_str ());
return false;
}

bool res = m_client->handleOperation(commandContent);
bool res = m_client->handleOperation (commandContent);
return res;
}
}

Iec61850Utility::log_error("Unrecognised operation %s", operation.c_str());
Iec61850Utility::log_error ("Unrecognised operation %s",
operation.c_str ());

return false;
}

Loading

0 comments on commit ee8dd70

Please sign in to comment.