Skip to content

Commit

Permalink
Merge branch 'develop' into develop_mz
Browse files Browse the repository at this point in the history
  • Loading branch information
mzillgith committed Feb 12, 2024
2 parents ebab861 + 0019471 commit e4ef8cf
Show file tree
Hide file tree
Showing 10 changed files with 568 additions and 125 deletions.
4 changes: 4 additions & 0 deletions include/iec61850.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,13 +145,17 @@ class IEC61850Client
void sendCommandAck (const std::string& label, ControlModel mode,
bool terminated);

bool firstTimeConnect = true;
MmsValue* lastEntryId = nullptr;

private:
std::shared_ptr<std::vector<IEC61850ClientConnection*> > m_connections
= nullptr;

IEC61850ClientConnection* m_active_connection = nullptr;
std::mutex m_activeConnectionMtx;


enum class ConnectionStatus
{
STARTED,
Expand Down
1 change: 1 addition & 0 deletions include/iec61850_client_config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
FRIEND_TEST (ReportingTest, ReportingUpdateQuality); \
FRIEND_TEST (ReportingTest, ReportingGI); \
FRIEND_TEST (ReportingTest, ReportingSetpointCommand); \
FRIEND_TEST (ReportingTest, ReconfigureDynamicDataset); \
FRIEND_TEST (ReportingTest, ReportingChangeValueMultipleTimes); \
FRIEND_TEST (SpontDataTest, Polling); \
FRIEND_TEST (SpontDataTest, PollingAllCDC); \
Expand Down
17 changes: 0 additions & 17 deletions src/iec61850.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,6 @@ void
IEC61850::start ()
{
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;
}
// LCOV_EXCL_STOP

m_client = new IEC61850Client (this, m_config);

Expand Down
21 changes: 6 additions & 15 deletions src/iec61850_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,20 +50,6 @@ isCommandCdcType (CDCTYPE type)
return type >= SPC && type < SPG;
}

static uint64_t
getMonotonicTimeInMs ()
{
uint64_t timeVal = 0;

struct timespec ts;

if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0)
{
timeVal = ((uint64_t)ts.tv_sec * 1000LL) + (ts.tv_nsec / 1000000);
}

return timeVal;
}

static long
getValueInt (Datapoint* dp)
Expand Down Expand Up @@ -233,7 +219,7 @@ const std::map<PIVOTROOT, std::string> rootToStrMap

IEC61850Client::IEC61850Client (IEC61850* iec61850,
IEC61850ClientConfig* iec61850_client_config)
: m_config (iec61850_client_config), m_iec61850 (iec61850)
: m_config (iec61850_client_config), m_iec61850 (iec61850), firstTimeConnect(true)
{
}

Expand All @@ -255,6 +241,11 @@ IEC61850Client::stop ()
delete m_monitoringThread;
m_monitoringThread = nullptr;
}

if(lastEntryId){
MmsValue_delete(lastEntryId);
lastEntryId = nullptr;
}
}

int
Expand Down
88 changes: 45 additions & 43 deletions src/iec61850_client_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,11 @@
using namespace rapidjson;

static const std::unordered_map<std::string, int> trgOptions
= { { "data_changed", TRG_OPT_DATA_CHANGED },
{ "quality_changed", TRG_OPT_QUALITY_CHANGED },
{ "data_update", TRG_OPT_DATA_UPDATE },
{ "integrity", TRG_OPT_INTEGRITY },
{ "gi", TRG_OPT_GI },
{ "transient", TRG_OPT_TRANSIENT } };
= { { "dchg", TRG_OPT_DATA_CHANGED },
{ "qchg", TRG_OPT_QUALITY_CHANGED },
{ "dupd", TRG_OPT_DATA_UPDATE },
{ "period", TRG_OPT_INTEGRITY },
{ "gi", TRG_OPT_GI } };

static const std::unordered_map<std::string, CDCTYPE> cdcMap
= { { "SpsTyp", SPS }, { "DpsTyp", DPS }, { "BscTyp", BSC },
Expand Down Expand Up @@ -585,59 +584,62 @@ IEC61850ClientConfig::parseOsiTSelector (std::string& inputOsiSelector,
}

OsiSelectorSize
IEC61850ClientConfig::parseOsiSelector (std::string& inputOsiSelector,
uint8_t* selectorValue,
const uint8_t selectorSize)
IEC61850ClientConfig::parseOsiSelector(std::string& inputOsiSelector, uint8_t* selectorValue, const uint8_t selectorSize)
{
char* tokenContext = nullptr;
const char* nextToken
= strtok_r (&inputOsiSelector[0], " ,.-", &tokenContext);
uint8_t count = 0;
uint8_t i = 0;

while (nullptr != nextToken)
if (inputOsiSelector.find(',') == std::string::npos)
{
if (count >= selectorSize)
std::regex hexPattern("^([0-9a-fA-F]{2})+$");
if(inputOsiSelector.substr(0, 2) == "0x") inputOsiSelector.erase(0, 2);
if(!std::regex_match(inputOsiSelector, hexPattern))
{
throw ConfigurationException (
"bad format for 'OSI Selector' (too many bytes)");
throw ConfigurationException("bad format for 'OSI Selector' (Expected hexadecimal string)");
}

int base = 10;

if (0 == strncmp (nextToken, "0x", 2))
if(inputOsiSelector.size()/2 > selectorSize)
{
base = 16;
throw ConfigurationException("bad format for 'OSI Selector' (too many bytes)");
}

unsigned long ul = 0;
std::istringstream hex_chars_stream(inputOsiSelector);
uint8_t count = 0;

try
char hex_chars[2];

while (hex_chars_stream >> hex_chars[0] >> hex_chars[1])
{
ul = std::stoul (nextToken, nullptr, base);
}
catch (std::invalid_argument&)
{
throw ConfigurationException (
"bad format for 'OSI Selector' (not a byte)");
}
catch (std::out_of_range&)
{
throw ConfigurationException (
"bad format for 'OSI Selector (exceed an int)'");
char* endptr;
selectorValue[count] = static_cast<uint8_t>(strtol(hex_chars, &endptr, 16));
if (*endptr != 0)
{
throw ConfigurationException("bad format for 'OSI Selector' (not a byte)");
}
count++;
}
return count;
}
else
{
std::replace(inputOsiSelector.begin(), inputOsiSelector.end(), ',', ' ');
std::istringstream ss(inputOsiSelector);
std::string token;

if (ul > 255)
while(std::getline(ss, token, ' ') && i < selectorSize)
{
throw ConfigurationException (
"bad format for 'OSI Selector' (exceed a byte)");
}
if(token.substr(0, 2) == "0x") token.erase(0, 2);

std::regex hexPattern("^([0-9a-fA-F]{2})+$");
if(!std::regex_match(token, hexPattern))
{
throw ConfigurationException("bad format for 'OSI Selector' (Expected hexadecimal string)");
}

selectorValue[count] = static_cast<uint8_t> (ul);
count++;
nextToken = strtok_r (nullptr, " ,.-", &tokenContext);
selectorValue[i] = static_cast<uint8_t>(std::stoul(token, nullptr, 16));
i++;
}
return i;
}

return count;
}

void
Expand Down
Loading

0 comments on commit e4ef8cf

Please sign in to comment.