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

📄 cm_targt.c

📁 基于EthernetIP协议的应用程序,可以读取AB公司Controllogix系列Ethernetip协议PLC数据. 此软件代码可用于工业控制.
💻 C
📖 第 1 页 / 共 5 页
字号:
	  ** a successful forward close response, as they differ in Application Reply
	  ** Size/Remaining Path Size
	  */

	  if( !fOpen && ( psConnRecord->sPublic.bGRC == SUCCESS ) )
		  pLeFwdReply->bPathSize       = 0;
	  else

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


      pLeFwdReply->bPathSize           = psConnRecord->bRemainingPathSize;
      pLeFwdReply->bReserved           = 0;
   }

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

   CI_PrependReplyHeader( pComBuf,
                          fOpen ? CM_SC_FWD_OPEN : CM_SC_FWD_CLOSE,
                          psConnRecord->sPublic.bGRC,
                          psConnRecord->sPublic.iERC );

   /*
   ** Return the packet tribble to the task that started this mess.
   ** Note that we've done so in the connection record.
   */

   GS_ReturnTrrbl( pTrrbl );
   *ppTrrbl = NULL;

} /* end of cm_IssueFwdReply() */



/*---------------------------------------------------------------------------
** cm_ObjectTask()
**---------------------------------------------------------------------------
*/

TASKRETURN cm_ObjectTask( TASKPARAM )
{
   cm_ConnectionRecordType  *psConnRecord;
   cm_upsTrrblType           upsTrrbl;


   /*
   ** Process requests forever.
   */

   while( 1 )
   {
      /*
      ** Grab a request from the queue & dispatch to the
      ** appropriate processing code.
      */

      upsTrrbl.Generic = GS_TakeTrrbl( CM_xQid );

      switch( upsTrrbl.Generic->eRequest )
      {

      case TREQ_TIMEOUT_CONNECTION:

         /*
         ** Request to close one connection because of a timeout.
         */
         cm_CloseConnection( upsTrrbl.Close, TRUE );
         break;


      case TREQ_CLOSE_CONNECTION:

         /*
         ** Request to close one connetion.
         */

         cm_CloseConnection( upsTrrbl.Close, FALSE );
         break;


      case TREQ_CLOSE_ALL_CONNECTIONS:

         /*
         ** Request to close all connections and disable the connection
         ** manager from starting new connections.
         ** Fall through to the I'm alive case to close
         ** all existing connections.
         */

         cm_s.fAllowConn = FALSE;


      case TREQ_RX_IM_ALIVE:

         /*
         ** I'm alive! packet received from another node.
         ** Scan the active connections list and shut down any existing
         ** connections with the other node (or all nodes).
         */

         cm_ProcessImAlive( upsTrrbl.Packet );
         break;


      case TREQ_ALLOW_CONNECTIONS:

         /*
         ** Allow connections to be accepted once again. This is the
         ** matching operation to TREQ_CLOSE_ALL_CONNECTIONS.
         */

         cm_s.fAllowConn = TRUE;
         GS_ReturnTrrbl( upsTrrbl.Generic );
         break;


      case TREQ_RX_UNSCHEDULED_PACKET:
         /*
         ** Process a new unscheduled Rx packet,
         ** most likely a forward open or forward close.
         */
         cm_ProcessNewRxPacket( upsTrrbl );
         break;


      case TREQ_INQUIRE_CONNECTION:

         /*
         ** Inquire if a connection is active.
         */

         cm_InquireConnection( upsTrrbl.Inquire );
         break;


      case TREQ_ENABLE_CONNECTION:

         break;


      case TREQ_DISABLE_CONNECTION:

         break;


      /*
      ** Internal reply from some portion of processing an open.
      **    - App open response.
      **    - Transport creation response.
      **    - App open complete response.
      */

      case TREQ_APP_OPEN:

         cm_ProcessAppOpen( upsTrrbl.AppOpenClose );
         break;


      case TREQ_APP_OPEN_COMPLETE:

         cm_ProcessAppOpenComplete( upsTrrbl.AppOpenClose );
         break;


      case TREQ_RESERVE_TRANSPORTS:

         psConnRecord = cm_GetPrivateRecord( upsTrrbl.Transport->psConnRecord );
         psConnRecord->iSteps |= CM_PS_R_TRAN_RETURNED;
         cm_ContinueProcessing( psConnRecord );
         GS_DeleteTrrbl( upsTrrbl.Transport );
         break;


      case TREQ_START_TRANSPORTS:

         psConnRecord = cm_GetPrivateRecord( upsTrrbl.Transport->psConnRecord );
         psConnRecord->iSteps |= CM_PS_S_TRAN_RETURNED;
         cm_ContinueProcessing( psConnRecord );
         GS_DeleteTrrbl( upsTrrbl.Transport );
         break;


      /*
      ** Internal reply from some portion of procesing a close or timeout.
      **    - App close response.
      **    - Transport deletion response.
      */

      case TREQ_APP_CLOSE:

         cm_ProcessAppClose( upsTrrbl.AppOpenClose );
         break;


      case TREQ_DELETE_TRANSPORTS:

         psConnRecord = cm_GetPrivateRecord( upsTrrbl.Transport->psConnRecord );
         psConnRecord->iSteps |= CM_PS_D_TRAN_RETURNED;
         cm_ContinueProcessing( psConnRecord );
         GS_DeleteTrrbl( upsTrrbl.Transport );
         break;


      case TREQ_TIMER_EXPIRED:
         cm_ProcessTimer( upsTrrbl.Timeout );
         break;


      /*
      ** Unsupported tribble.
      */

      default:

         GS_LogEvent( GS_UNSUPPORTED_TRIBBLE_REQUEST, upsTrrbl.Generic->eRequest, upsTrrbl.Generic, FATAL );
         break;


      } /* end of switch( pTrrbl->eRequest ) */

   } /* end of while( 1 ) */

} /* end of cm_ObjectTask() */



/*---------------------------------------------------------------------------
** cm_PackConnId()
**---------------------------------------------------------------------------
*/

void cm_PackConnId( CM_LeConnIdType *psLeConnId, UINT8 abConnId[] )
{
   UINT16  iConnNumber;


   /*
   ** Pack a connection ID from tag order into wire order.
   */

   iConnNumber = ( (UINT16)(abConnId[ 2 ]) << 8 ) + abConnId[ 1 ];

   psLeConnId->bMacId        = abConnId[ 0 ];
   psLeConnId->iLeConnNumber = UC_iTOiLe( iConnNumber );
   psLeConnId->bAbandoned    = 0;

} /* end of cm_PackConnId() */



/*---------------------------------------------------------------------------
** cm_ParseFwdOpen()
**---------------------------------------------------------------------------
*/

void cm_ParseFwdOpen( CB_ComBufType            *pComBuf,
                      cm_ConnectionRecordType  *psConnRecord
                    )
{
   INT16             iSegSize;
   INT16             iSize;
   INT16             iStartingSize;
   UINT8            *pbPath;
   UINT8            *pbNewPathSizeLocation;
   CM_LeFwdOpenType *pLeFwdOpen;
   CI_LeKeyType     *psLeKey;
   BOOL              fHaveNetSegment;
   BOOL              fDone;

   pbNewPathSizeLocation = NULL;

   /*
   ** Initialize to not having seen a schedule segment yet
   */

   fHaveNetSegment   = FALSE;


   /*
   ** Grab the stuff of interest from the forward open itself.
   */

   pLeFwdOpen = CB_GetDataPtrComBuf( pComBuf );

   psConnRecord->sPublic.bGRC            = CI_GRC_SUCCESS;
   psConnRecord->sPublic.iERC            = CI_GRC_SUCCESS;

   psConnRecord->sPublic.bOpenPriorityTickTime = pLeFwdOpen->bOpenPriorityTickTime;
   psConnRecord->sPublic.bOpenTimeoutTicks     = pLeFwdOpen->bOpenTimeoutTicks;

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

   psConnRecord->sPublic.iOrigConnectionSn     = UC_iLeTOi( pLeFwdOpen->iLeOrigConnectionSn );
   psConnRecord->sPublic.iOrigVendorId         = UC_iLeTOi( pLeFwdOpen->iLeOrigVendorId );
   psConnRecord->sPublic.lOrigDeviceSn         = UC_lLeTOl( pLeFwdOpen->lLeOrigDeviceSn );

   psConnRecord->sPublic.bTimeoutMult          = pLeFwdOpen->bTimeoutMult;
   psConnRecord->sPublic.lProApi               = UC_lLeTOl( pLeFwdOpen->lLeTORpi );
   psConnRecord->sPublic.lConApi               = UC_lLeTOl( pLeFwdOpen->lLeOTRpi );
#ifdef CD_EN_OBJECTS
   /* Default the production inhibit to 1/4 the API */
   psConnRecord->sPublic.lProInhib = psConnRecord->sPublic.lProApi >> 2;
#endif
   psConnRecord->sPublic.iProConnParams        = UC_iLeTOi( pLeFwdOpen->iLeTOConnParams );
   psConnRecord->sPublic.iConConnParams        = UC_iLeTOi( pLeFwdOpen->iLeOTConnParams );

   psConnRecord->sPublic.iConAppSize           = ( psConnRecord->sPublic.iConConnParams & CM_CP_SIZE_MASK ) - 2;
   psConnRecord->sPublic.iProAppSize           = ( psConnRecord->sPublic.iProConnParams & CM_CP_SIZE_MASK ) - 2;

   psConnRecord->sPublic.bClassTrigger         = pLeFwdOpen->bClassTrigger;

   /* ! ConformanceTestProblem: if reserved bits are set: error */
   if(
	   ((pLeFwdOpen->iLeTOConnParams & 0x6000)==0x6000)
	|| ((pLeFwdOpen->iLeOTConnParams & 0x6000)==0x6000)
	){
      iSize = iStartingSize = (UINT16)pLeFwdOpen->bConnPathSize;
      psConnRecord->sPublic.bGRC = CI_GRC_FAILURE;
      psConnRecord->sPublic.iERC = CM_ERC_BAD_CONN_TYPE;
      goto BailOut;
   }

   /*
   ** Strip off the forward open from the combuf.
   */
   CB_ShrinkComBuf( pComBuf, sizeof( CM_LeFwdOpenType ) );

   /*
   ** Load in a sensible default for the transmission rate.
   */

   psConnRecord->sPublic.bProRate = 1;


   /*
   ** start edits: September,9th 2005, H.F.
   **
   ** Assume, that it is not an Exclusive Owner Connection
   */

   psConnRecord->sPublic.bExclusiveOwnerConn = FALSE;

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


   /*
   ** Start parsing the connection path.
   ** Verify that the path fits in the remainder of the combuf without
   ** sloshing over the edges in either direction.
   */

   pbPath = CB_GetDataPtrComBuf( pComBuf );
   iSize = iStartingSize = (UINT16)pLeFwdOpen->bConnPathSize;

   if( ( iSize * 2 ) > CB_GetDataSizeComBuf( pComBuf ) )
   {
      psConnRecord->sPublic.bGRC = CI_GRC_CONFIG_TOO_SMALL;
      goto BailOut;
   }


   if( ( iSize * 2 ) < CB_GetDataSizeComBuf( pComBuf ) )
   {
      psConnRecord->sPublic.bGRC = CI_GRC_CONFIG_TOO_BIG;
      goto BailOut;
   }

   /*
   ** We appear to have a sensible amount of data in the connection path.
   ** Parse until we run out of stuff in the connection path.
   */


   /*
   ** start edits: October,6th 2005, H.F.
   **
   ** assume, that a data segment does not exist
   **
   */

   psConnRecord->sPublic.bDataSegSize = 0;

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


   fDone = FALSE;
   while( ( iSize > 0 ) && ( fDone == FALSE ) )
   {
      switch( *pbPath & CI_SEGMENT_TYPE_MASK)
      {
      case CI_LOGICAL_SEGMENT:

            switch( *pbPath )
            {
            case CI_LOGICAL_SEG_CLASS | CI_LOGICAL_SEG_8_BIT:

               /*
               ** 8 bit class segment.
               */

               psConnRecord->sPublic.iClass = *(pbPath + 1);
               iSegSize = 1;
               break;


            case CI_LOGICAL_SEG_CLASS | CI_LOGICAL_SEG_16_BIT:

               /*
               ** 16 bit class segment.
               */

               psConnRecord->sPublic.iClass = UC_iLeTOi( *( (UINT16*)(pbPath + 2) ) );
               iSegSize = 2;
               break;


            case CI_LOGICAL_SEG_CON_POINT | CI_LOGICAL_SEG_8_BIT:

               /*
               ** Connection point segment.
               ** First connection point is for O-T (consumer),
               ** second is for T-O (producer).
               */

               if( psConnRecord->sPublic.iConConnPoint == 0 )
               {
                  psConnRecord->sPublic.iConConnPoint = *(pbPath + 1);
               }
               else
               {
                  psConnRecord->sPublic.iProConnPoint = *(pbPath + 1);
               }

               iSegSize = 1;
               break;


            case CI_LOGICAL_SEG_KEY:

               /*
               ** Electronic key segment.
               ** Parse out and convert the details.
               */

               psLeKey = (void*)(pbPath + 2);
               iSegSize = *(pbPath + 1) + 1;

               psConnRecord->sPublic.sKey.iVendorId       = UC_iLeTOi( psLeKey->iLeVendorId );
               psConnRecord->sPublic.sKey.iProductType    = UC_iLeTOi( psLeKey->iLeProductType );
               psConnRecord->sPublic.sKey.iProductCode    = UC_iLeTOi( psLeKey->iLeProductCode );
               psConnRecord->sPublic.sKey.fUpdatesAllowed = psLeKey->bMajorRevision & CM_KEY_UPDATES_OK_MASK;
               psConnRecord->sPublic.sKey.bMajorRevision  = psLeKey->bMajorRevision & CM_KEY_MAJOR_REV_MASK;
               psConnRecord->sPublic.sKey.bMinorRevision  = psLeKey->bMinorRevision;
               break;

⌨️ 快捷键说明

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