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

📄 en_util.c

📁 基于EthernetIP协议的应用程序,可以读取AB公司Controllogix系列Ethernetip协议PLC数据. 此软件代码可用于工业控制.
💻 C
📖 第 1 页 / 共 3 页
字号:
               pTagEntry->iLeSeqCount = iTPUSeqCount;
               pTagEntry->fFirstMessageRcvd = ~0;  /* No longer first message received */
            }
         } /* End if TP sequence count */

         /*
         ** Retrigger the connection heart beat timer
         */

         GS_EnterCritical( );
         if( pTagEntry->xRxTimer != NULL )
         {
            pTagEntry->iTimeLeft = GS_RetriggerTimer( pTagEntry->xRxTimer );
            if( pTagEntry->iTimeLeft > 0 )
            {
               pTagEntry->iMsecLastRecv = gs_sTimers.sSysTime.iMSecTime;
            }
         }

         pTagEntry->iSeqCount = iSeqCount;
         GS_ExitCritical( );
      } /* End if Common Packet Encapsulation sequence count */

   } /* End if sequenced packet */
   return OK;
}



/*---------------------------------------------------------------------------
** en_cd_ParseLpacket( )
**---------------------------------------------------------------------------
*/

UINT32 en_cd_ParseLpacket( PKTBUF_P msg, ECE * ece )


{

   /*
   ** At this point we have received a valid Encap message.  The message was received via the sockets,
   ** checked for the Encap Command type and found to be of type RRData.  The mesage was then passed to
   ** this task for further processing
   */

   UINT32          iCId;
   UINT16          iSizeInBytes;
   CB_ComBufType  *pCb;
   union
   {
      GS_TrrblType   *Generic;
      CD_PacketTrrblType *Packet;
   }  pT;

   UINT16          iTagIndex;
   cd_TransportRecordType *pTagEntry;

   iSizeInBytes = msg->lLength;
   if( msg->sEncap.sPkt_tag.sTag.iTag_type == CPF_TAG_PKT_UCMM )
   {

      /*
      ** Allocate a ComBuf from memory.  The addendum might include
      ** socket information so include that length in
      ** the allocation.
      */

      pCb = CB_NewComBuf( iSizeInBytes + msg->lAdd_len );

      /*
      ** Copy the Lpacket into the ComBuf, skip the fixed
      ** tag header.
      */

      CB_PrependComBuf( pCb, msg->pData, iSizeInBytes );

      /*
      ** Allocate a trrbl from memory
      */

      pT.Packet = GS_NewTrrbl( CD_PacketTrrblType );

      /*
      ** Associate the ComBuf to the trrbl
      */

      pT.Packet->pComBuf = pCb;
      pT.Packet->iPort = CD_ETHERNET_PORT;
      pT.Packet->iTransport = 0;


      pT.Packet->xReturnQueue = CD_s[CD_ETHERNET_PORT].xTxUnschedLoQid;
      if( ece->sEid.u.type == ECE_TYPE_INBOUND )
      {
         /*
         ** Inbound message
         **
         ** if there is socket information in the pktbuf addendum, save it in the ECE
         ** section for use by the CD layer.
         */

         en_cd_GetSocketAddresses( msg, &msg->sEce.sSa );

         /*
         ** Save the original message, which also has ece context which we will use for the reply
         */

         pT.Packet->bRequest = TRUE;
         pT.Packet->xCdHandle = msg;
      }
      else
      {
         /*
         ** Since this is an outbound connection, verify that all messages
         ** received have our IP address in the 0th context position.
         ** This indicates it is a reply to a message we originated
         */
         if ( msg->sEncap.sHdr.alEncaph_context[ 0 ] != list_target_data.sS.s_sock.lSin_addr )
         {
			DBLN("Request message received on reply only socket");
            return ENCAP_E_BAD_TARGET_ID;
         }


        /*
        ** Check to see if this reply message has a socket address in it.
        ** Socket addresses are attached to class 1 forward open replies.
        */

         if ( msg->sEncap.lValid & PKTBUF_ENCAPV_ADD )
         {
             en_cd_GetSocketAddresses( msg, &msg->sEce.sSa );
             /*
             ** Now that we have the socket addresses prepend the information
             ** to the combuf.  The first thing the forward open is
             ** going to need to do is dig this information
             ** out so we don't change the overall handling
             ** of a typical reply.
             */

             CB_PrependComBuf( pCb, &msg->sEce.sSa, sizeof msg->sEce.sSa );
         }

         /*
         ** Free the packetbuffer, we will not need it any longer
         ** set bRequest = 0 to indicate outbound, we originated this message
         ** that this is a reply to.  If this is the reply to a forward
         ** open we originated, we will need to store the SID with the other
         ** connection information. Unfortunately this is going to
         ** require more of the cd layer transports to know how to handle this.
         */

         pT.Packet->xUmHandle = ( void * ) msg->sEncap.sHdr.alEncaph_context[1];
         PktBufFree( msg );
         pT.Packet->bRequest = 0;
         pT.Packet->xCdHandle = ece;
      }

      /*
      ** UCMM packet. Tribble plus combuf.
      ** Send to the UCMM object.
      */

      pT.Packet->eRequest = TREQ_RX_FIXED_TAG_PACKET;
      GS_PutTrrbl( CD_s[ CD_ETHERNET_PORT ].xUMQid, pT.Packet );

   }
   else if( msg->sEncap.sAdr_tag.sTag.iTag_type == CPF_TAG_ADR_CONNECTED )
   {
      iCId = ENCAP_VALUE_LONG( msg->sEncap.sAdr_tag.data.sC.lCid );
      iTagIndex = ( iCId & sRadioActiveMasks.nTransportMask ) - 1;   /* connected address */

      /*
      ** Sanity check 1, make sure tagindex in range
      */


	  /*
	  ** start edits: October,27th 2005, H.F.
	  **
	  ** upper bound must exclude EN_CD_LAST_C3_TRANSPORT
	  **

      if( ( iTagIndex + 1 < EN_CD_FIRST_C3_TRANSPORT ) ||
          ( iTagIndex + 1 >= EN_CD_LAST_C3_TRANSPORT ) )
      {
         return ENCAP_E_BAD_TARGET_ID;
      }

	  **
	  */

      if( ( iTagIndex + 1 < EN_CD_FIRST_C3_TRANSPORT ) ||
          ( iTagIndex + 1 > EN_CD_LAST_C3_TRANSPORT ) )
      {
         return ENCAP_E_BAD_TARGET_ID;
      }

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


      pTagEntry = ( CD_s[ CD_ETHERNET_PORT ].papTransportRecords )[ iTagIndex ];

      /*
      ** Sanity check 2, Make sure we have a valid transport pointer.
      */

      if (pTagEntry == NULL)
      {
         return ENCAP_E_BAD_TARGET_ID;
      }

      /*
      ** Sanity check 3, Make sure transport ID's match
      */

      if (iCId != *(UINT32 *)pTagEntry->abRxTag)
      {
         return ENCAP_E_BAD_TARGET_ID;
      }


      /*
      ** Check the transport class and perform the appropriate processing
      */

      switch ( pTagEntry->iClass )
      {
      case CM_TCT_CLASS_3:

         /*
         ** Calculate the Lpacket size in bytes
         */

         iSizeInBytes = msg->lLength;

         /*
         ** Allocate a ComBuf from memory
         */

         pCb = CB_NewComBuf( iSizeInBytes );
         if( pCb == NULL )
            return ENCAP_E_OUTOFMEM;
         /*
         ** Copy the Lpacket into the ComBuf
         */

         CB_PrependComBuf( pCb, msg->pData, iSizeInBytes );

         /*
         ** Allocate a trrbl from memory
         */

         pT.Packet = GS_NewTrrbl( CD_PacketTrrblType );
         if( pT.Packet == NULL )
         {
            CB_DeleteComBuf( pCb );
            return ENCAP_E_OUTOFMEM;
         }

         /*
         ** Let other functions know where this came from
         */

         pT.Packet->iPort = CD_ETHERNET_PORT;

         /*
         ** Associate the ComBuf to the trrbl
         */

         pT.Packet->pComBuf = pCb;

         /*
         ** Corresponding transport instance
         */
        /*
        ** jjw. 8/7/00 Changed endian format to match format stored in
        ** the connection record
        */

         pT.Packet->iTransport = sRadioActiveMasks.nTransportMask & pTagEntry->iTransportId;

         /*
         ** Return the trrbl to the Unscheduled Transmit task
         */

         pT.Packet->xReturnQueue = CD_s[CD_ETHERNET_PORT].xTxUnschedHiQid;

         /*
         ** Send the trrbl to the transport's destination message queue
         */

         /*
         ** We need to verify that the received message is valid for the encap session it was received on.
         ** If not we'll have to ignore it.  Verify that The Encap session ID does match the id the session
         ** ID the CID connection was made under
         */

         if( pTagEntry->sEce.lSid != ece->lSid )
         {
            GS_DeleteTrrblAndComBuf( pT.Packet );
            return ENCAP_E_BAD_TARGET_ID;
         }

         /*
         ** Look up the transport record.
         **
         ** The for SendUnitData commands there is no presumed reply.  As a result there is no need to
         ** keep the received message because we will not have to restore the original context.
         ** Free the packetbuffer, we will not need it any longer
         */

         PktBufFree( msg );
         cd_RouteClass3Packet( pT.Packet );
         break;

      default:
         return ENCAP_E_UNHANDLED_CMD;

      }  /* End of transport class switch  statement */
   }  /* End of else clause - bTagIndex */

   return ENCAP_E_SUCCESS;

}  /* End of en_cd_ParseLpacket( ) */

/*---------------------------------------------------------------------------
** en_cd_ProducerCopyFunction()
**---------------------------------------------------------------------------
*/

UINT16  en_cd_ProducerCopyFunction( void     *pvAppHandle,
                                    LeUINT16 *pui16LeSeqCount,
                                    UINT8    *paui8DataIn,
                                    UINT16    ui16DataLen )
{
   /*
   ** This routine is called when an application has data that needs to be
   ** produced or when the other port's CD layer has received data that needs
   ** to be bridged/sent-out the Ethernet port.
   ** xAppHandle is a pointer to the CD Transport Record for this connection.
   */

   cd_TransportRecordType  *pTR = (cd_TransportRecordType *) pvAppHandle;
   UINT8                   *pBuf = pTR->pBufA;


   /* Make sure ComBuf pointer is not NULL if data is present. */
   if( pBuf == NULL  &&  ui16DataLen > 0)
   {
      /*
      ** No CommBuf -- Abort & return 0 if no ComBuf and data is present.
      */
      return( 0 );
   }


   /*
   **  Update transport record's ComBuf with new PDU, which consists of the
   **  16-bit sequence count and the data.
   **
   */
   /*
   ** Add the PDU's 16-bit sequence count (not to be confused with the 32-bit Transport
   ** Sequence Number that is incremented with each transmission).
   */
   *(LeUINT16 *) pBuf = *pui16LeSeqCount;

   /* Add data packet to ComBuf. */
   memcpy( pBuf + 2, paui8DataIn, ui16DataLen);

   /*
   **  Inform the Ethernet CD-layer that a new transport record is ready for
   **  transmission.
   */
   EN_CD_PutTransportBuffer( pTR->iTransportId );

   /* Return the number of bytes copied. */
   return( ui16DataLen );
} /* End of en_cd_ProducerCopyFunction() */



#endif  /* #ifdef CD_EN_OBJECTS */

/****************************************************************************
**
** End of EN_UTIL.C
**
*****************************************************************************
*/

⌨️ 快捷键说明

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