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

📄 cd_util.c

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

   /*
   ** Lookup the transport record. Bail if it's invalid.
   */

   pTr = cd_LookupTransportRecord( iPort, iTransport );

   if ( pTr == NULL )
   {
      return( CD_INVALID_TRANSPORT );
   }

   /*
   ** Unlink and make sure no other connections are linked to this
   ** transport before disposing of it.
   */

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

   if( cd_UnlinkConnSnFromTransport( iConnectionSn, pTr ) == 0 )

   **
   */

   if( !( iNumConnectionsLeft = cd_UnlinkConnSnFromTransport( iConnectionSn, pTr ) ) )
   
   /*
   ** end edits: October,11th 2005, H.F.
   */
   {

      /*
      ** If we have a receive watchdog timer, shut it down.
      ** Nullify or delete the timeout tribble as appropriate.
      */

/*
** jjw check the timer in the critical region, possible
** it could expire between when it was checked and
** when it was actually deleted otherwise
*/

         GS_EnterCritical( );
         {
         if ( pTr->xRxTimer != NULL )
         {
            /*
            ** The timer is not null, so delete it.
            **
            ** If 0 is returned by GS_DeleteTimer(), it indicates
            ** that the timer has expired.  Thus a timeout TRRBL
            ** (pRxTot) has been tossed to CD.
            **
            ** ( GS_DeleteTimer( pTr->xRxTimer ) == 0 ) ==> Timer expired.
            */

            if ( GS_DeleteTimer( pTr->xRxTimer ) == 0 )
            {
               if ( pTr->pRxTot != NULL )
               {
                  pTr->pRxTot->iId = 0;
               }
            }
            else
            {
               GS_DeleteTrrbl( pTr->pRxTot );
            }
            pTr->xRxTimer  = NULL;
            pTr->pRxTot    = NULL;
         }
      }
      GS_ExitCritical( );

      /*
      ** If we have a class 3 client retry timer, shut it down.
      ** Nullify or delete the timeout tribble as appropriate.
      */

      if ( pTr->xRetryTimer != NULL )
      {
         GS_EnterCritical( );
         {
            if ( GS_DeleteTimer( pTr->xRetryTimer ) == 0 )
            {
               pTr->pRetryTot->iId = 0;
            }
            else
            {
               GS_DeleteTrrbl( pTr->pRetryTot );
            }
            pTr->xRetryTimer  = NULL;
            pTr->pRetryTot    = NULL;
         }
         GS_ExitCritical( );
      }

      /*
      ** Do any ASIC specific shutdown and buffer freeing.
      */

      (CD_s[ iPort ].StopTransport)( pTr );

      /*
      ** For class 3's, delete the combuf holding the freshest transmit data.
      */

      if( pTr->pCbFreshest != NULL )
      {
         CB_DeleteComBuf( pTr->pCbFreshest );
      }

      /*
      ** All cleaned up. Toss the transport record itself.
      */

       GS_EnterCritical( );
       {
          /*
          ** Do the NULL in a critical region in case it takes more than one
          ** asm language instruction.  We don't want access when only half
          ** the 32 bit field is NULL'd out.
          */
       ( CD_s[ iPort ].papTransportRecords )[ iTransport - 1 ]  = NULL;
       }
       GS_ExitCritical( );
      GS_Free( pTr );

   } /* end  if( cd_UnlinkConnSnFromTransport( iConnectionSn, pTr ) == 0 ) */


   /*
   ** start edits: October,11th 2005, H.F.
   **
   ** if there are other connections linked to this transport (i.e.
   ** Producer Connection Point) determine the now lowest RPI to apply
   ** to the API timer
   */

   else /* there are other connections linked to this transport */
   {
	   /* 
	   ** Scan the connection record list for connections with the 
	   ** same Producer Connection Point, but different Serial Numbers
	   */

	   psParallelConnRecord = LL_FirstEntry( &cm_s.sRecordList );

	   while( iNumConnectionsLeft &&
				!LL_EndOfList( &cm_s.sRecordList, psParallelConnRecord ) )
	   {
		   if( (psParallelConnRecord->sPublic.iProConnPoint == psConnRecord->iProConnPoint)
			   && (psParallelConnRecord->sPublic.iConnectionSn != iConnectionSn) )
		   {
			   /*
			   ** Found another connection with the same Producer
			   ** Connection Point, check its RPI
			   */
			   if( psParallelConnRecord->sPublic.lProApi < lNewProApi )
			   {
				   /* store relevant parameters for API Timer */
				   lNewProApi = psParallelConnRecord->sPublic.lProApi;
				   lNewProInhib = psParallelConnRecord->sPublic.lProInhib;
			   }

			   iNumConnectionsLeft--;
		   }

		   psParallelConnRecord = LL_NextEntry( psParallelConnRecord );
	   }

	   /*
	   ** check, if the determined API is greater than the current
	   ** API
	   */
	   if( lNewProApi > pTr->lProApi )
	   {
		   /* ...apply new (slower) APIs */
		   pTr->lProApi = pTr->lConApi = lNewProApi;
		   pTr->lProInhib = lNewProInhib;

		   /* adjust the API timer */
		   pTr->xAPITimer->nRetrigger = pTr->lProApi/1000;

		   /* retrigger API timer */
		   GS_RetriggerTimer(pTr->xAPITimer);
		   en_cd_Class1TxPacket( pTr->pBufA, pTr);

		   /*
		   ** start edits: October,13th 2005, H.F.:
		   **
		   ** update data after transmission
		   ** (NOTE: An ad_ResyncCommAndAppBufs() call before executing
		   ** en_cd_Class1TxPacket() does not work!)
		   */

		   GS_PutMsgQueueBits( AD_xQid, AD_BIT_MSG_SENT_PRO );

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

   }

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


   return( SUCCESS );

} /* End of cd_DeleteTransport() */



/*---------------------------------------------------------------------------
** cd_LinkConnSnToTransport()
**---------------------------------------------------------------------------
*/

INT8 cd_LinkConnSnToTransport( UINT16 iConnSn, cd_TransportRecordType  *pTr, UINT16 iPort )
{
   INT8 i;

   i = 0;
   while( i < (iPort == CD_CONTROLNET_PORT ? CN_CD_MAX_MULTICAST :EN_CD_MAX_MULTICAST) )
   {
      if( pTr->aiConnectionSn[ i ] == iConnSn )
      {
         /*
         ** Already linked, so just report number linked.
         */
         return( cd_NumConnSnLinkedToTransport( pTr ) );
      }
      else if( pTr->aiConnectionSn[ i ] == 0 )
      {
         /*
         ** Space is available, so link and report number linked.
         */
         pTr->aiConnectionSn[ i ] = iConnSn;
         return( cd_NumConnSnLinkedToTransport( pTr ) );
      }
      i++;
   }

   /*
   ** No space is available, so report error.
   */

   return( ( INT8 ) -1 );

} /* End of cd_LinkConnSnToTransport() */


/*---------------------------------------------------------------------------
** cd_LookupTransportRecord()
**---------------------------------------------------------------------------
*/


void cd_OpenTransportCount( int *theClass1Count, int *theClass3Count )
{
	CD_DataType aCD;
	int i;

	/* ! */
	*theClass1Count = *theClass3Count = 0;

	/* ! */
	aCD = CD_s[CD_ETHERNET_PORT];
	for( i=0; i<aCD.iNumTransports; i++ ){

		/* ! */
		struct cd_TransportRecordType *aTR = aCD.papTransportRecords[i];
		if( aTR!=NULL )
			if( (aTR->iState & CD_TS_STARTED) && !(aTR->iState & CD_TS_CLOSING)){

				/* !  */
				if( (aTR->iClass & CM_TCT_CLASS_MASK)==CM_TCT_CLASS_1 ) (*theClass1Count)++;
				if( (aTR->iClass & CM_TCT_CLASS_MASK)==CM_TCT_CLASS_3 ) (*theClass3Count)++;
			}

	}

}

cd_TransportRecordType *cd_LookupTransportRecord( UINT16 iPort, UINT16 iTransport )
{
   if( !CD_ValidPortNum( iPort ) )
   {
      GS_LogEvent( CD_FAULT_TYPE, iPort, NULL, FATAL );
   }

   iTransport &= sRadioActiveMasks.nTransportMask;

   if( iTransport == 0 )
   {
      return( NULL );
   }

   if( iTransport > CD_s[ iPort ].iNumTransports )
   {
      return( NULL );
   }

   return( ( CD_s[ iPort ].papTransportRecords )[ iTransport - 1 ] );
}

/*---------------------------------------------------------------------------
** cd_NumConnSnLinkedToTransport()
**---------------------------------------------------------------------------
*/

INT8 cd_NumConnSnLinkedToTransport( cd_TransportRecordType  *pTr  )
{
   INT8 i;
   INT8 iNumConnectionsLeft;

   iNumConnectionsLeft = 0;
   i = 0;
   while( i < (CN_CD_MAX_MULTICAST > EN_CD_MAX_MULTICAST ? CN_CD_MAX_MULTICAST : EN_CD_MAX_MULTICAST) )
   {
      if( pTr->aiConnectionSn[ i ] != 0 )
      {
         /*
         ** Link found.
         */
         iNumConnectionsLeft++;
      }
      i++;
   }

   /*
   **  Report number left.
   */

   return( iNumConnectionsLeft );

} /* End of cd_NumConnSnLinkedToTransport() */



/*---------------------------------------------------------------------------
** cd_ProcessTimer()
**---------------------------------------------------------------------------
*/

void cd_ProcessTimer( CD_TimeoutTrrblType *pTrrbl )
{
   cd_TransportRecordType *pTr;
   CM_CloseTrrblType      *pTrrblClose;
   INT8 i;


   i = 0;

   /*
   ** If the TOT has been nullified, just toss it.
   */

   if( pTrrbl->iId == 0 )
   {
      GS_DeleteTrrbl( pTrrbl );
      return;
   }

   /*
   ** Lookup the transport record. Bail if it's invalid.
   */

   pTr = cd_LookupTransportRecord( pTrrbl->iPort, pTrrbl->iId );

   if ( pTr == NULL )
   {
      GS_DeleteTrrbl( pTrrbl );
      return;
   }

   /*
   ** Valid timeout tribble (TOT).
   ** Issue close connection requests to the connection manager.
   */
   while( i < (CN_CD_MAX_MULTICAST > EN_CD_MAX_MULTICAST ? CN_CD_MAX_MULTICAST :EN_CD_MAX_MULTICAST) )
   {
      if( pTr->aiConnectionSn[ i ] != 0 )
      {
         /*
         ** Found a linked connection, tell CM to close it.
         */
         pTrrblClose = GS_NewTrrbl( CM_CloseTrrblType );
         pTrrblClose->eRequest      = TREQ_TIMEOUT_CONNECTION;
         pTrrblClose->xUserHandle   = NULL;
         pTrrblClose->iConnectionSn = pTr->aiConnectionSn[ i ];
         pTrrblClose->fUnrequestedClose = FALSE;
         pTrrblClose->pCombuf = NULL;

         GS_PutTrrbl( CM_xQid, pTrrblClose );

      }

      i++;
   }

   /*
   ** Delete the TOT & erase all references to it.
   */

   GS_DeleteTrrbl( pTrrbl );
   pTr->pRxTot = NULL;

} /* end of cd_ProcessTimer() */



/*---------------------------------------------------------------------------
** cd_RouteClass3Packet()
**---------------------------------------------------------------------------
*/

void cd_RouteClass3Packet( CD_PacketTrrblType *pTrrbl )
{
   cd_TransportRecordType  *pTr;
   LeUINT16                 iLeSeqCount;

   /*
   ** Look up the transport record.
   */

   GS_UseCritical();
   pTr = cd_LookupTransportRecord( pTrrbl->iPort, pTrrbl->iTransport );

   if( pTr == NULL )
   {

⌨️ 快捷键说明

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