⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cm_targt.c

📁 基于EthernetIP协议的应用程序,可以读取AB公司Controllogix系列Ethernetip协议PLC数据. 此软件代码可用于工业控制.
💻 C
📖 第 1 页 / 共 5 页
字号:
   */

   /*
   ** If we have issued an 'app open' or an 'app open complete' request,
   ** make sure we received the reply before continuing.
   */

   if( ( psConnRecord->iSteps & CM_PS_AO_ISSUED )
     && !( psConnRecord->iSteps & CM_PS_AO_RETURNED ) )
   {
      return;
   }

   if( ( psConnRecord->iSteps & CM_PS_AOC_ISSUED )
     && !( psConnRecord->iSteps & CM_PS_AOC_RETURNED ) )
   {
      return;
   }


   /*
   ** If we have issued a transport reserve or start request,
   ** make sure we receive the reply before continuing.
   */

   if( ( psConnRecord->iSteps & CM_PS_R_TRAN_ISSUED )
     && !( psConnRecord->iSteps & CM_PS_R_TRAN_RETURNED  ) )
   {
      return;
   }

   if( ( psConnRecord->iSteps & CM_PS_S_TRAN_ISSUED )
     && !( psConnRecord->iSteps & CM_PS_S_TRAN_RETURNED  ) )
   {
      return;
   }

   /*
   ** If we have issued a forward open,
   ** make sure we receive the reply before continuing.
   */

   if( ( psConnRecord->iSteps & CM_PS_FO_ISSUED )
      && !( psConnRecord->iSteps & CM_PS_FO_RETURNED ) )
   {
      return;
   }

   /*----------------------------------------------------------
   ** All requests have returned.
   ** It is now save to continue closeing this connection.
   **----------------------------------------------------------
   */


   /*
   ** If we're an originator issue the forward close packet and
   ** wait for the reply.
   */

   /*
   ** Issue the app close and wait for the reply.
   */

   if( !( psConnRecord->iSteps & CM_PS_AC_ISSUED ) )
   {
      cm_IssueAppOpenClose( psConnRecord );
      return;
   }

   if( !( psConnRecord->iSteps & CM_PS_AC_RETURNED ) )
   {
      return;
   }

   /*
   ** If there are any transports running, shut them down.
   ** Wait for the shutdown to complete.
   */

   if( CM_IsConnectionTypeNull( &(psConnRecord->sPublic) ) )
   {
      /*
      ** Null Open's bypass the Transport Deletion process so,
      ** set bits to indicate Transport Deletion is complete.
      */

      psConnRecord->iSteps |= ( CM_PS_D_TRAN_ISSUED | CM_PS_D_TRAN_RETURNED );
   }

   if( !( psConnRecord->iSteps & CM_PS_D_TRAN_ISSUED ) )
   {
      pTrrbl = GS_NewTrrbl( CD_TransportTrrblType );
      pTrrbl->eRequest     = TREQ_DELETE_TRANSPORTS;
      pTrrbl->xReturnQueue = CM_xQid;
      pTrrbl->psConnRecord = &psConnRecord->sPublic;
      GS_PutTrrbl( CD_s[ psConnRecord->sPublic.iPort ].xConfigQid, pTrrbl );
      psConnRecord->iSteps |= CM_PS_D_TRAN_ISSUED;
      return;
   }

   if( !( psConnRecord->iSteps & CM_PS_D_TRAN_RETURNED ) )
   {
      return;
   }

   /*
   ** Return any forward open and forward close response packets.
   ** Forward open is handled on the first call, forward close on the second.
   */

   cm_IssueFwdReply( psConnRecord );
   cm_IssueFwdReply( psConnRecord );

   /*
   ** If we're an originator, return the origination request tribble.
   */

   /*
   ** Generate an event indicating that the connection has been closed.
   */
	pIdTrrbl = GS_NewTrrbl( ID_TrrblType );
	pIdTrrbl->eRequest    = TREQ_UPDATE_STATUS;
	pIdTrrbl->iStatusMask = ID_STATUS_OWNED_MASK;
	pIdTrrbl->iStatus     = ID_STATUS_UNOWNED;
	GS_PutTrrbl( ID_xQid, pIdTrrbl );

   if( CM_IsConnectionTypeNull( &(psConnRecord->sPublic) ) )
   {
      GS_LogEvent( CM_CONNECTION_NULL_ERROR, psConnRecord->sPublic.iConnectionSn, 0, TRIVIAL );
   }
   else if( ( psConnRecord->sPublic.bClassTrigger & CM_TCT_CLASS_MASK ) == CM_TCT_CLASS_1 )
   {
      GS_LogEvent( CM_CONNECTION_CLASS_1_CLOSING, psConnRecord->sPublic.iConnectionSn, 0, TRIVIAL );

	  /*
	  ** start edits: September,20th 2005, H.F.
	  **
	  ** set Consumer, Producer and Config Assembly to "Inactive" state, if
	  ** they are no longer used in any connection
	  */

	  /* Get the Assembly Instances and transition to Inactive */
	  if( aConsumerAssemblyInstance=EC_FindUserDefinedAssemblyInstance( psConnRecord->sPublic.iConConnPoint ) )
	  {
		  if( psConnRecord->iState & CM_PS_OPEN )
			  aConsumerAssemblyInstance->itsIOConnectionCount--;

		  if( !aConsumerAssemblyInstance->itsIOConnectionCount )
		  {
			  /* Consumer Assemblies additionally become idle */
			  aConsumerAssemblyInstance->itsState &= 0xFFF8;
			  aConsumerAssemblyInstance->itsState |= 0x0002;

			  /*
			  ** start edits: October,14th 2005, H.F.
			  */

			  SY_RunIdleArea[aConsumerAssemblyInstance->itsAppDataAreaId-AD_APP_DATA_AREA_EC_BASE] = 0;

			  /*
			  ** end edits: October,14th 2005, H.F.
			  */


			  GS_EnterCritical();
			  {
				  EC_Run_IdleCB( FALSE, psConnRecord->sPublic.iConConnPoint );
			  }
			  GS_ExitCritical();

			  /*
			  ** start edits: September,23rd 2005, H.F.
			  */

			  EC_AssemblyStateCB( 1 /* inactive */, aConsumerAssemblyInstance->itsInstanceNo );

			  /*
			  ** end edits: September,23rd 2005, H.F.
			  */
		  }
	  }
	  if( aProducerAssemblyInstance=EC_FindUserDefinedAssemblyInstance( psConnRecord->sPublic.iProConnPoint ) )
	  {
		  if( psConnRecord->iState & CM_PS_OPEN )
			  aProducerAssemblyInstance->itsIOConnectionCount--;

		  if( !aProducerAssemblyInstance->itsIOConnectionCount )
		  {
			  aProducerAssemblyInstance->itsState &= 0xFFF9;
			  aProducerAssemblyInstance->itsState |= 0x0002;

			  /*
			  ** start edits: September,23rd 2005, H.F.
			  */

			  EC_AssemblyStateCB( 1 /* inactive */, aProducerAssemblyInstance->itsInstanceNo );

			  /*
			  ** end edits: September,23rd 2005, H.F.
			  */


			  /*
			  ** start edits: October,14th 2005, H.F.
			  **
			  ** set idle in SY_RunIdleArea, as the producer is not
			  ** producing data any longer
			  */

			  SY_RunIdleArea[aProducerAssemblyInstance->itsAppDataAreaId-AD_APP_DATA_AREA_EC_BASE] = 0;

			  /*
			  ** end edits: October,14th 2005, H.F.
			  */

		  }
	  }
	  if( aConfigAssemblyInstance=EC_FindUserDefinedAssemblyInstance( psConnRecord->sPublic.iInstance ) )
	  {
		  if( psConnRecord->iState & CM_PS_OPEN )
			  aConfigAssemblyInstance->itsIOConnectionCount--;

		  if( !aConfigAssemblyInstance->itsIOConnectionCount )
		  {
			  /*
			  ** start edits: October,6th 2005, H.F.
			  **

			  aConfigAssemblyInstance->itsState &= 0xFFF9;

			  **
			  ** Config. Assemblies additionally become idle and not-configured
			  **
			  */

			  aConfigAssemblyInstance->itsState &= 0xFFF0;

			  /*
			  ** end edits: October,6th 2005, H.F.
			  */


			  /*
			  ** start edits: October,14th 2005, H.F.
			  */

			  SY_RunIdleArea[aConfigAssemblyInstance->itsAppDataAreaId-AD_APP_DATA_AREA_EC_BASE] = 0;

			  /*
			  ** end edits: October,14th 2005, H.F.
			  */

			  
			  aConfigAssemblyInstance->itsState |= 0x0002;

			  /*
			  ** start edits: September,23rd 2005, H.F.
			  */

			  EC_AssemblyStateCB( 1 /* inactive */, aConfigAssemblyInstance->itsInstanceNo );

			  /*
			  ** end edits: September,23rd 2005, H.F.
			  */
		  }
	  }

	  /*
	  ** end edits: September,20th 2005, H.F.
	  */

   }
   else
   {
      GS_LogEvent( CM_CONNECTION_CLASS_3_CLOSING, psConnRecord->sPublic.iConnectionSn, 0, TRIVIAL );
   }


   /*
   ** start edits: September,9th 2005, H.F.
   **
   ** Check, if an Exclusive Owner Connection will be closed
   ** and release the Consumer Assembly Instance then
   */

   if( psConnRecord->sPublic.bExclusiveOwnerConn )
   {
	   aConsumerAssemblyInstance=EC_FindUserDefinedAssemblyInstance( psConnRecord->sPublic.iConConnPoint );
	   aConsumerAssemblyInstance->itsExclusiveOwnedStatus = 0;	/* not exclusive owned */
   }

   /*
   ** end edits: September,9th 2005, H.F.
   */

   
   cm_DeleteCR( psConnRecord );


} /* end of cm_ContinueClosing() */


/*---------------------------------------------------------------------------
** cm_ContinueOpening()
**---------------------------------------------------------------------------
*/

void cm_ContinueOpening( cm_ConnectionRecordType *psConnRecord )
{
   CD_TransportTrrblType *pTrrbl;
   ID_TrrblType             *pIdTrrbl;


   /*
   ** start edits: September,20th 2005, H.F.
   */

   t_UserDefinedAssemblyInstance   *aConsumerAssemblyInstance;
   t_UserDefinedAssemblyInstance   *aProducerAssemblyInstance;
   t_UserDefinedAssemblyInstance   *aConfigAssemblyInstance;

   /*
   ** end edits: September,20th 2005, H.F.
   */

   
   /*
   ** Make sure we received the app open reply before continuing.
   */

   if( !( psConnRecord->iSteps & CM_PS_AO_RETURNED ) )
   {
      return;
   }

   /*
   ** Reserve any new transports.
   ** Reused (multicast) transports will be filled in via the app open.
   ** Null Open's bypass the Reserve process.
   */

   if( CM_IsConnectionTypeNull( &(psConnRecord->sPublic) ) )
   {
      /*
      ** Null Open's bypass the Reserve process so,
      ** set bits to indicate Reserve is complete.
      */

      psConnRecord->iSteps |= ( CM_PS_R_TRAN_ISSUED | CM_PS_R_TRAN_RETURNED );
   }

   if( !( psConnRecord->iSteps & CM_PS_R_TRAN_ISSUED ) )
   {
      pTrrbl = GS_NewTrrbl( CD_TransportTrrblType );
      pTrrbl->eRequest     = TREQ_RESERVE_TRANSPORTS;
      pTrrbl->xReturnQueue = CM_xQid;
      pTrrbl->psConnRecord = &psConnRecord->sPublic;
      GS_PutTrrbl( CD_s[ psConnRecord->sPublic.iPort ].xConfigQid, pTrrbl );
      psConnRecord->iSteps |= CM_PS_R_TRAN_ISSUED;
      return;
   }

   if( !( psConnRecord->iSteps & CM_PS_R_TRAN_RETURNED ) )
   {
      return;
   }

   /*
   ** Start all transports.
   ** Null Open's bypass the Start and the AppOpenComplete process.
   */

   if( CM_IsConnectionTypeNull( &(psConnRecord->sPublic) ) )
   {
      /*
      ** Null Open's bypass the Start and AppOpenComplete process so,
      ** set bits to indicate Start and AppOpenComplete is complete.
      */

      psConnRecord->iSteps |= ( CM_PS_S_TRAN_ISSUED |
                                CM_PS_S_TRAN_RETURNED |
                                CM_PS_AOC_ISSUED |
                                CM_PS_AOC_RETURNED );
   }


   if( !( psConnRecord->iSteps & CM_PS_S_TRAN_ISSUED ) )
   {
      pTrrbl = GS_NewTrrbl( CD_TransportTrrblType );
      pTrrbl->eRequest     = TREQ_START_TRANSPORTS;
      pTrrbl->xReturnQueue = CM_xQid;
      pTrrbl->psConnRecord = &psConnRecord->sPublic;
      GS_PutTrrbl( CD_s[ psConnRecord->sPublic.iPort ].xConfigQid, pTrrbl );
      psConnRecord->iSteps |= CM_PS_S_TRAN_ISSUED;
      return;
   }

   if( !( psConnRecord->iSteps & CM_PS_S_TRAN_RETURNED ) )
   {
      return;
   }

   /*
   ** Issue an app open complete to the object being connected to.
   ** Wait for the response before continuing.
   */

   if( !( psConnRecord->iSteps & CM_PS_AOC_ISSUED ) )
   {
      cm_IssueAppOpenClose( psConnRecord );
      return;
   }

   if( !( psConnRecord->iSteps & CM_PS_AOC_RETURNED ) )
   {
      return;
   }

   /*
   ** Return the forward open reply if we're a target.
   ** Return the originate tribble if we're the originator.
   */

   if( psConnRecord->pTrrblFO != NULL )
   {
      cm_IssueFwdReply( psConnRecord );
   }

   /*
   ** Bump the connection state to indicate successful opening.
   */

   psConnRecord->iState |= CM_PS_OPEN;

   /*
   ** Generate an event indicating that the connection is up and running.
   */

	pIdTrrbl = GS_NewTrrbl( ID_TrrblType );
	pIdTrrbl->eRequest    = TREQ_UPDATE_STATUS;
	pIdTrrbl->iStatusMask = ID_STATUS_OWNED_MASK;
	pIdTrrbl->iStatus     = ID_STATUS_OWNED;
	GS_PutTrrbl( ID_xQid, pIdTrrbl );

   if( CM_IsConnectionTypeNull( &(psConnRecord->sPublic) ) )
   {
      GS_LogEvent( CM_CONNECTION_NULL, psConnRecord->sPublic.iConnectionSn, 0, TRIVIAL );
      cm_DeleteCR( psConnRecord );
   }
   else if( ( psConnRecord->sPublic.bClassTrigger & CM_TCT_CLASS_MASK ) == CM_TCT_CLASS_1 )
   {
      GS_LogEvent( CM_CONNECTION_CLASS_1_OPEN, psConnRecord->sPublic.iConnectionSn, 0, TRIVIAL );


	  /*
	  ** start edits: September,20th 2005, H.F.
	  **
	  ** set Consumer, Producer and Config Assembly to "Active" state
	  ** and increase their Connection Counts
	  */

	  /* Get the Assembly Instances and transition to Active */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -