| /******************************************************************************* |
| * Copyright (c) 2005 - 2018 ACIN, Profactor GmbH, fortiss GmbH, |
| * Johannes Kepler University |
| * 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, Rene Smodic, Gerhard Ebenhofer, Thomas Strasser, |
| * Martin Melik Merkumians, |
| * - initial implementation and rework communication infrastructure |
| *******************************************************************************/ |
| #include <fortenew.h> |
| #include "resource.h" |
| #include "device.h" |
| #include "adapter.h" |
| #include "adapterconn.h" |
| #include "if2indco.h" |
| #include "utils/criticalregion.h" |
| #include "utils/fixedcapvector.h" |
| #include "ecet.h" |
| |
| #ifdef FORTE_DYNAMIC_TYPE_LOAD |
| #include "lua/luaengine.h" |
| #include "lua/luacfbtypeentry.h" |
| #include "lua/luabfbtypeentry.h" |
| #include "lua/luaadaptertypeentry.h" |
| #endif |
| |
| CResource::CResource(CResource* pa_poDevice, const SFBInterfaceSpec *pa_pstInterfaceSpec, const CStringDictionary::TStringId pa_nInstanceNameId, TForteByte *pa_acFBConnData, TForteByte *pa_acFBVarsData) : |
| CFunctionBlock(pa_poDevice, pa_pstInterfaceSpec, pa_nInstanceNameId, pa_acFBConnData, pa_acFBVarsData), forte::core::CFBContainer(CStringDictionary::scm_nInvalidStringId, 0), // the fbcontainer of resources does not have a seperate name as it is stored in the resource |
| mResourceEventExecution(CEventChainExecutionThread::createEcet()), mResIf2InConnections(0) |
| #ifdef FORTE_SUPPORT_MONITORING |
| , mMonitoringHandler(*this) |
| #endif |
| { |
| #ifdef FORTE_DYNAMIC_TYPE_LOAD |
| luaEngine = new CLuaEngine(); |
| #endif |
| initializeResIf2InConnections(); |
| } |
| |
| CResource::CResource(const SFBInterfaceSpec *pa_pstInterfaceSpec, const CStringDictionary::TStringId pa_nInstanceNameId, TForteByte *pa_acFBConnData, TForteByte *pa_acFBVarsData) : |
| CFunctionBlock(0, pa_pstInterfaceSpec, pa_nInstanceNameId, pa_acFBConnData, pa_acFBVarsData), forte::core::CFBContainer(CStringDictionary::scm_nInvalidStringId, 0), // the fbcontainer of resources does not have a seperate name as it is stored in the resource |
| mResourceEventExecution(0), mResIf2InConnections(0) |
| #ifdef FORTE_SUPPORT_MONITORING |
| , mMonitoringHandler(*this) |
| #endif |
| { |
| #ifdef FORTE_DYNAMIC_TYPE_LOAD |
| luaEngine = new CLuaEngine(); |
| #endif |
| initializeResIf2InConnections(); |
| } |
| |
| CResource::~CResource(){ |
| #ifdef FORTE_DYNAMIC_TYPE_LOAD |
| delete luaEngine; |
| #endif |
| delete mResourceEventExecution; |
| delete[] mResIf2InConnections; |
| } |
| |
| EMGMResponse CResource::executeMGMCommand(forte::core::SManagementCMD &paCommand){ |
| EMGMResponse retVal = e_INVALID_DST; |
| |
| if(CStringDictionary::scm_nInvalidStringId == paCommand.mDestination){ |
| switch (paCommand.mCMD){ |
| case cg_nMGM_CMD_Create_FBInstance: { |
| forte::core::TNameIdentifier::CIterator itRunner(paCommand.mFirstParam.begin()); |
| retVal = createFB(itRunner, paCommand.mSecondParam.front(), this); |
| } |
| break; |
| case cg_nMGM_CMD_Create_FBType: |
| #ifdef FORTE_DYNAMIC_TYPE_LOAD |
| retVal = createFBTypeFromLua(paCommand.mFirstParam.front(), paCommand.mAdditionalParams); |
| #else |
| retVal = e_UNSUPPORTED_CMD; |
| #endif |
| break; |
| case cg_nMGM_CMD_Create_AdapterType: |
| #ifdef FORTE_DYNAMIC_TYPE_LOAD |
| retVal = createAdapterTypeFromLua(paCommand.mFirstParam.front(), paCommand.mAdditionalParams); |
| #else |
| retVal = e_UNSUPPORTED_CMD; |
| #endif |
| break; |
| case cg_nMGM_CMD_Delete_FBInstance: { |
| forte::core::TNameIdentifier::CIterator itRunner(paCommand.mFirstParam.begin()); |
| retVal = deleteFB(itRunner); |
| } |
| break; |
| case cg_nMGM_CMD_Create_Connection: |
| retVal = createConnection(paCommand.mFirstParam, paCommand.mSecondParam); |
| break; |
| case cg_nMGM_CMD_Delete_Connection: |
| retVal = deleteConnection(paCommand.mFirstParam, paCommand.mSecondParam); |
| break; |
| case cg_nMGM_CMD_Read: |
| retVal = readValue(paCommand.mFirstParam, paCommand.mAdditionalParams); |
| break; |
| case cg_nMGM_CMD_Write: |
| retVal = writeValue(paCommand.mFirstParam, paCommand.mAdditionalParams); |
| break; |
| case cg_nMGM_CMD_Start: |
| case cg_nMGM_CMD_Stop: |
| case cg_nMGM_CMD_Kill: |
| case cg_nMGM_CMD_Reset: |
| retVal = handleExecutionStateCmd(paCommand.mCMD, paCommand.mFirstParam); |
| break; |
| #ifdef FORTE_SUPPORT_QUERY_CMD |
| case cg_nMGM_CMD_QUERY_FBTypes: |
| retVal = queryAllFBTypes(paCommand.mAdditionalParams); |
| break; |
| case cg_nMGM_CMD_QUERY_AdapterTypes: |
| retVal = queryAllAdapterTypes(paCommand.mAdditionalParams); |
| break; |
| case cg_nMGM_CMD_QUERY_FB: |
| retVal = queryFBs(paCommand.mAdditionalParams); |
| break; |
| case cg_nMGM_CMD_QUERY_FBType: |
| retVal = createFBTypeResponseMessage(paCommand.mFirstParam.front(), paCommand.mAdditionalParams); |
| break; |
| case cg_nMGM_CMD_QUERY_AdapterType: |
| retVal = createAdapterTypeResponseMessage(paCommand.mFirstParam.front(), paCommand.mAdditionalParams); |
| break; |
| case cg_nMGM_CMD_QUERY_Connection: |
| retVal = queryConnections(paCommand.mAdditionalParams); |
| break; |
| #endif //FORTE_SUPPORT_QUERY_CMD |
| default: |
| #ifdef FORTE_SUPPORT_MONITORING |
| retVal = mMonitoringHandler.executeMonitoringCommand(paCommand); |
| #else |
| retVal = e_UNSUPPORTED_CMD; |
| #endif |
| break; |
| } |
| } |
| return retVal; |
| } |
| |
| EMGMResponse CResource::changeFBExecutionState(EMGMCommandType pa_unCommand){ |
| EMGMResponse retVal = CFunctionBlock::changeFBExecutionState(pa_unCommand); |
| if(e_RDY == retVal){ |
| retVal = changeContainedFBsExecutionState(pa_unCommand); |
| if(e_RDY == retVal){ |
| if(cg_nMGM_CMD_Start == pa_unCommand && 0 != m_pstInterfaceSpec){ //on start, sample inputs |
| for(int i = 0; i < m_pstInterfaceSpec->m_nNumDIs; ++i){ |
| if(0 != m_apoDIConns[i]){ |
| m_apoDIConns[i]->readData(getDI(i)); |
| } |
| } |
| } |
| if(0 != mResourceEventExecution){ |
| // if we have a m_poResourceEventExecution handle it |
| mResourceEventExecution->changeExecutionState(pa_unCommand); |
| } |
| } |
| } |
| return retVal; |
| } |
| |
| EMGMResponse CResource::handleExecutionStateCmd(EMGMCommandType paCMD, forte::core::TNameIdentifier &paTarget){ |
| EMGMResponse retVal = e_NO_SUCH_OBJECT; |
| CFunctionBlock *fb = this; |
| |
| if(!paTarget.isEmpty()){ |
| forte::core::TNameIdentifier::CIterator itRunner(paTarget.begin()); |
| fb = getContainedFB(itRunner); |
| } |
| |
| if(0 != fb){ |
| retVal = fb->changeFBExecutionState(paCMD); |
| } |
| return retVal; |
| } |
| |
| EMGMResponse CResource::createConnection(forte::core::SManagementCMD &paCommand){ |
| return createConnection(paCommand.mFirstParam, paCommand.mSecondParam); |
| } |
| |
| EMGMResponse CResource::createConnection(forte::core::TNameIdentifier &paSrcNameList, forte::core::TNameIdentifier &paDstNameList){ |
| EMGMResponse retVal = e_NO_SUCH_OBJECT; |
| |
| CConnection *con = getConnection(paSrcNameList); |
| if(0 != con){ |
| CStringDictionary::TStringId portName = paDstNameList.back(); |
| paDstNameList.popBack(); |
| forte::core::TNameIdentifier::CIterator runner(paDstNameList.begin()); |
| CFunctionBlock *dstFB = getContainedFB(runner); |
| if((0 != dstFB) && (runner.isLastEntry())){ |
| retVal = con->connect(dstFB, portName); |
| } |
| } |
| |
| return retVal; |
| } |
| |
| EMGMResponse CResource::deleteConnection(forte::core::TNameIdentifier &paSrcNameList, forte::core::TNameIdentifier &paDstNameList){ |
| EMGMResponse retVal = e_NO_SUCH_OBJECT; |
| |
| CConnection *con = getConnection(paSrcNameList); |
| if(0 != con){ |
| CStringDictionary::TStringId portName = paDstNameList.back(); |
| paDstNameList.popBack(); |
| forte::core::TNameIdentifier::CIterator runner(paDstNameList.begin()); |
| CFunctionBlock *dstFB = getContainedFB(runner); |
| if((0 != dstFB) && (runner.isLastEntry())){ |
| retVal = con->disconnect(dstFB, portName); |
| } |
| } |
| |
| return retVal; |
| } |
| |
| EMGMResponse CResource::writeValue(forte::core::TNameIdentifier &paNameList, const CIEC_STRING & paValue, bool paForce){ |
| EMGMResponse retVal = e_NO_SUCH_OBJECT; |
| |
| CStringDictionary::TStringId portName = paNameList.back(); |
| paNameList.popBack(); |
| forte::core::TNameIdentifier::CIterator runner(paNameList.begin()); |
| |
| CFunctionBlock *fb = this; |
| if(paNameList.size() >= 1){ |
| //this is not an identifier for the resource interface |
| fb = getContainedFB(runner); // the last entry is the input name therefore reduce list here by one |
| } |
| |
| if((0 != fb) && (runner.isLastEntry())){ |
| CIEC_ANY *var = fb->getVar(&portName, 1); |
| if(0 != var){ |
| // 0 is not supported in the fromString method |
| if((paValue.length() > 0) && (paValue.length() == var->fromString(paValue.getValue()))){ |
| //if we cannot parse the full value the value is not valid |
| if(paForce){ |
| var->setForced(true); |
| CDataConnection *con = fb->getDOConnection(portName); |
| if(0 != con){ |
| //if we have got a connection it was a DO mirror the forced value there |
| CCriticalRegion criticalRegion(m_oResDataConSync); |
| con->writeData(var); |
| } |
| } |
| retVal = e_RDY; |
| } |
| else{ |
| retVal = e_BAD_PARAMS; |
| } |
| } |
| } |
| return retVal; |
| } |
| |
| EMGMResponse CResource::readValue(forte::core::TNameIdentifier &paNameList, CIEC_STRING & paValue){ |
| EMGMResponse retVal = e_NO_SUCH_OBJECT; |
| CIEC_ANY *var = getVariable(paNameList); |
| if(0 != var){ |
| int nUsedChars = -1; |
| switch (var->getDataTypeID()){ |
| case CIEC_ANY::e_WSTRING: |
| case CIEC_ANY::e_STRING:{ |
| size_t bufferSize = var->getToStringBufferSize() + forte::core::util::getExtraSizeForXMLEscapedChars(static_cast<CIEC_WSTRING&>(*var).getValue()); |
| nUsedChars = static_cast<CIEC_WSTRING&>(*var).toUTF8(paValue.getValue(), bufferSize, false); |
| if(bufferSize != var->getToStringBufferSize() && 0 < nUsedChars) { //avoid re-running on strings which were already proven not to have any special character |
| nUsedChars += static_cast<int>(forte::core::util::transformNonEscapedToEscapedXMLText(paValue.getValue())); |
| } |
| break; |
| } |
| default: |
| nUsedChars = var->toString(paValue.getValue(), paValue.getCapacity()); |
| break; |
| } |
| |
| if(-1 != nUsedChars){ |
| paValue.assign(paValue.getValue(), static_cast<TForteUInt16>(nUsedChars)); |
| retVal = e_RDY; |
| } |
| else{ |
| retVal = e_INVALID_OBJECT; |
| } |
| } |
| return retVal; |
| } |
| |
| #ifdef FORTE_SUPPORT_QUERY_CMD |
| |
| EMGMResponse CResource::queryAllFBTypes(CIEC_STRING & paValue){ |
| EMGMResponse retVal = e_UNSUPPORTED_TYPE; |
| |
| CTypeLib::CTypeEntry *fbTypeRunner = CTypeLib::getFBLibStart(); |
| if(fbTypeRunner != 0){ |
| retVal = e_RDY; |
| for(; fbTypeRunner != 0; fbTypeRunner = fbTypeRunner->m_poNext){ |
| paValue.append(CStringDictionary::getInstance().get(fbTypeRunner->getTypeNameId())); |
| if(fbTypeRunner->m_poNext != 0){ |
| paValue.append(", "); |
| } |
| } |
| } |
| return retVal; |
| } |
| |
| EMGMResponse CResource::queryAllAdapterTypes(CIEC_STRING & paValue){ |
| EMGMResponse retVal = e_UNSUPPORTED_TYPE; |
| |
| CTypeLib::CTypeEntry *adapterTypeRunner = CTypeLib::getAdapterLibStart(); |
| if(adapterTypeRunner != 0){ |
| retVal = e_RDY; |
| for(; adapterTypeRunner != 0; adapterTypeRunner = adapterTypeRunner->m_poNext){ |
| paValue.append(CStringDictionary::getInstance().get(adapterTypeRunner->getTypeNameId())); |
| if(adapterTypeRunner->m_poNext != 0){ |
| paValue.append(", "); |
| } |
| } |
| } |
| return retVal; |
| } |
| |
| EMGMResponse CResource::queryFBs(CIEC_STRING & paValue){ |
| for(TFunctionBlockList::Iterator itRunner(getFBList().begin()); itRunner != getFBList().end(); ++itRunner){ |
| if(itRunner != getFBList().begin()){ |
| paValue.append("\n"); |
| } |
| paValue.append("<FB name=\""); |
| paValue.append((static_cast<CFunctionBlock *>(*itRunner))->getInstanceName()); |
| paValue.append("\" type=\""); |
| paValue.append(CStringDictionary::getInstance().get((static_cast<CFunctionBlock *>(*itRunner))->getFBTypeId())); |
| paValue.append("\"/>"); |
| } |
| return e_RDY; |
| } |
| |
| EMGMResponse CResource::queryConnections(CIEC_STRING & paReqResult){ |
| EMGMResponse retVal = e_UNSUPPORTED_TYPE; |
| //TODO check container list to support subapps issue[538333] |
| for(TFunctionBlockList::Iterator itRunner(getFBList().begin()); itRunner != getFBList().end(); ++itRunner){ |
| createEOConnectionResponse(**itRunner, paReqResult); |
| createDOConnectionResponse(**itRunner, paReqResult); |
| createAOConnectionResponse(**itRunner, paReqResult); |
| } |
| retVal = e_RDY; |
| return retVal; |
| } |
| |
| void CResource::createEOConnectionResponse(const CFunctionBlock& paFb, CIEC_STRING& paReqResult){ |
| const SFBInterfaceSpec * const spec = paFb.getFBInterfaceSpec(); |
| if(spec->m_nNumEOs > 0){ |
| for(size_t i = 0; spec->m_aunEONames[i] != spec->m_aunEONames[spec->m_nNumEOs]; i++){ |
| const CEventConnection* eConn = paFb.getEOConnection(spec->m_aunEONames[i]); |
| for(CSinglyLinkedList<CConnectionPoint>::Iterator itRunnerDst(eConn->getDestinationList().begin()); itRunnerDst != eConn->getDestinationList().end(); |
| ++itRunnerDst){ |
| if(itRunnerDst != eConn->getDestinationList().begin()){ |
| paReqResult.append("\n"); |
| } |
| createConnectionResponseMessage(spec->m_aunEONames[i], itRunnerDst->mFB->getFBInterfaceSpec()->m_aunEINames[itRunnerDst->mPortId], *itRunnerDst->mFB, |
| paFb, paReqResult); |
| } |
| } |
| } |
| } |
| |
| void CResource::createDOConnectionResponse(const CFunctionBlock& paFb, CIEC_STRING& paReqResult){ |
| const SFBInterfaceSpec * const spec = paFb.getFBInterfaceSpec(); |
| if(spec->m_nNumDOs > 0){ |
| for(size_t i = 0; spec->m_aunDONames[i] != spec->m_aunDONames[spec->m_nNumDOs]; i++){ |
| const CDataConnection * const dConn = paFb.getDOConnection(spec->m_aunDONames[i]); |
| for(CSinglyLinkedList<CConnectionPoint>::Iterator itRunnerDst(dConn->getDestinationList().begin()); itRunnerDst != dConn->getDestinationList().end(); |
| ++itRunnerDst){ |
| if(itRunnerDst != dConn->getDestinationList().begin()){ |
| paReqResult.append("\n"); |
| } |
| createConnectionResponseMessage(spec->m_aunDONames[i], itRunnerDst->mFB->getFBInterfaceSpec()->m_aunDINames[itRunnerDst->mPortId], *itRunnerDst->mFB, |
| paFb, paReqResult); |
| } |
| } |
| } |
| } |
| |
| void CResource::createAOConnectionResponse(const CFunctionBlock& paFb, CIEC_STRING& paReqResult){ |
| const SFBInterfaceSpec * const spec = paFb.getFBInterfaceSpec(); |
| if(spec->m_nNumAdapters > 0){ |
| for(size_t i = 0; i < spec->m_nNumAdapters; i++){ |
| const CAdapter * const adapter = paFb.getAdapter(spec->m_pstAdapterInstanceDefinition[i].m_nAdapterNameID); |
| const CAdapterConnection* aConn = adapter->getAdapterConnection(); |
| if(spec->m_pstAdapterInstanceDefinition[i].m_bIsPlug && 0 != aConn){ |
| if(i != 0){ |
| paReqResult.append("\n"); |
| } |
| if(!aConn->getDestinationList().isEmpty()){ |
| CSinglyLinkedList<CConnectionPoint>::Iterator itRunnerDst(aConn->getDestinationList().begin()); |
| createConnectionResponseMessage(spec->m_pstAdapterInstanceDefinition[i].m_nAdapterNameID, |
| itRunnerDst->mFB->getFBInterfaceSpec()->m_pstAdapterInstanceDefinition[itRunnerDst->mPortId].m_nAdapterNameID, *itRunnerDst->mFB, paFb, |
| paReqResult); |
| } |
| } |
| } |
| } |
| } |
| |
| void CResource::createConnectionResponseMessage(const CStringDictionary::TStringId srcId, const CStringDictionary::TStringId dstId, |
| const CFunctionBlock& paDstFb, const CFunctionBlock& paSrcFb, CIEC_STRING& paReqResult) const { |
| paReqResult.append("<Connection Source=\""); |
| paReqResult.append(paSrcFb.getInstanceName()); |
| paReqResult.append("."); |
| paReqResult.append(CStringDictionary::getInstance().get(srcId)); |
| paReqResult.append("\" Destination=\""); |
| paReqResult.append(paDstFb.getInstanceName()); |
| paReqResult.append("."); |
| paReqResult.append(CStringDictionary::getInstance().get(dstId)); |
| paReqResult.append("\"/>"); |
| } |
| |
| EMGMResponse CResource::createFBTypeResponseMessage(const CStringDictionary::TStringId paValue, CIEC_STRING & paReqResult){ |
| EMGMResponse retVal = e_UNSUPPORTED_TYPE; |
| CTypeLib::CFBTypeEntry* fbType = static_cast<CTypeLib::CFBTypeEntry *>(CTypeLib::findType(paValue, CTypeLib::getFBLibStart())); |
| if(0 != fbType){ |
| retVal = createXTypeResponseMessage(fbType, paValue, retVal, paReqResult); |
| } |
| return retVal; |
| } |
| |
| EMGMResponse CResource::createAdapterTypeResponseMessage(const CStringDictionary::TStringId paValue, CIEC_STRING & paReqResult){ |
| EMGMResponse retVal = e_UNSUPPORTED_TYPE; |
| CTypeLib::CAdapterTypeEntry* adapterType = static_cast<CTypeLib::CAdapterTypeEntry *>(CTypeLib::findType(paValue, CTypeLib::getAdapterLibStart())); |
| if(0 != adapterType){ |
| retVal = createXTypeResponseMessage(adapterType, paValue, retVal, paReqResult); |
| } |
| return retVal; |
| } |
| |
| EMGMResponse CResource::createXTypeResponseMessage(const CTypeLib::CSpecTypeEntry* paTypeEntry, const CStringDictionary::TStringId paValue, EMGMResponse retVal, CIEC_STRING& paReqResult){ |
| const SFBInterfaceSpec* paInterfaceSpec = paTypeEntry->getInterfaceSpec(); |
| if(0 != paInterfaceSpec){ |
| paReqResult.append("Name=\""); |
| paReqResult.append(CStringDictionary::getInstance().get(paValue)); |
| paReqResult.append("\">\n <InterfaceList>\n "); |
| createEventInterfaceResponseMessage(paInterfaceSpec, paReqResult); |
| createDataInterfaceResponseMessage(paInterfaceSpec, paReqResult); |
| createAdapterInterfaceResponseMessage(paInterfaceSpec, paReqResult); |
| paReqResult.append("</InterfaceList>\n"); |
| retVal = e_RDY; |
| } |
| return retVal; |
| } |
| |
| void CResource::createEventInterfaceResponseMessage(const SFBInterfaceSpec* paInterfaceSpec, CIEC_STRING& paReqResult){ |
| if(paInterfaceSpec->m_nNumEIs > 0){ |
| paReqResult.append("<EventInputs>\n "); |
| createInterfaceResponseMessages(paReqResult, "Event", paInterfaceSpec->m_aunEINames, NULL, paInterfaceSpec->m_nNumEIs, paInterfaceSpec->m_anEIWith, paInterfaceSpec->m_anEIWithIndexes, paInterfaceSpec->m_aunDINames); |
| paReqResult.append("</EventInputs>\n "); |
| } |
| if(paInterfaceSpec->m_nNumEOs > 0){ |
| paReqResult.append("<EventOutputs>\n "); |
| createInterfaceResponseMessages(paReqResult, "Event", paInterfaceSpec->m_aunEONames, NULL, paInterfaceSpec->m_nNumEOs, paInterfaceSpec->m_anEOWith, paInterfaceSpec->m_anEOWithIndexes, paInterfaceSpec->m_aunDONames); |
| paReqResult.append("</EventOutputs>\n "); |
| } |
| } |
| |
| void CResource::createDataInterfaceResponseMessage(const SFBInterfaceSpec* paInterfaceSpec, CIEC_STRING& paReqResult){ |
| if(paInterfaceSpec->m_nNumDIs > 0){ |
| paReqResult.append("<InputVars>\n "); |
| createInterfaceResponseMessages(paReqResult, "VarDeclaration", paInterfaceSpec->m_aunDINames, paInterfaceSpec->m_aunDIDataTypeNames, paInterfaceSpec->m_nNumDIs); |
| paReqResult.append("</InputVars>\n "); |
| } |
| if(paInterfaceSpec->m_nNumDOs > 0){ |
| paReqResult.append("<OutputVars>\n "); |
| createInterfaceResponseMessages(paReqResult, "VarDeclaration", paInterfaceSpec->m_aunDONames, paInterfaceSpec->m_aunDODataTypeNames, paInterfaceSpec->m_nNumDOs); |
| paReqResult.append("</OutputVars>\n "); |
| } |
| } |
| |
| void CResource::createAdapterInterfaceResponseMessage(const SFBInterfaceSpec* paInterfaceSpec, CIEC_STRING& paReqResult){ |
| if(paInterfaceSpec->m_nNumAdapters > 0){ |
| CIEC_STRING sockets = ""; |
| CIEC_STRING plugs = ""; |
| for(int i = 0; i < paInterfaceSpec->m_nNumAdapters; i++){ |
| if(paInterfaceSpec->m_pstAdapterInstanceDefinition[i].m_bIsPlug){ |
| createInterfaceResponseMessage(plugs, "AdapterDeclaration", CStringDictionary::getInstance().get(paInterfaceSpec->m_pstAdapterInstanceDefinition[i].m_nAdapterNameID), CStringDictionary::getInstance().get(paInterfaceSpec->m_pstAdapterInstanceDefinition[i].m_nAdapterTypeNameID)); |
| } |
| else{ |
| createInterfaceResponseMessage(sockets, "AdapterDeclaration", CStringDictionary::getInstance().get(paInterfaceSpec->m_pstAdapterInstanceDefinition[i].m_nAdapterNameID), CStringDictionary::getInstance().get(paInterfaceSpec->m_pstAdapterInstanceDefinition[i].m_nAdapterTypeNameID)); |
| } |
| } |
| if(plugs != ""){ |
| paReqResult.append("<Plugs>\n "); |
| paReqResult.append(plugs.getValue()); |
| paReqResult.append("</Plugs>\n "); |
| } |
| if(sockets != ""){ |
| paReqResult.append("<Sockets>\n "); |
| paReqResult.append(sockets.getValue()); |
| paReqResult.append("</Sockets>\n "); |
| } |
| } |
| } |
| |
| void CResource::createInterfaceResponseMessages(CIEC_STRING &paReqResult, const char *pa_pcType, |
| const CStringDictionary::TStringId* paNameList, const CStringDictionary::TStringId* paTypeList, |
| const int pa_nNumberOfElements, const TDataIOID* paEWith, const TForteInt16* paEWithIndexes, const CStringDictionary::TStringId* paDNameList){ |
| for(int nIndex = 0; nIndex < pa_nNumberOfElements; nIndex++){ |
| if(NULL != paTypeList){ |
| createInterfaceResponseMessage(paReqResult, pa_pcType, CStringDictionary::getInstance().get(paNameList[nIndex]), CStringDictionary::getInstance().get(paTypeList[nIndex])); |
| } |
| else{ |
| createInterfaceResponseMessage(paReqResult, pa_pcType, CStringDictionary::getInstance().get(paNameList[nIndex]), "Event", paEWith, paEWithIndexes, nIndex, paDNameList); |
| } |
| } |
| } |
| |
| void CResource::createInterfaceResponseMessage(CIEC_STRING& paReqResult, const char* pa_pcType, const CIEC_STRING& paName, const CIEC_STRING& paType, |
| const TDataIOID* paEWith, const TForteInt16* paEWithIndexes, const int pa_nIndex, const CStringDictionary::TStringId* paENameList) const { |
| paReqResult.append("<"); |
| paReqResult.append(pa_pcType); |
| paReqResult.append(" Name=\""); |
| paReqResult.append(paName.getValue()); |
| paReqResult.append("\" Type=\""); |
| paReqResult.append(paType.getValue()); |
| if(0 != paEWithIndexes && -1 != paEWithIndexes[pa_nIndex]){ |
| paReqResult.append("\">\n "); |
| for(int nRunIndex = paEWithIndexes[pa_nIndex]; scmWithListDelimiter != paEWith[nRunIndex]; nRunIndex++){ |
| paReqResult.append("<With Var=\""); |
| paReqResult.append(CStringDictionary::getInstance().get(paENameList[paEWith[nRunIndex]])); |
| paReqResult.append("\"/>\n "); |
| } |
| paReqResult.append("</Event>\n "); |
| } |
| else{ |
| paReqResult.append("\"/>\n"); |
| } |
| } |
| #endif //FORTE_SUPPORT_QUERY_CMD |
| |
| #ifdef FORTE_DYNAMIC_TYPE_LOAD |
| EMGMResponse CResource::createFBTypeFromLua(CStringDictionary::TStringId typeNameId, |
| CIEC_STRING& paLuaScriptAsString){ |
| EMGMResponse retVal = e_UNSUPPORTED_TYPE; |
| if(NULL != strstr(paLuaScriptAsString.getValue(), "internalFBs")){ // CFBType |
| if(CLuaCFBTypeEntry::createLuaFBTypeEntry(typeNameId, paLuaScriptAsString) != NULL){ |
| retVal = e_RDY; |
| } |
| else{ |
| retVal = e_INVALID_OPERATION; |
| } |
| } |
| else{ // BFBType |
| if(CLuaBFBTypeEntry::createLuaFBTypeEntry(typeNameId, paLuaScriptAsString) != NULL){ |
| retVal = e_RDY; |
| } |
| else{ |
| retVal = e_INVALID_OPERATION; |
| } |
| } |
| paLuaScriptAsString.clear(); |
| return retVal; |
| } |
| |
| EMGMResponse CResource::createAdapterTypeFromLua(CStringDictionary::TStringId typeNameId, |
| CIEC_STRING& paLuaScriptAsString){ |
| EMGMResponse retVal = e_UNSUPPORTED_TYPE; |
| if(CLuaAdapterTypeEntry::createLuaAdapterTypeEntry(typeNameId, paLuaScriptAsString) != NULL){ |
| retVal = e_RDY; |
| }else{ |
| retVal = e_INVALID_OPERATION; |
| } |
| paLuaScriptAsString.clear(); |
| return retVal; |
| } |
| |
| #endif //FORTE_DYNAMIC_TYPE_LOAD |
| |
| CIEC_ANY *CResource::getVariable(forte::core::TNameIdentifier &paNameList){ |
| CStringDictionary::TStringId portName = paNameList.back(); |
| paNameList.popBack(); |
| forte::core::TNameIdentifier::CIterator runner(paNameList.begin()); |
| |
| CFunctionBlock *fb = this; |
| if(paNameList.size() >= 1){ |
| //this is not an identifier for the resource interface |
| fb = getContainedFB(runner); // the last entry is the input name therefore reduce list here by one |
| } |
| |
| CIEC_ANY *var = 0; |
| if((0 != fb) && (runner.isLastEntry())){ |
| var = fb->getVar(&portName, 1); |
| } |
| return var; |
| } |
| |
| CConnection *CResource::getConnection(forte::core::TNameIdentifier &paSrcNameList){ |
| CConnection *con = 0; |
| if(1 == paSrcNameList.size()){ |
| con = getResIf2InConnection(paSrcNameList[0]); |
| } |
| else if(paSrcNameList.size() > 1){ |
| CStringDictionary::TStringId portName = paSrcNameList.back(); |
| paSrcNameList.popBack(); |
| forte::core::TNameIdentifier::CIterator runner(paSrcNameList.begin()); |
| |
| CFunctionBlock *srcFB = getContainedFB(runner); |
| if((0 != srcFB) && (runner.isLastEntry())){ |
| //only use the found result if we have really the last result in the list |
| con = srcFB->getEOConnection(portName); |
| if(0 == con){ |
| //it is not an event connection try data connection next |
| con = srcFB->getDOConnection(portName); |
| if(0 == con){ |
| //it is not an data connection try data connection next |
| //TODO think if it would be better to move this to CFunctionBlock |
| CAdapter *adp = srcFB->getAdapter(portName); |
| if((0 != adp) && (adp->isPlug())){ |
| //only plugs hold the connection object |
| con = adp->getAdapterConnection(); |
| } |
| } |
| } |
| } |
| } |
| return con; |
| } |
| |
| CConnection *CResource::getResIf2InConnection(CStringDictionary::TStringId paResInput) const{ |
| CConnection *con = 0; |
| if(0 != m_pstInterfaceSpec){ |
| TPortId inPortId = getDIID(paResInput); |
| if(cg_unInvalidPortId != inPortId){ |
| con = mResIf2InConnections + inPortId; |
| } |
| } |
| return con; |
| } |
| |
| void CResource::initializeResIf2InConnections(){ |
| if(0 != m_pstInterfaceSpec){ |
| mResIf2InConnections = new CInterface2InternalDataConnection[m_pstInterfaceSpec->m_nNumDIs]; |
| for(TPortId i = 0; i < m_pstInterfaceSpec->m_nNumDIs; i++){ |
| (mResIf2InConnections + i)->setSource(this, i); |
| } |
| } |
| } |