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

📄 cd_util.c

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

            case CD_XPORT_TYPE_PROVIDE_BUFFER:
            case CD_XPORT_TYPE_ACCESS_BUFFER:

               /*
               ** These cases are not currently implemented for a consumer
               ** transport.  So fall through and report error.
               */

            default:
               eStatus = CD_UNSUPPORTED_TRANSPORT;
               psConnRecord->iERC = CM_ERC_BAD_TRANSPORT;
               goto Bailout;

            } /* end switch */
         } /* end if Reserve */
      }  /* end if Class 1  */
   } /* end if( ( pTr->iState & CD_TS_RESERVED ) == 0 ) */


   /*
   **********************************************************
   ** Start of START_TRANSPORTS Section for the Consumer
   *********************************************************
   */

   if( ( psTrrbl->eRequest == TREQ_START_TRANSPORTS )
      && ( ( pTr->iState & CD_TS_STARTED ) == 0 ) )
   {
      pTr->iState |= CD_TS_STARTED;

      if( iClass == CM_TCT_CLASS_1 )
      {
         /*
         ** Always pick up the size.
         */

         pTr->iDataSize       = psConnRecord->iConAppSize;


         /* For Consumer Transport */
         switch( psConnRecord->bConTransportType & CD_XPORT_TYPE_MASK )
         {
         case CD_XPORT_TYPE_PROVIDE_FUNCTION:

            /*
            ** Provide a copy function that will be called whenever new
            ** data is ready to be Consumed.  That is, the transport
            ** stores the data until the application needs to consume it.
            **
            ** This case is valid for the NetLinx Dualport, which should
            ** have it's own transport commission function.
            ** It is not valid for either ControlNet ASIC, so flag an error.
            */

            eStatus = CD_UNSUPPORTED_TRANSPORT;
            psConnRecord->iERC = CM_ERC_BAD_TRANSPORT;
            goto Bailout;

         case CD_XPORT_TYPE_DEFAULT:
         case CD_XPORT_TYPE_CALL_FUNCTION:

            /*
            ** This case is how the Consumer Xports have worked in the past.
            **
            ** Store pointer to function to call and handle to pass back.
            */

            if( pTr->fBridged )
            {
                pTr->pRxCopyFunction = psConnRecord->psOtherConnRecord->pProCopyFunction;
                pTr->xRxAppHandle    = psConnRecord->psOtherConnRecord->xProAppHandle;
            }
            else
            {
                pTr->pRxCopyFunction = psConnRecord->pConCopyFunction;
                pTr->xRxAppHandle    = psConnRecord->xConAppHandle;
            }
            break;


         case CD_XPORT_TYPE_PROVIDE_BUFFER:
         case CD_XPORT_TYPE_ACCESS_BUFFER:

            /*
            ** These cases are not currently implemented for a consumer
            ** transport.  So fall through and report error.
            */

         default:
            eStatus = CD_UNSUPPORTED_TRANSPORT;
            psConnRecord->iERC = CM_ERC_BAD_TRANSPORT;
            goto Bailout;

         } /* end switch */
#ifdef CD_EN_OBJECTS
         /*
         ** We need to setup the multicast group that we will be listening on
         */

         if ( psConnRecord->iPort == CD_ETHERNET_PORT )
         {
            if( ( psConnRecord->iConConnParams & CM_CP_TYPE_MASK ) == CM_CP_TYPE_MULTICAST )
            {
               /*
               ** Join the multicast listening group for this multicast address
               */

               *( UINT32 * ) &pTr->abRxTag[0] = UC_lLeTOl( psConnRecord->lLeConConnId );
               iError = en_cd_JoinMulticast(&psConnRecord->sEce.psMcast->sMc_addr);
               if ( iError != OK)
               {
                  eStatus = EN_NO_MULTICAST;
                  goto Bailout;
               }
            }
            pTr->sEce = psTrrbl->psConnRecord->sEce;

         } /* End if an ethernet port */
#endif
      }  /* end if Class 1 */



      /*
      ** Since we're a class 1 consumer or a class 3, create the Rx watchdog timer.
      **
      ** But first, check to see if it is already done.
      */

      if( pTr->pRxTot == NULL )
      {
         /*
         ** Build the timeout tribble.
         */
         pTr->pRxTot = GS_NewTrrbl( CD_TimeoutTrrblType );
         pTr->pRxTot->eRequest = TREQ_TIMER_EXPIRED;
         pTr->pRxTot->iId      = psConnRecord->iConTransportId;
         pTr->pRxTot->iPort    = psConnRecord->iPort;

         /*
         ** Now build the timer itself.
         */

         pTr->xRxTimer = GS_NewLinkedMsgTimer( TIMER_ONE_SHOT,
            ( psConnRecord->lTimeout < 10000L ) ? 10000L : psConnRecord->lTimeout,
            psConnRecord->lTimeout,
            CD_s[ psConnRecord->iPort ].xConfigQid,
            pTr->pRxTot );
         if( pTr->xRxTimer == NULL )
         {
            GS_DeleteTrrbl( pTr->pRxTot );
            eStatus = CD_RESOURCE_UNAVAILABLE;
            psConnRecord->iERC = CM_ERC_NO_BUFFER;
            goto Bailout;
         }
      }

      if( pTr->fBridged )
      {
         if( iClass == CM_TCT_CLASS_3 )
         {
            /*
            ** If bridged class 3, the connection records should be cross-linked
            ** so cross-link the transports.
            */

            if( ( psConnRecord->psOtherConnRecord )
               && ( psConnRecord->psOtherConnRecord->iConTransportId ) )
            {
               pTr->iOtherTransportId = psConnRecord->psOtherConnRecord->iConTransportId;
            }
            else
            {
               /*
               ** This should never happen.  The system could be unstable,
               ** so log a fatal fault.
               */

               GS_LogEvent( CM_INCONSISTENT_STATE, 0, psTrrbl, FATAL );
            }
         }
		 else
		 {
            /*
            ** If bridged class 1, the connection records should be cross-linked
            ** so cross-link the transports.
            */

            if( ( psConnRecord->psOtherConnRecord )
               && ( psConnRecord->psOtherConnRecord->iProTransportId ) )
            {
               pTr->iOtherTransportId = psConnRecord->psOtherConnRecord->iProTransportId;
            }
            else
            {
               /*
               ** This should never happen.  The system could be unstable,
               ** so log a fatal fault.
               */

               GS_LogEvent( CM_INCONSISTENT_STATE, 0, psTrrbl, FATAL );
            }
         }
      }

      /*
      ** Now do the ASIC specific initialization and start up the transport.
      */
#ifdef CD_EN_OBJECTS
      /* For tcpip we have to verify that messages for a given cip connection match the
      ** encap session that it was created on.  We do that by copying the encap session
      ** information into the cip record.
      */
      if ( psConnRecord->iPort == CD_ETHERNET_PORT )
      {
         pTr->sEce = psTrrbl->psConnRecord->sEce;
      }
#endif
      eStatus = (CD_s[ psConnRecord->iPort ].StartTransport)( pTr );

      if( eStatus != SUCCESS )
      {
         eStatus = CD_TRANSPORT_ALLOC_FAIL;
         psConnRecord->iERC = CM_ERC_BAD_TRANSPORT;
         goto Bailout;
      }

      /*
      ** Now start any allocated timers
      */

      if( pTr->xRetryTimer != NULL )
      {
         GS_StartTimer( pTr->xRetryTimer );
      }

      if( pTr->xRxTimer != NULL )
      {
         GS_StartTimer( pTr->xRxTimer );
      }
   }

   return( SUCCESS );


Bailout:

   /*
   ** Some sort of problem detected during setup.
   ** Clean things up and log a fault.
   ** If the failure was in the ASIC specific portion, that cleanup
   ** is already done. If the failure was anywhere in the general portion,
   ** the ASIC specific startup was not called.
   */

   if( psTrrbl->psConnRecord != NULL )
   {
      psConnRecord->bGRC = CI_GRC_FAILURE;

      if( psConnRecord->iProTransportId != 0 )
      {
         iTransport = psConnRecord->iProTransportId & sRadioActiveMasks.nTransportMask;

         pTr = cd_LookupTransportRecord(  psConnRecord->iPort,  psConnRecord->iProTransportId );

         if( pTr != NULL )
         {
            /*
            ** Unlink and make sure no other connections are linked to this
            ** transport before disposing of it.
            */

            if( cd_UnlinkConnSnFromTransport( psConnRecord->iConnectionSn, pTr ) == 0 )
            {
               if( pTr->pRetryTot != NULL )
               {
                  GS_DeleteTrrbl( pTr->pRetryTot );
               }

               if( pTr->xRetryTimer != NULL )
               {
                  GS_DeleteTimer( pTr->xRetryTimer );
               }

               if( pTr->pRxTot != NULL )
               {
                  GS_DeleteTrrbl( pTr->pRxTot );
               }

               if( pTr->xRxTimer != NULL )
               {
                  GS_DeleteTimer( pTr->xRxTimer );
               }

               GS_Free( pTr );

              ( CD_s[ psConnRecord->iPort ].papTransportRecords )[ iTransport - 1 ] = NULL;
            }
         }

         GS_LogEvent( eStatus, iTransport, 0, WARNING );
         psConnRecord->iProTransportId = 0;
      }

      if( psConnRecord->iConTransportId != 0 )
      {
         iTransport = psConnRecord->iConTransportId & sRadioActiveMasks.nTransportMask;

         pTr = cd_LookupTransportRecord( psConnRecord->iPort,  iTransport  );

         if( pTr != NULL )
         {
            /*
            ** Unlink and make sure no other connections are linked to this
            ** transport before disposing of it.
            */

            if( cd_UnlinkConnSnFromTransport( psConnRecord->iConnectionSn, pTr ) == 0 )
            {
               if( pTr->pRetryTot != NULL )
               {
                  GS_DeleteTrrbl( pTr->pRetryTot );
               }

               if( pTr->xRetryTimer != NULL )
               {
                  GS_DeleteTimer( pTr->xRetryTimer );
               }

               if( pTr->pRxTot != NULL )
               {
                  GS_DeleteTrrbl( pTr->pRxTot );
               }

               if( pTr->xRxTimer != NULL )
               {
                  GS_DeleteTimer( pTr->xRxTimer );
               }

               GS_Free( pTr );

               ( CD_s[ psConnRecord->iPort ].papTransportRecords )[  iTransport - 1  ] = NULL;
            }
         }

         GS_LogEvent( eStatus, iTransport, 0, WARNING );
         psConnRecord->iConTransportId = 0;
      }
#ifdef CD_EN_OBJECTS
      /*
      ** Free the mcast IP address if allocated
      */

      if( psConnRecord->iPort == CD_ETHERNET_PORT )
      {
         en_cd_FreeIpMcastAddress( psConnRecord );
      }
#endif
   }

   return( eStatus );

} /* End of cd_CommissionTransports() */



/*---------------------------------------------------------------------------
** cd_DecommissionTransports()
**---------------------------------------------------------------------------
*/

StatusType cd_DecommissionTransports( CD_TransportTrrblType *psTrrbl )
{
   StatusType  eStatusPro;
   StatusType  eStatusCon;
   CM_ConnectionRecordType *psConnRecord;

   psConnRecord = psTrrbl->psConnRecord;

   /*
   ** Delete transports if this is the last connection linked to them.
   */


   /*
   ** start edits: October,11th 2005, H.F.
   **
   ** additional input variable in cd_DeleteTransport
   **

   eStatusPro = cd_DeleteTransport( psConnRecord->iPort, psConnRecord->iProTransportId, psConnRecord->iConnectionSn );
   eStatusCon = cd_DeleteTransport( psConnRecord->iPort, psConnRecord->iConTransportId, psConnRecord->iConnectionSn );

   **
   */

   eStatusPro = cd_DeleteTransport( psConnRecord->iPort, psConnRecord->iProTransportId, psConnRecord->iConnectionSn, psConnRecord );
   eStatusCon = cd_DeleteTransport( psConnRecord->iPort, psConnRecord->iConTransportId, psConnRecord->iConnectionSn, psConnRecord );

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


   if( eStatusPro != SUCCESS )
   {
      return( eStatusPro );
   }

   return( eStatusCon );

} /* end of cd_DecommissionTransports() */



/*---------------------------------------------------------------------------
** cd_DeleteTransport()
**---------------------------------------------------------------------------
*/

StatusType cd_DeleteTransport( UINT16 iPort, UINT16 iTransport, UINT16 iConnectionSn, CM_ConnectionRecordType * psConnRecord )
{
   cd_TransportRecordType *pTr;

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

   cm_ConnectionRecordType *psParallelConnRecord;
   INT8 iNumConnectionsLeft;
   UINT32  lNewProApi = 0xFFFFFFFF;		/* initialization */
   UINT32  lNewProInhib;

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

   
   iTransport &= sRadioActiveMasks.nTransportMask;

⌨️ 快捷键说明

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