Merge pull request #309 from mbourhis/mbourhis/python_swig_event_handler_for_command_termination

Mbourhis/python swig event handler for command termination
pull/331/head
Michael Zillgith 5 years ago committed by GitHub
commit 5512b0f9be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,97 @@
#ifndef PYIEC61850_COMMANDTERMHANDLER_HPP
#define PYIEC61850_COMMANDTERMHANDLER_HPP
#include "eventHandler.hpp"
/*
* Abstract class for processing the received 'Command Termination' events.
*/
class CommandTermHandler: public EventHandler {
public:
virtual ~CommandTermHandler() {}
virtual void setReceivedData(void *i_data_p)
{
// copy the received data
ControlObjectClient *l_my_data_p = static_cast<ControlObjectClient*>(i_data_p);
_libiec61850_control_object_client = *l_my_data_p;
}
ControlObjectClient _libiec61850_control_object_client;
};
/*
* Class for the subscription to the 'Command Termination' events
*/
class CommandTermSubscriber: public EventSubscriber {
public:
CommandTermSubscriber(): EventSubscriber()
{
m_libiec61850_control_object_client = nullptr;
}
virtual ~CommandTermSubscriber() {}
virtual bool subscribe()
{
// preconditions
if (nullptr == m_libiec61850_control_object_client) {
fprintf(stderr, "CommandTermSubscriber::subscribe() failed: 'control object client' is null\n");
return false;
}
// install the libiec61850 callback:
// the 'function pointer' is the 'static' method of this class
ControlObjectClient_setCommandTerminationHandler(
m_libiec61850_control_object_client,
CommandTermSubscriber::triggerCommandTermHandler,
NULL);
std::string l_object_ref = ControlObjectClient_getObjectReference(m_libiec61850_control_object_client);
return (EventSubscriber::registerNewSubscriber(this, l_object_ref));
}
// Static method: it is the 'callback' for libiec61850 in C
static void triggerCommandTermHandler(void *parameter, ControlObjectClient connection)
{
PyThreadStateLock PyThreadLock;
// Preconditions
if (nullptr == connection) {
fprintf(stderr, "CommandTermSubscriber::triggerCommandTermHandler() failed: input object is null\n");
return;
}
// Search the appropriate 'EventSubscriber' object
std::string l_subscriber_id = ControlObjectClient_getObjectReference(connection);
EventSubscriber *l_registered_subscriber = EventSubscriber::findSubscriber(l_subscriber_id);
if (l_registered_subscriber) {
EventHandler *l_event_handler_p = l_registered_subscriber->getEventHandler();
if (l_event_handler_p) {
l_event_handler_p->setReceivedData(&connection);
l_event_handler_p->trigger();
}
else {
fprintf(stderr, "CommandTermSubscriber::triggerCommandTermHandler() failed: EventHandler is undefined\n");
}
}
else {
fprintf(stderr, "CommandTermSubscriber::triggerCommandTermHandler() failed: subscriber is not registered\n");
}
}
// Setters
void setLibiec61850ControlObjectClient(const ControlObjectClient &i_libiec61850_control_object_client)
{
m_libiec61850_control_object_client = i_libiec61850_control_object_client;
}
protected:
// Parameters
ControlObjectClient m_libiec61850_control_object_client;
};
#endif

@ -28,6 +28,7 @@ private:
class EventHandler {
public:
EventHandler() {}
virtual ~EventHandler() {}
virtual void setReceivedData(void *i_data_p) = 0;
virtual void trigger() = 0;
@ -36,13 +37,9 @@ class EventHandler {
class EventSubscriber {
public:
// TODO: use a map to store and find the instantiated EventSubscriber
static EventSubscriber* m_last_created_event_subscriber;
EventSubscriber(): _event_handler_p(nullptr)
{
m_last_created_event_subscriber = this;
// add python thread support
Py_Initialize();
PyEval_InitThreads();
@ -50,11 +47,11 @@ class EventSubscriber {
virtual ~EventSubscriber()
{
EventSubscriber::unregisterSubscriber(m_subscriber_id);
deleteEventHandler();
m_last_created_event_subscriber = nullptr;
}
virtual void subscribe() = 0;
virtual bool subscribe() = 0;
void deleteEventHandler()
{
@ -75,8 +72,59 @@ class EventSubscriber {
return _event_handler_p;
}
void setSubscriberId(const std::string &i_id)
{
m_subscriber_id = i_id;
}
protected:
static std::map<std::string, EventSubscriber*> m_subscriber_map;
static bool registerNewSubscriber(EventSubscriber *i_new_subscriber, const std::string &i_id)
{
// Preconditions
if (i_id.empty()) {
fprintf(stderr, "EventSubscriber::subscribe() failed: the subscriber id is empty\n");
return false;
}
if (m_subscriber_map.end() != m_subscriber_map.find(i_id)) {
fprintf(stderr, "EventSubscriber::subscribe() failed: the subscriber is already registered\n");
return false;
}
m_subscriber_map[i_id] = i_new_subscriber;
i_new_subscriber->setSubscriberId(i_id);
return true;
}
static EventSubscriber* findSubscriber(const std::string &i_id)
{
EventSubscriber *o_found_event_subscriber_p = nullptr;
std::map<std::string, EventSubscriber*>::iterator l_it = m_subscriber_map.find(i_id);
if (m_subscriber_map.end() != l_it) {
o_found_event_subscriber_p = l_it->second;
}
return o_found_event_subscriber_p;
}
static void unregisterSubscriber(const std::string &i_subscriber_id)
{
std::map<std::string, EventSubscriber*>::iterator l_it = m_subscriber_map.find(i_subscriber_id);
if (m_subscriber_map.end() != l_it) {
m_subscriber_map.erase(l_it);
}
else {
fprintf(stderr, "EventSubscriber::unregisterSubscriber() failed: '%s' is not registered\n");
}
}
private:
EventHandler *_event_handler_p;
std::string m_subscriber_id;
};
#endif

@ -22,13 +22,30 @@ class GooseHandler: public EventHandler {
class GooseSubscriberForPython: public EventSubscriber {
public:
GooseSubscriberForPython(): EventSubscriber()
{
m_libiec61850_goose_subscriber = nullptr;
}
virtual ~GooseSubscriberForPython() {}
virtual bool subscribe()
{
// preconditions
if (nullptr == m_libiec61850_goose_subscriber) {
fprintf(stderr, "GooseSubscriberForPython::subscribe() failed: 'GOOSE subscriber' is null\n");
return false;
}
virtual void subscribe() {
// install the libiec61850 callback:
// the 'function pointer' is the 'static' method of this class
GooseSubscriber_setListener(m_libiec61850_goose_subscriber,
GooseSubscriberForPython::triggerGooseHandler,
NULL);
std::string l_go_cb_ref = GooseSubscriber_getGoCbRef(m_libiec61850_goose_subscriber);
return (EventSubscriber::registerNewSubscriber(this, l_go_cb_ref));
}
// Static method: it is the 'callback' for libiec61850 in C
@ -36,16 +53,28 @@ class GooseSubscriberForPython: public EventSubscriber {
{
PyThreadStateLock PyThreadLock;
// TODO: search the appropriate 'EventSubscriber' object
if (m_last_created_event_subscriber) {
EventHandler *l_event_handler_p = m_last_created_event_subscriber->getEventHandler();
// Preconditions
if (nullptr == subscriber) {
fprintf(stderr, "GooseSubscriberForPython::triggerGooseHandler() failed: input object is null\n");
return;
}
// Search the appropriate 'EventSubscriber' object
std::string l_subscriber_id = GooseSubscriber_getGoCbRef(subscriber);
EventSubscriber *l_registered_subscriber = EventSubscriber::findSubscriber(l_subscriber_id);
if (l_registered_subscriber) {
EventHandler *l_event_handler_p = l_registered_subscriber->getEventHandler();
if (l_event_handler_p) {
l_event_handler_p->setReceivedData(&subscriber);
l_event_handler_p->trigger();
}
else {
printf("The EventHandler is undefined\n");
fprintf(stderr, "GooseSubscriberForPython::triggerGooseHandler() failed: EventHandler is undefined\n");
}
}
else {
fprintf(stderr, "GooseSubscriberForPython::triggerGooseHandler() failed: subscriber is not registered\n");
}
}

@ -22,8 +22,20 @@ class RCBHandler: public EventHandler {
class RCBSubscriber: public EventSubscriber {
public:
RCBSubscriber(): EventSubscriber()
{
m_ied_connection = nullptr;
}
virtual ~RCBSubscriber() {}
virtual bool subscribe() {
// preconditions
if (nullptr == m_ied_connection) {
fprintf(stderr, "RCBSubscriber::subscribe() failed: 'IedConnection' is null\n");
return false;
}
virtual void subscribe() {
// install the libiec61850 callback:
// the 'function pointer' is the 'static' method of this class
IedConnection_installReportHandler(m_ied_connection,
@ -31,6 +43,8 @@ class RCBSubscriber: public EventSubscriber {
m_rcb_rpt_id.c_str(),
RCBSubscriber::triggerRCBHandler,
NULL);
return (EventSubscriber::registerNewSubscriber(this, m_rcb_reference));
}
// Static method: it is the 'callback' for libiec61850 in C
@ -38,17 +52,29 @@ class RCBSubscriber: public EventSubscriber {
{
PyThreadStateLock PyThreadLock;
// TODO: search the appropriate 'EventSubscriber' object
if (m_last_created_event_subscriber) {
EventHandler *l_event_handler_p = m_last_created_event_subscriber->getEventHandler();
// Preconditions
if (nullptr == report) {
fprintf(stderr, "RCBSubscriber::triggerRCBHandler() failed: input object is null\n");
return;
}
// Search the appropriate 'EventSubscriber' object
std::string l_subscriber_id = ClientReport_getRcbReference(report);
EventSubscriber *l_registered_subscriber = EventSubscriber::findSubscriber(l_subscriber_id);
if (l_registered_subscriber) {
EventHandler *l_event_handler_p = l_registered_subscriber->getEventHandler();
if (l_event_handler_p) {
l_event_handler_p->setReceivedData(&report);
l_event_handler_p->trigger();
}
else {
printf("The EventHandler is undefined\n");
fprintf(stderr, "RCBSubscriber::triggerRCBHandler() failed: EventHandler is undefined\n");
}
}
else {
fprintf(stderr, "RCBSubscriber::triggerRCBHandler() failed: subscriber is not registered\n");
}
}
// Setters

@ -98,15 +98,18 @@ void GooseSubscriber_setDstMac(GooseSubscriber subscriber,
/* Event Handler section */
%feature("director") RCBHandler;
%feature("director") GooseHandler;
%feature("director") CommandTermHandler;
%{
#include "eventHandlers/eventHandler.hpp"
#include "eventHandlers/reportControlBlockHandler.hpp"
#include "eventHandlers/gooseHandler.hpp"
EventSubscriber* EventSubscriber::m_last_created_event_subscriber = nullptr;
#include "eventHandlers/commandTermHandler.hpp"
std::map< std::string, EventSubscriber*> EventSubscriber::m_subscriber_map = {};
%}
%include "eventHandlers/eventHandler.hpp"
%include "eventHandlers/reportControlBlockHandler.hpp"
%include "eventHandlers/gooseHandler.hpp"
%include "eventHandlers/commandTermHandler.hpp"
/* Goose Publisher section */
%{

Loading…
Cancel
Save