Skip to content

Commit

Permalink
Merge pull request #22 from zachbthomas/iec-104-doublepoint-updates
Browse files Browse the repository at this point in the history
IEC-104 server and client updates
  • Loading branch information
GhostofGoes authored May 9, 2024
2 parents a1e9c48 + 17e6cb3 commit 9b8cbca
Show file tree
Hide file tree
Showing 5 changed files with 364 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ void ClientConnection::start(std::shared_ptr<ClientConnection> clientConnection)
}
}

int ClientConnection::convertBoolToDPValue(bool value)
{
if (value == 0)
return IEC60870_DOUBLE_POINT_OFF;
else
return IEC60870_DOUBLE_POINT_ON;
}

StatusMessage ClientConnection::readRegisterByTag(const std::string& tag, comms::RegisterDescriptor& rd)
{
auto status = getRegisterDescriptorByTag(tag, rd) ? STATUS_SUCCESS : STATUS_FAIL;
Expand All @@ -73,7 +81,7 @@ StatusMessage ClientConnection::readRegisterByTag(const std::string& tag, comms:
return sm;
}

StatusMessage ClientConnection::writeBinary(const std::string& tag, bool value)
StatusMessage ClientConnection::writeBinary(const std::string& tag, bool bvalue)
{
StatusMessage sm = STATUS_INIT;
comms::RegisterDescriptor rd;
Expand All @@ -86,15 +94,18 @@ StatusMessage ClientConnection::writeBinary(const std::string& tag, bool value)
return sm;
}

// Write boolean using protocol
std::cout << "Send single command C_SC_NA_1: " << tag << " -- " << value << std::endl;
InformationObject sc = (InformationObject)
SingleCommand_create(NULL, rd.mRegisterAddress, value, true, 0);
CS104_Connection_sendProcessCommandEx(mConnection, CS101_COT_ACTIVATION, 1, sc);
InformationObject_destroy(sc);
// Convert boolean to double point value
int value = ClientConnection::convertBoolToDPValue(bvalue);

// Update local data so we don't have to wait until the next poll
updateBinary(rd.mRegisterAddress, value);
// Write double point using protocol
std::cout << "Send double command C_DC_NA_1: " << tag << " -- " << bvalue << std::endl;
InformationObject dc = (InformationObject)
DoubleCommand_create(NULL, rd.mRegisterAddress, value, true, 0);
CS104_Connection_sendProcessCommandEx(mConnection, CS101_COT_ACTIVATION, 1, dc);
InformationObject_destroy(dc);

// Update local data so we don't have to wait until the next poll; save boolean to datastore
updateBinary(rd.mRegisterAddress, bvalue);
return sm;
}

Expand Down Expand Up @@ -194,29 +205,45 @@ bool ClientConnection::asduReceivedHandler(void* parameter, int address, CS101_A
}
}
// Binary values
else if (CS101_ASDU_getTypeID(asdu) == M_SP_NA_1) {
printf(" single point information:\n");
else if (CS101_ASDU_getTypeID(asdu) == M_DP_NA_1) {
printf(" double point information:\n");

int i;

for (i = 0; i < CS101_ASDU_getNumberOfElements(asdu); i++) {

SinglePointInformation io =
(SinglePointInformation) CS101_ASDU_getElement(asdu, i);
DoublePointInformation io =
(DoublePointInformation) CS101_ASDU_getElement(asdu, i);

uint16_t addr = InformationObject_getObjectAddress((InformationObject) io);
bool status = SinglePointInformation_getValue((SinglePointInformation) io);
DoublePointValue dp_value = DoublePointInformation_getValue((DoublePointInformation) io);

bool status = 0;
if (dp_value == IEC60870_DOUBLE_POINT_OFF)
{
status = 0;
}
else if (dp_value == IEC60870_DOUBLE_POINT_ON)
{
status = 1;
}
else
{
printf("IOA: %i- Double point value is in indeterminate state..defaulting to 0\n", addr);
status = 0;
}
printf(" IOA: %i value: %i\n", addr, status);

gClientConnection->updateBinary(addr, status);

SinglePointInformation_destroy(io);
DoublePointInformation_destroy(io);
}
}

return true;
}


} // namespace iec60870
} // namespace comms
} // namespace bennu
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include "bennu/devices/modules/comms/base/Common.hpp"
#include "bennu/devices/modules/comms/iec60870-5/protocol/src/inc/api/cs104_connection.h"
#include "bennu/devices/modules/comms/iec60870-5/protocol/src/inc/api/cs101_information_objects.h"


namespace bennu {
Expand Down Expand Up @@ -74,13 +75,16 @@ class ClientConnection : public std::enable_shared_from_this<ClientConnection>
static void connectionHandler(void* parameter, CS104_Connection connection, CS104_ConnectionEvent event);
static bool asduReceivedHandler(void* parameter, int address, CS101_ASDU asdu);

static int convertBoolToDPValue(bool value);

private:
bool mRunning;
std::string mRtuEndpoint; // IP/Port or DevName of remote RTU
CS104_Connection mConnection; // 104 connection object
std::map<std::uint16_t, std::string> mBinaryAddressToTagMapping;
std::map<std::uint16_t, std::string> mAnalogAddressToTagMapping;
std::map<std::string, comms::RegisterDescriptor> mRegisters;


};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ void DataHandler::parseServerTree(std::shared_ptr<Server> server, const ptree& t
std::string endpoint = tree.get<std::string>("endpoint");
std::string log = tree.get<std::string>("event-logging", "iec60870-5-104-server.log");
server->configureEventLogging(log);
std::string subtype = tree.get<std::string>("subtype");
auto binaryInputs = tree.equal_range("binary-input");
for (auto iter = binaryInputs.first; iter != binaryInputs.second; ++iter)
{
Expand Down Expand Up @@ -88,7 +89,7 @@ void DataHandler::parseServerTree(std::shared_ptr<Server> server, const ptree& t
// Initialize and start 104 server
// - Pass server pointer to Server::start() so Server::gServer can be set statically
// and used inside static 104 handlers
server->start(endpoint, server, rPollRate);
server->start(endpoint, server, rPollRate, subtype);
}
catch (ptree_bad_path& e)
{
Expand Down
Loading

0 comments on commit 9b8cbca

Please sign in to comment.