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

📄 cm_targt.c

📁 基于EthernetIP协议的应用程序,可以读取AB公司Controllogix系列Ethernetip协议PLC数据. 此软件代码可用于工业控制.
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************
*****************************************************************************
**
** File Name
** ---------
**
** CM_TARGT.C
**
*****************************************************************************
*****************************************************************************
**
** Description
** -----------
**
** Target portion of the Connection Manager object.
**
*****************************************************************************
*****************************************************************************
**
** Source Change Indices
** ---------------------
**
** Porting: <none>0----<major>         Customization: <none>0----<major>
**
*****************************************************************************
*****************************************************************************
**                                                                         **
** ETHERNET/IP EXAMPLE CODE                                                **
** COPYRIGHT (c) 2000-2005 ODVA (Open DeviceNet Vendor Association)		   **
**						   & ControlNet International Ltd.                 **
**                                                                         **
** All rights reserved, except as specifically licensed in writing.        **
** Use of the Ethernet/IP Example Protocol Software is subject to          **
** ODVA's and ControlNet International's Terms of Use Agreement.           **
** The following work constitutes example program code and is intended     **
** merely to illustrate useful programming techniques.  The user is        **
** responsible for applying the code correctly.  The code is provided      **
** AS IS without warranty and is in no way guaranteed to be error-free.    **
**                                                                         **
*****************************************************************************
*****************************************************************************
*/

/****************************************************************************
*****************************************************************************
**
** Change Log
** ----------
**
**
*****************************************************************************
*****************************************************************************
*/

/*
** Determine if this object is to be included.
*/

#include "ab_env.h"
#ifdef CORE_OBJECTS

#include "cd.h"       /* Communications Device public interfaces           */
#include "mr.h"       /* Message Router Public Interfaces                  */
#include "um.h"       /* UCMM Client request interfaces                    */
#include "cm.h"       /* Connection Manager public interfaces              */

#include "cm_targt.h" /* Connection Manager Target private interfaces      */

#include "id.h"
#include "ad.h"				/* September,15th 2005, H.F. */
#include "bf.h"		        /* September,15th 2005, H.F. */
#include "sy.h"				/* September,15th 2005, H.F. */
#include "sy_obj.h"			/* September,15th 2005, H.F. */
#include "ECUserDefined.h"	/* September,9th 2005, H.F.
#include "ECInterface.h"								*/

/****************************************************************************
**
** Public data
**
*****************************************************************************
*/

GS_MsgQueueType CM_xQid;



/****************************************************************************
**
** Private data
**
*****************************************************************************
*/

cm_DataType cm_s;



/****************************************************************************
**
** Public Services
**
*****************************************************************************
*/

/*---------------------------------------------------------------------------
** CM_DecodeTimePerTickAndTicks()
**---------------------------------------------------------------------------
*/

GS_MSecType CM_DecodeTimePerTickAndTicks( UINT8 bTimePerTick , UINT8 bNumTicks )
{
   return( ( ( GS_MSecType ) 1 << ( bTimePerTick & CM_PTT_TICKTIME_MASK ) ) * bNumTicks );

} /* end of CM_DecodeTimePerTickAndTicks() */



/*---------------------------------------------------------------------------
** CM_EncodeTimePerTickAndTicks()
**---------------------------------------------------------------------------
*/

BOOL  CM_EncodeTimePerTickAndTicks( GS_MSecType nTimeout, UINT8 *pbTimePerTick , UINT8 *pbNumTicks )
{
   UINT8 bTimePerTick;

   /*
   ** Given a time in milli-seconds, calulate the the number of ticks and time per tick.
   ** See Chapter 4, section 4.2.6 of the ControlNet spec.
   */

   bTimePerTick = 0;

   /*
   ** Note that the ( 8 + bTimePerTick ) is used because *pbNumTicks is an 8 bit value.
   */

   while( nTimeout >= ((GS_MSecType)( 1L << ( 8 + bTimePerTick ) ) ) )
   {
      bTimePerTick++;
      if( bTimePerTick > CM_PTT_TICKTIME_MASK )
      {
         break;
      }
   }

   if( bTimePerTick <= CM_PTT_TICKTIME_MASK )
   {
      /*
      ** OR in value so that priority does not get overwritten
      */

      *pbTimePerTick &= ~CM_PTT_TICKTIME_MASK;
      *pbTimePerTick |= bTimePerTick;

      *pbNumTicks = (unsigned char/* jjw 11/1/9*/ )( nTimeout / ( 1L << bTimePerTick ) );

      return( TRUE );
   }
   else
   {
      /*
      ** TimePerTick Error
      */

      return( FALSE );
   }
} /* end of CM_EncodeTimePerTickAndTicks() */



/*---------------------------------------------------------------------------
** CM_Init()
**---------------------------------------------------------------------------
*/

StatusType CM_Init( UINT16 iOptions )
{
   GS_TaskSeedType            sSeed;
   MR_RegistrationTrrblType  *pMrTrrbl;


   /*
   ** Allocate/Create all resources (except for tasks).
   */

   if( iOptions & AB_CREATE_RESOURCE )
   {
      /*
      ** Create the task's request queue.
      */

      CM_xQid = GS_NewMsgQueue();
   }

   /*
   ** Initialize all internal data structures.
   */

   if( iOptions & AB_INIT_RESOURCE )
   {
      /*
      ** Initialize (empty) the connection record list.
      ** Initialize the connection ID counter.
      */

      cm_s.fAllowConn     = TRUE;
      LL_Init( &cm_s.sRecordList );
      cm_s.iConnSn        = 1;
      cm_s.fConnSnWrapped = FALSE;
   }

   /*
   ** Create the task & associate it with the message queue created earlier.
   */

   if( iOptions & AB_CREATE_TASK )
   {
      sSeed.pRoutine   = cm_ObjectTask;
      sSeed.pParameter = NULL;
      sSeed.pStack     = NULL;
      sSeed.iStackSize = CM_STACK_SIZE;
      sSeed.nPrio      = CM_TASK_PRIO;
      sSeed.pTaskName  = "CM  ";

      GS_AssociateTaskAndQueues( GS_NewTask( &sSeed ), CM_xQid, GS_NO_QUEUE );
   }

   /*
   ** Final initialization after tasks are running.
   */

   if( iOptions & AB_INIT_TASK )
   {
      /*
      ** Register ourselves with the message router.
      */

      pMrTrrbl = GS_NewTrrbl( MR_RegistrationTrrblType );
      pMrTrrbl->eRequest  = TREQ_REGISTER_OBJECT;
      pMrTrrbl->iClass    = CM_CLASS_NUMBER;
      pMrTrrbl->iInstance = MR_CLASS_AND_INSTANCE_1;
      pMrTrrbl->iPort     = MR_ALL_PORTS;
      pMrTrrbl->xQ        = CM_xQid;
      GS_PutTrrbl( MR_xQid, pMrTrrbl );
   }

   return( SUCCESS );

} /* end of CM_Init() */



/****************************************************************************
**
** Private services
**
*****************************************************************************
*/

/*---------------------------------------------------------------------------
** cm_BuildFwdErrorReply()
**---------------------------------------------------------------------------
*/

void cm_BuildFwdErrorReply( CB_ComBufType *pComBuf,
                            LeUINT16       iLeOrigConnectionSn,
                            LeUINT16       iLeOrigVendorId,
                            LeUINT32       lLeOrigDeviceSn,
                            UINT8          bPathSize,
                            UINT8          bServiceCode,
                            UINT8          bGRC,
                            UINT16         iERC )
{
   CM_LeFwdOpenErrorReplyType* pLeFwdReply;


   /*
   ** Build general forward open/close error reply packet.
   ** Good forward close reply is the same format.
   */

   CB_ClearAndExpandComBuf( pComBuf, sizeof( CM_LeFwdOpenErrorReplyType ) );

   pLeFwdReply = CB_GetDataPtrComBuf( pComBuf );

   pLeFwdReply->lLeOrigDeviceSn     = lLeOrigDeviceSn;
   pLeFwdReply->iLeOrigVendorId     = iLeOrigVendorId;
   pLeFwdReply->iLeOrigConnectionSn = iLeOrigConnectionSn;
   pLeFwdReply->bPathSize           = bPathSize;
   pLeFwdReply->bReserved           = 0;

   /*
   ** Build a good or bad reply header based on the status codes.
   */

   CI_PrependReplyHeader( pComBuf, bServiceCode, bGRC, iERC );

} /* end of cm_BuildFwdErrorReply() */



/*---------------------------------------------------------------------------
** cm_CloseConnection()
**---------------------------------------------------------------------------
*/

void cm_CloseConnection( CM_CloseTrrblType *pTrrbl, BOOL fTimeout )
{
   StatusType                eStatus;
   cm_ConnectionRecordType  *psConnRecord;

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

   cm_ConnectionRecordType  *psParallelConnRecord;
   CM_CloseTrrblType      *pTrrblClose;

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


   /*
   ** Find the connection to close.
   */

   psConnRecord = cm_FindConnection( pTrrbl->iConnectionSn, 0, 0, 0, 0, 0, 0, 0, 0 );

   if( ( psConnRecord == NULL ) || ( psConnRecord->iState & CM_PS_CLOSING ) )
   {
      /*
      ** No such connection or connection already being closed.
      ** Just return the tribble.
      */

      pTrrbl->eStatus = CM_CONNECTION_NOT_FOUND;
      GS_ReturnTrrbl( pTrrbl );
   }
   else
   {
      /*
      ** Connection found. Mark it as being closed.
      ** Record an appropriate error for a timed out connection.
      ** Save the close request tribble for controlled closes (non-timeout).
      */

      psConnRecord->iState     |= CM_PS_CLOSING;

      if( fTimeout )
      {
         psConnRecord->sPublic.bGRC = CI_GRC_FAILURE;
         psConnRecord->sPublic.iERC = CM_ERC_CONN_TIMED_OUT;

         eStatus = ( ( psConnRecord->sPublic.bClassTrigger & CM_TCT_CLASS_MASK ) == CM_TCT_CLASS_1 )
            ? CM_CONNECTION_CLASS_1_TIMEOUT : CM_CONNECTION_CLASS_3_TIMEOUT;
         GS_LogEvent( eStatus, psConnRecord->sPublic.iConnectionSn, 0, SEVERE );
         GS_ReturnTrrbl( pTrrbl );


		 /*
		 ** start edits: September,29th 2005, H.F.
		 **
		 ** if the timed out connection is an exclusive owner connection,
		 ** any other connection with the same producer connection point
		 ** must be closed, too. Otherwise the Originator of the exclusive
		 ** owner connection would not be signalled that the O->T data is
		 ** no longer being received by the target device, as the target
		 ** device would further produce data on the same Multicast address
		 ** and Connection ID.
		 */

		 /* check, if an exclusive owner connection timed out */
		 if( psConnRecord->sPublic.bExclusiveOwnerConn )
		 {
			 /* 
			 ** Scan the connection record list for connections with the 
			 ** same Producer Connection Point
			 */

			 psParallelConnRecord = LL_FirstEntry( &cm_s.sRecordList );

			 while( !LL_EndOfList( &cm_s.sRecordList, psParallelConnRecord ) )
			 {
				 if( psParallelConnRecord->sPublic.iProConnPoint
					 == psConnRecord->sPublic.iProConnPoint )
				 {
					 /*
					 ** Found a connection with the same Producer
					 ** Connection Point, tell CM to close it.
					 */
					 pTrrblClose = GS_NewTrrbl( CM_CloseTrrblType );
					 pTrrblClose->eRequest      = TREQ_CLOSE_CONNECTION;
					 pTrrblClose->xUserHandle   = NULL;
					 pTrrblClose->iConnectionSn = psParallelConnRecord->sPublic.iConnectionSn;
					 pTrrblClose->fUnrequestedClose = FALSE;
					 pTrrblClose->pCombuf = NULL;

					 GS_PutTrrbl( CM_xQid, pTrrblClose );
				 }

				 psParallelConnRecord = LL_NextEntry( psParallelConnRecord );
			 }
		 }

		 /*
		 ** end edits: September,29th 2005, H.F.
		 */
      }
      else
      {
         psConnRecord->pTrrblClose = pTrrbl;
      }

      /*
      ** Continue the close process.
      */

      cm_ContinueProcessing( psConnRecord );
   }

} /* end of cm_CloseConnection() */


/*---------------------------------------------------------------------------
** cm_ContinueClosing()
**---------------------------------------------------------------------------
*/

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

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

	t_UserDefinedAssemblyInstance   *aConsumerAssemblyInstance;

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


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

	t_UserDefinedAssemblyInstance   *aProducerAssemblyInstance;
	t_UserDefinedAssemblyInstance   *aConfigAssemblyInstance;

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


   /*----------------------------------------------------------
   ** Before closeing this connection, make sure any opening
   ** requests that have been issued, have returned.
   **----------------------------------------------------------

⌨️ 快捷键说明

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