blob: f20ce15ab58345d060a6bc156a56cb7ec8d1f6e3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014 fortiss GmbH
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Alois Zoitl - initial API and implementation and/or initial documentation
*******************************************************************************/
#include "essfplayer.h"
#include "essfphandler.h"
#include <commfb.h>
using namespace forte::com_infra;
const char CES_SFP_Layer::scmParameterSeperator;
CES_SFP_Layer::CES_SFP_Layer(CComLayer* paUpperLayer, CBaseCommFB* paComFB) :
CComLayer(paUpperLayer, paComFB), mSFPItem(0){
}
CES_SFP_Layer::~CES_SFP_Layer(){
closeConnection();
}
EComResponse CES_SFP_Layer::sendData(void *paData, unsigned int paSize){
EComResponse retVal = e_ProcessDataOk;
if(0 == paSize){
//TODO change to an update now with out the need for a new allocation
sfp_item_update_data_allocated(*mSFPItem, sfp_variant_new_null(), sfp_time_in_millis ());
}else {
CIEC_ANY const *SDs(static_cast<TConstIEC_ANYPtr>(paData));
for(unsigned int i = 0; i < paSize; i++){
CEclipseSCADASFPHandler::updateDataPoint(mSFPItem[i], SDs[i]); //TODO use common timestamp for all
}
}
return retVal;
}
EComResponse CES_SFP_Layer::recvData(const void *paData, unsigned int ){
mInterruptResp = e_ProcessDataOk;
const struct sfp_variant *value = static_cast<const struct sfp_variant *>(paData);
if(0 == getCommFB()->getNumRD()){
//we are a subscribe 0
if(VT_NULL != value->type){
mInterruptResp = e_ProcessDataRecvFaild;
}
}else{
CIEC_ANY &RD1(*getCommFB()->getRDs());
if(!CEclipseSCADASFPHandler::readBackDataPoint(value, RD1)){
mInterruptResp = e_ProcessDataRecvFaild;
}
}
getCommFB()->interruptCommFB(this);
return mInterruptResp;
}
EComResponse CES_SFP_Layer::processInterrupt(){
//we don't need to do anything here
return mInterruptResp;
}
EComResponse CES_SFP_Layer::openConnection(char *paLayerParameter){
size_t numData;
CIEC_ANY *dataArray;
if(e_Subscriber == getCommFB()->getComServiceType()){
numData = getCommFB()->getNumRD();
dataArray = getCommFB()->getRDs();
}else{
numData = getCommFB()->getNumSD();
dataArray = getCommFB()->getSDs();
}
EComResponse retVal = createItems(dataArray, numData, paLayerParameter);
if(e_InitOk == retVal){
if(e_Subscriber == getCommFB()->getComServiceType()){
if(0 == numData){
numData = 1; //register for the item used for the event transmition
}
for(size_t i = 0; i < numData; i++){
getExtEvHandler<CEclipseSCADASFPHandler>().registerWriteCallBack(mSFPItem[i], this);
}
}
}
return retVal;
}
void CES_SFP_Layer::closeConnection(){
if(0 != mSFPItem){
int numData = (e_Subscriber == getCommFB()->getComServiceType()) ?
getCommFB()->getNumRD() : getCommFB()->getNumSD();
if(0 == numData){
numData = 1; //remove the item used for the event transmition
}
for(int i = 0; i < numData; i++){
if(0 != mSFPItem[i]){
getExtEvHandler<CEclipseSCADASFPHandler>().unregisterDataPoint(mSFPItem[i]);
}
}
delete[] mSFPItem;
mSFPItem = 0;
}
}
EComResponse CES_SFP_Layer::createItems(CIEC_ANY *paDataArray, int paNumData, char *paLayerParameter){
EComResponse retVal = e_InitOk;
if(0 == paNumData){
//handle pure event messages
mSFPItem = new sfp_item *[1];
*mSFPItem = getExtEvHandler<CEclipseSCADASFPHandler>().registerDataPoint(paLayerParameter, "Coment");
if(0 != *mSFPItem){
sfp_item_update_data_allocated(*mSFPItem, sfp_variant_new_null(), sfp_time_in_millis ());
}else{
retVal = e_InitInvalidId;
}
}else{
mSFPItem = new sfp_item *[paNumData];
memset(mSFPItem, 0, sizeof(sfp_item *) * paNumData);
char *nextParam;
for(int i = 0; i < paNumData; i++){
if(0 != paLayerParameter){
nextParam = strchr(paLayerParameter, scmParameterSeperator);
if(0 != nextParam){
*nextParam = '\0';
nextParam++;
}
mSFPItem[i] = getExtEvHandler<CEclipseSCADASFPHandler>().registerDataPoint(paLayerParameter, "Coment");
if(0 != mSFPItem[i]){
//write the initial value to the SFP server so that the data type of the item gets set
CEclipseSCADASFPHandler::updateDataPoint(mSFPItem[i], paDataArray[i]);
}else {
retVal = e_InitInvalidId;
break;
}
}else{
retVal = e_InitInvalidId;
break;
}
paLayerParameter = nextParam;
}
}
return retVal;
}