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

📄 cm_targt.c

📁 基于EthernetIP协议的应用程序,可以读取AB公司Controllogix系列Ethernetip协议PLC数据. 此软件代码可用于工业控制.
💻 C
📖 第 1 页 / 共 5 页
字号:
	  if( aConsumerAssemblyInstance=EC_FindUserDefinedAssemblyInstance( psConnRecord->sPublic.iConConnPoint ) )
	  {
		  aConsumerAssemblyInstance->itsState &= 0xFFF9;
		  aConsumerAssemblyInstance->itsState |= 0x0004;
		  aConsumerAssemblyInstance->itsIOConnectionCount++;

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

		  EC_AssemblyStateCB( 2 /* active */, aConsumerAssemblyInstance->itsInstanceNo );

		  /*
		  ** end edits: September,23rd 2005, H.F.
		  */
	  }
	  if( aProducerAssemblyInstance=EC_FindUserDefinedAssemblyInstance( psConnRecord->sPublic.iProConnPoint ) )
	  {
		  aProducerAssemblyInstance->itsState &= 0xFFF9;
		  aProducerAssemblyInstance->itsState |= 0x0004;
		  aProducerAssemblyInstance->itsIOConnectionCount++;

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

		  EC_AssemblyStateCB( 2 /* active */, aProducerAssemblyInstance->itsInstanceNo );

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


		  /*
		  ** start edits: October,14th 2005, H.F.
		  **
		  ** set run in SY_RunIdleArea, if the producer's run bit is set;
		  */

		  if( aProducerAssemblyInstance->itsState & 0x0001 /* run */ )
			  SY_RunIdleArea[aProducerAssemblyInstance->itsAppDataAreaId-AD_APP_DATA_AREA_EC_BASE] = 1 /* run */;

		  /*
		  ** end edits: October,14th 2005, H.F.
		  */
	  }
	  if( aConfigAssemblyInstance=EC_FindUserDefinedAssemblyInstance( psConnRecord->sPublic.iInstance ) )
	  {
		  aConfigAssemblyInstance->itsState &= 0xFFF9;
		  aConfigAssemblyInstance->itsState |= 0x0004;
		  aConfigAssemblyInstance->itsIOConnectionCount++;

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

		  EC_AssemblyStateCB( 2 /* active */, aConfigAssemblyInstance->itsInstanceNo );

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

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

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

} /* end of cm_ContinueOpening() */



/*---------------------------------------------------------------------------
** cm_ContinueProcessing()
**---------------------------------------------------------------------------
*/

void cm_ContinueProcessing( cm_ConnectionRecordType *psConnRecord )
{
   /*
   ** If there was an error, close down the connection.
   */

   if( psConnRecord->sPublic.bGRC != SUCCESS )
   {
      psConnRecord->iState |= CM_PS_FAULTED;
   }

   /*
   ** Continue opening or closing as appropriate.
   */

   if( psConnRecord->iState & ( CM_PS_CLOSING | CM_PS_FAULTED ) )
   {
      cm_ContinueClosing( psConnRecord );
   }
   else
   {
      cm_ContinueOpening( psConnRecord );
   }

} /* end of cm_ContinueProcessing() */



/*---------------------------------------------------------------------------
** cm_DeleteCR()
**---------------------------------------------------------------------------
*/

void cm_DeleteCR( cm_ConnectionRecordType *psConnRecord )
{
   CM_ConnectionRecordType *psPublicCR;


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

   sy_RxBufferType          *psRxBuffers;


   /*
   ** Free receive buffers, if necessary (e.g. if connection
   ** has not been established because of too many configuration
   ** data)
   */

   psRxBuffers = psConnRecord->sPublic.xConAppHandle;

   if( psRxBuffers )
   {
	   if( psRxBuffers->apBuffers[0] )
		   GS_Free( psRxBuffers->apBuffers[0] );

	   if( psRxBuffers->apBuffers[1] )
		   GS_Free( psRxBuffers->apBuffers[1] );
   }

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


   /*
   ** Free any memory allocated to hold the connection path.
   ** Remove the connection from the connection list
   ** then toss the connection record itself.
   */

   if( psConnRecord->paiLePath )
   {
      GS_Free( psConnRecord->paiLePath );
   }

   if( psConnRecord->sPublic.pCbDestHost != NULL )
   {
      CB_DeleteComBuf(psConnRecord->sPublic.pCbDestHost);
   }


   /*
   ** Make sure any links to another conn record are broken.
   */

   if( psConnRecord->sPublic.psOtherConnRecord )
   {
      psPublicCR = cm_GetPublicRecord( psConnRecord );

      if( psPublicCR->psOtherConnRecord->psOtherConnRecord == psPublicCR )
      {
         /*
         ** If the other CR is linked back to our CR,
         ** then break the link.
         */

         psPublicCR->psOtherConnRecord->psOtherConnRecord  = 0;
         psPublicCR->psOtherConnRecord->iOtherConnectionSn = 0;
      }
   }

   LL_RemoveDoubleLinkList( psConnRecord );
   GS_Free( psConnRecord );

} /* end of cm_DeleteCR() */



/*---------------------------------------------------------------------------
** cm_FindConnection()
**---------------------------------------------------------------------------
*/

cm_ConnectionRecordType* cm_FindConnection( UINT16  iConnectionSn,
                                            UINT16  iOrigVendorId,
                                            UINT32  lOrigDeviceSn,
                                            UINT16  iOrigConnectionSn,
                                            UINT16  iPort,
                                            UINT16  iClass,
                                            UINT16  iInstance,
                                            UINT16  iProConnPoint,
                                            UINT16  iConConnPoint
                                          )
{
   cm_ConnectionRecordType  *psConnRecord;


   /*
   ** Scan the connection record list looking for a match.
   ** Return NULL if we fall off the end of the list without finding one.
   */

   psConnRecord = LL_FirstEntry( &cm_s.sRecordList );

   while( !LL_EndOfList( &cm_s.sRecordList, psConnRecord ) )
   {
      if( iConnectionSn != 0 )
      {
         /*
         ** Check for match by local connection serial number.
         */

         if( psConnRecord->sPublic.iConnectionSn == iConnectionSn )
         {
            return( psConnRecord );
         }
      }
      else if( iOrigVendorId != 0 )
      {
         /*
         ** Check for match by originator connection serial number.
         */

         if( ( psConnRecord->sPublic.iOrigVendorId     == iOrigVendorId ) &&
             ( psConnRecord->sPublic.lOrigDeviceSn     == lOrigDeviceSn ) &&
             ( psConnRecord->sPublic.iOrigConnectionSn == iOrigConnectionSn ) )
         {
            if( ( iPort == 0 ) || ( psConnRecord->sPublic.iPort == iPort ) )
            {
               return( psConnRecord );
            }
         }
      }
      else
      {
         /*
         ** Check for match by class, instance and connection points.
         */

         if( ( psConnRecord->sPublic.iClass        == iClass        ) &&
             ( psConnRecord->sPublic.iInstance     == iInstance     ) &&
             ( psConnRecord->sPublic.iProConnPoint == iProConnPoint ) &&
             ( psConnRecord->sPublic.iConConnPoint == iConConnPoint ) )
         {
            if( ( iPort == 0 ) || ( psConnRecord->sPublic.iPort == iPort ) )
            {
               return( psConnRecord );
            }
         }
      }

      psConnRecord = LL_NextEntry( psConnRecord );
   }

   psConnRecord = NULL;
   return( psConnRecord );

} /* end of cm_FindConnection() */



/*---------------------------------------------------------------------------
** cm_InquireConnection()
**---------------------------------------------------------------------------
*/

void cm_InquireConnection( CM_InquireTrrblType *pTrrbl )
{
   /*
   ** Look for the connection in the active connection list.
   */

   if( cm_FindConnection( 0, 0, 0, 0, 0,
                          pTrrbl->iClass,
                          pTrrbl->iInstance,
                          pTrrbl->iProConnPoint,
                          pTrrbl->iConConnPoint ) == NULL )
   {
      pTrrbl->eStatus = CM_CONNECTION_NOT_FOUND;
   }

   GS_ReturnTrrbl( pTrrbl );

} /* end of cm_InquireConnection() */



/*---------------------------------------------------------------------------
** cm_IssueAppOpenClose()
**---------------------------------------------------------------------------
*/

void cm_IssueAppOpenClose( cm_ConnectionRecordType *psConnRecord )
{
   CM_AppOpenCloseTrrblType  *pTrrbl;

   /*
   ** Allocate a tribble and fill in the common stuff.
   ** Switch to fill in the specific details.
   */

   pTrrbl = GS_NewTrrbl( CM_AppOpenCloseTrrblType );
   pTrrbl->xReturnQueue = CM_xQid;
   pTrrbl->psConnRecord = cm_GetPublicRecord( psConnRecord );

   if( psConnRecord->iState & ( CM_PS_CLOSING | CM_PS_FAULTED ) )
   {
      /*
      ** Build an app close tribble when we're shutting down
      ** (cleanly or otherwise...)
      */

      pTrrbl->eRequest = TREQ_APP_CLOSE;
      pTrrbl->pComBuf  = psConnRecord->pTrrblFC ? psConnRecord->pTrrblFC->pComBuf : NULL;
      psConnRecord->iSteps |= CM_PS_AC_ISSUED;
   }
   else if( psConnRecord->iState & CM_PS_OPENING )
   {
      /*
      ** Build an app open complete tribble for final notification to the object
      ** that the connection is up and running.
      */
      pTrrbl->eRequest = TREQ_APP_OPEN_COMPLETE;
      pTrrbl->pComBuf  = psConnRecord->pTrrblFO ? psConnRecord->pTrrblFO->pComBuf : NULL;
      psConnRecord->iSteps |= CM_PS_AOC_ISSUED;
   }
   else
   {
      /*
      ** Build an app open tribble to get initial approval of the connection
      ** from the object we're trying to connect to.
      */

      pTrrbl->eRequest = TREQ_APP_OPEN;
      pTrrbl->pComBuf  = psConnRecord->pTrrblFO ? psConnRecord->pTrrblFO->pComBuf : NULL;
      psConnRecord->iSteps |= CM_PS_AO_ISSUED;
      psConnRecord->iState |= CM_PS_OPENING;
   }

   psConnRecord->sPublic.pTrrblAppOpenClose = pTrrbl;

   /*
   ** Route the request to the object we're connecting to.
   ** NOTE: iClass and iInstance must be compatible with CD_PacketTrrblType
   */
   pTrrbl->iClass    = psConnRecord->sPublic.iClass;
   pTrrbl->iInstance = psConnRecord->sPublic.iInstance;
   pTrrbl->iPort     = psConnRecord->sPublic.iPort;
   GS_PutTrrbl( MR_xRoutingQid, pTrrbl );

} /* end of cm_IssueAppOpenClose() */



/*---------------------------------------------------------------------------
** cm_IssueFwdReply()
**---------------------------------------------------------------------------
*/

void cm_IssueFwdReply( cm_ConnectionRecordType *psConnRecord )
{
   CB_ComBufType           *pComBuf;
   CD_PacketTrrblType      *pTrrbl;
   CD_PacketTrrblType     **ppTrrbl;
   BOOL                    fOpen;


   /*
   ** We're a target.
   ** Issue either a forward open reply or a forward close reply.
   */

   if( psConnRecord->pTrrblFO != NULL )
   {
      ppTrrbl = &(psConnRecord->pTrrblFO);
      pTrrbl  =   psConnRecord->pTrrblFO;
      pComBuf = pTrrbl->pComBuf;
      fOpen   = TRUE;
   }
   else
   if( psConnRecord->pTrrblFC != NULL )
   {
      ppTrrbl = &(psConnRecord->pTrrblFC);
      pTrrbl  =   psConnRecord->pTrrblFC;
      pComBuf = pTrrbl->pComBuf;
      fOpen   = FALSE;
   }
   else
   {
      return;
   }

   /*
   ** Choose a response packet to build.
   */

   if( fOpen && ( psConnRecord->sPublic.bGRC == SUCCESS ) )
   {
      /*
      ** Build good forward open response.
      ** Declare pointer to forward open reply structure for temp use.
      */

      CM_LeFwdOpenReplyType* pLeFwdReply;


      CB_ExpandComBuf( pComBuf, sizeof( CM_LeFwdOpenReplyType ) );
      pLeFwdReply = CB_GetDataPtrComBuf( pComBuf );

      pLeFwdReply->lLeOTConnId = psConnRecord->sPublic.lLeConConnId;
      pLeFwdReply->lLeTOConnId = psConnRecord->sPublic.lLeProConnId;

      pLeFwdReply->iLeOrigConnectionSn = UC_iTOiLe( psConnRecord->sPublic.iOrigConnectionSn );
      pLeFwdReply->iLeOrigVendorId     = UC_iTOiLe( psConnRecord->sPublic.iOrigVendorId );
      pLeFwdReply->lLeOrigDeviceSn     = UC_lTOlLe( psConnRecord->sPublic.lOrigDeviceSn );
      pLeFwdReply->lLeOTApi            = UC_lTOlLe( psConnRecord->sPublic.lConApi );
      pLeFwdReply->lLeTOApi            = UC_lTOlLe( psConnRecord->sPublic.lProApi );


      /*
      ** Retrieve the CD Handle from the connection record and store in trrbl
      */

      pTrrbl->xCdHandle = psConnRecord->sPublic.xCdHandle;
   }
   else
   {
      /*
      ** Build forward open error response or any forward close response.
      ** They are all the same format.
      ** Declare pointer to forward open error reply structure for temp use.
      */

      CM_LeFwdOpenErrorReplyType* pLeFwdReply;


      CB_ClearAndExpandComBuf( pComBuf, sizeof( CM_LeFwdOpenErrorReplyType ) );
      pLeFwdReply = CB_GetDataPtrComBuf( pComBuf );

      pLeFwdReply->lLeOrigDeviceSn     = UC_lTOlLe( psConnRecord->sPublic.lOrigDeviceSn );
      pLeFwdReply->iLeOrigVendorId     = UC_iTOiLe( psConnRecord->sPublic.iOrigVendorId );
      pLeFwdReply->iLeOrigConnectionSn = UC_iTOiLe( psConnRecord->sPublic.iOrigConnectionSn );


	  /*
	  ** start edits: November,15th 2005, H.F.
	  **
	  ** it must be distinguished between a forward open error response and

⌨️ 快捷键说明

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