/* * sv_subscriber_api.h * * Copyright 2015 Michael Zillgith * * This file is part of libIEC61850. * * libIEC61850 is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * libIEC61850 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with libIEC61850. If not, see . * * See COPYING file for the complete license text. */ #ifndef SAMPLED_VALUES_SV_SUBSCRIBER_H_ #define SAMPLED_VALUES_SV_SUBSCRIBER_H_ #include "libiec61850_common_api.h" #ifdef __cplusplus extern "C" { #endif /** * \brief opaque handle to a SV ASDU (Application service data unit) instance. * * Sampled Values (SV) ASDUs (application service data units) are the basic units for * sampled value data. Each ASDU represents a single sample consisting of multiple measurement * values with a single dedicated timestamp. * * NOTE: SVClientASDU are statically allocated and are only valid inside of the SVUpdateListener * function when called by the library. If you need the data contained in the ASDU elsewhere * you have to copy and store the data by yourself! */ typedef struct sSVClientASDU* SVClientASDU; /** * \brief opaque handle to a SV subscriber instance * * A subscriber is an instance associated with a single stream of measurement data. It is identified * by the Ethernet destination address, the appID value (both are on SV message level) and the svID value * that is part of each ASDU (SVClientASDU object). */ typedef struct sSVSubscriber* SVSubscriber; /** * \brief Callback function for received SV messages * * Will be called for each ASDU contained in a SV message! * * \param subscriber the subscriber that was associated with the received SV message * \param parameter a user provided parameter that is simply passed to the callback * \param asdu SV ASDU data structure. This structure is only valid inside of the callback function */ typedef void (*SVUpdateListener)(SVSubscriber subscriber, void* parameter, SVClientASDU asdu); /** * \brief opaque handle to a SV receiver instance */ typedef struct sSVReceiver* SVReceiver; /** * \brief Create a new SV receiver instance. * * A receiver is responsible for processing all SV message for a single Ethernet interface. * In order to process messages from multiple Ethernet interfaces you have to create multiple * instances. * * \return the newly created receiver instance */ SVReceiver SVReceiver_create(void); /** * \brief Disable check for destination address of the received SV messages * * Per default both the appID and the destination address are checked to identify * relevant SV messages. Destination address check can be disabled for performance * reason when the appIDs are unique in the local system. * * \param self the receiver instance reference */ void SVReceiver_disableDestAddrCheck(SVReceiver self); /** * \brief Set the Ethernet interface ID for the receiver instance * * Use this function if you want to use a different interface than * the default interface set by CONFIG_ETHERNET_INTERFACE_ID (stack_config.h) * NOTE: This function has to be called before calling SVReceiver_start. * * \param self the receiver instance reference * \param interfaceId the Ethernet interface id (platform specific e.g. eth0 for linux). */ void SVReceiver_setInterfaceId(SVReceiver self, const char* interfaceId); /** * \brief Add a subscriber instance to the receiver * * The given subscriber will be connected to the receiver instance. * * \param self the receiver instance reference * \param subscriber the subscriber instance to connect */ void SVReceiver_addSubscriber(SVReceiver self, SVSubscriber subscriber); /** * \brief Disconnect subscriber and receiver * * \param self the receiver instance reference * \param subscriber the subscriber instance to disconnect */ void SVReceiver_removeSubscriber(SVReceiver self, SVSubscriber subscriber); /** * \brief Receiver starts listening for SV messages. * * NOTE: This call will start a new background thread. * * \param self the receiver instance reference */ void SVReceiver_start(SVReceiver self); /** * \brief Receiver stops listening for SV messages * * \param self the receiver instance reference */ void SVReceiver_stop(SVReceiver self); /** * \brief Destroy receiver instance (cleanup resources) * * \param self the receiver instance reference */ void SVReceiver_destroy(SVReceiver self); /*************************************** * Functions for non-threaded operation ***************************************/ void SVReceiver_startThreadless(SVReceiver self); void SVReceiver_stopThreadless(SVReceiver self); bool SVReceiver_tick(SVReceiver self); /* * Subscriber */ SVSubscriber SVSubscriber_create(const uint8_t* ethAddr, uint16_t appID); /** * \brief Set a callback handler to process received SV messages * * If the received SV message contains multiple ASDUs (application service data units) the callback * function will be called for each ASDU separately. If a callback function has already been installed * for this SVSubscriber object the old callback will be replaced. * * \param self The subscriber object * \param listener the callback function to install * \param a user provided parameter that is provided to the callback function * */ void SVSubscriber_setListener(SVSubscriber self, SVUpdateListener listener, void* parameter); void SVSubscriber_destroy(SVSubscriber self); /************************************************************************* * SVClientASDU object methods **************************************************************************/ /** * \brief return the SmpCnt value included in the SV ASDU * * The SmpCnt (sample counter) is increased for each ASDU to * identify the sample. * * \param self ASDU object instance */ uint16_t SVClientASDU_getSmpCnt(SVClientASDU self); /** * \brief return the SvID value included in the SV ASDU * * \param self ASDU object instance */ const char* SVClientASDU_getSvId(SVClientASDU self); /** * \brief return the ConfRev value included in the SV ASDU * * \param self ASDU object instance */ uint32_t SVClientASDU_getConfRev(SVClientASDU self); /** * \brief Get an INT8 data value in the data part of the ASDU * * \param self ASDU object instance * \param index the index (byte position of the start) of the data in the data part * * \return SV data */ int8_t SVClientASDU_getINT8(SVClientASDU self, int index); /** * \brief Get an INT16 data value in the data part of the ASDU * * \param self ASDU object instance * \param index the index (byte position of the start) of the data in the data part * * \return SV data */ int16_t SVClientASDU_getINT16(SVClientASDU self, int index); /** * \brief Get an INT32 data value in the data part of the ASDU * * \param self ASDU object instance * \param index the index (byte position of the start) of the data in the data part * * \return SV data */ int32_t SVClientASDU_getINT32(SVClientASDU self, int index); /** * \brief Get an INT8U data value in the data part of the ASDU * * \param self ASDU object instance * \param index the index (byte position of the start) of the data in the data part * * \return SV data */ uint8_t SVClientASDU_getINT8U(SVClientASDU self, int index); /** * \brief Get an INT16U data value in the data part of the ASDU * * \param self ASDU object instance * \param index the index (byte position of the start) of the data in the data part * * \return SV data */ uint16_t SVClientASDU_getINT16U(SVClientASDU self, int index); /** * \brief Get an INT32U data value in the data part of the ASDU * * \param self ASDU object instance * \param index the index (byte position of the start) of the data in the data part * * \return SV data */ uint32_t SVClientASDU_getINT32U(SVClientASDU self, int index); /** * \brief Get an FLOAT32 data value in the data part of the ASDU * * \param self ASDU object instance * \param index the index (byte position of the start) of the data in the data part * * \return SV data */ float SVClientASDU_getFLOAT32(SVClientASDU self, int index); /** * \brief Get an FLOAT64 data value in the data part of the ASDU * * \param self ASDU object instance * \param index the index (byte position of the start) of the data in the data part * * \return SV data */ double SVClientASDU_getFLOAT64(SVClientASDU self, int index); /** * \brief Returns the size of the data part of the ASDU * * \param self ASDU object instance * * \return size of the ASDU data part in bytes. */ int SVClientASDU_getDataSize(SVClientASDU self); #ifdef __cplusplus } #endif #endif /* SAMPLED_VALUES_SV_SUBSCRIBER_ */