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

📄 en_encap.c

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

      PktBufFree( psPktBuf );
      break;

   /*
   ** Not sure how this could happen, but we should crash on the error.
   */

   default:
      GS_LogEvent( CD_UNSUPPORTED_CONFIG_REQUEST,         /* Incorrect type code specified in ECE */
                  ECE_TYPE( psEce->sEid ),
                  0,
                  FATAL );
      break;
   }
}


/*---------------------------------------------------------------------------
** en_cd_CreateMcastTable( )
**---------------------------------------------------------------------------
*/

void en_cd_CreateMcastTable( struct in_addr * NET_ipaddr, struct in_addr * NET_subnet )
{
   MCAST_P         map;
   UINT32          netmask;
   UINT32          ipaddr;
   INT32           i;
   UINT32          host;
   UINT32          ma;

   ipaddr = htonl( NET_ipaddr->s_addr );

   /*
   ** If subnet mask is set, then net and hosts are determined by the mask
   */

   if ( NET_subnet->s_addr )
      netmask = htonl( NET_subnet->s_addr );
   else
   {
      if ( IN_CLASSA( ipaddr ) )
         netmask = IN_CLASSA_NET;
      else if ( IN_CLASSB( ipaddr ) )
         netmask = IN_CLASSB_NET;
      else
         netmask = IN_CLASSC_NET;
   }

   host = ipaddr & ( ~netmask );

   /*
   ** Mask host number, shift and add to base address.
   */

   ma = CIP_MCAST_BASE + ( ( host & CIP_MCAST_HMASK ) << CIP_MCAST_BSHIFT );

   for ( i = 0, map = &sMcast_table.asMcast[ 0 ]; i < NUM_MCAST_BLOCKS; i++, map++, ma++ )
   {
      map->lFree = 1;
      UC_SetMem( ( caddr_t ) &map->sMc_addr, 0, sizeof( struct sockaddr_in ) );
#ifndef WIN32
      map->sMc_addr.sin_len = sizeof( struct sockaddr_in );
#endif
      map->sMc_addr.sin_family = AF_INET;
      map->sMc_addr.sin_port = htons( CLASS1_UDP_PORT );
      map->sMc_addr.sin_addr.s_addr = htonl( ma ); /* ma is host order, put in net order */
   }
   sMcast_table.lValid = 1;
}



/*---------------------------------------------------------------------------
** en_cd_InitTargetData( )
**---------------------------------------------------------------------------
*/

void en_cd_InitTargetData( void )
{
   struct in_addr  NET_ipaddr;         /* IP address assigned to the module */
   struct in_addr  NET_subnet;         /* IP subnet mask ( if any ) assigned to
                                        * the module */
   UINT32          nStatus;
   INT32           nNameLen;


   u_char         *p;

   list_target_data.sS.s_sock.iSin_family = htons( AF_INET );
   list_target_data.sS.s_sock.iSin_port = htons( lEncapServerPort );

   /*
   ** Default IP address on primary interface
   */

   list_target_data.sS.s_sock.lSin_addr = htonl( 0 );
   en_cd_IFGetConfig( &NET_ipaddr, &NET_subnet, 0 );
   list_target_data.sS.s_sock.lSin_addr = NET_ipaddr.s_addr;

   /*
   ** Ugly but........
   */

   nStatus = gethostname( list_target_data.sS.achS_name, sizeof list_target_data.sS.achS_name );
   list_target_data.sS.achS_name[ sizeof( list_target_data.sS.achS_name ) - 1 ] = '\0';
   nNameLen = strlen( list_target_data.sS.achS_name ) + 1;   /* Include the NULL */
   p = ( u_char * ) & list_target_data.sS.s_sock.lSin_addr;
   sprintf( IPAddress, "%d.%d.%d.%d", p[ 0 ], p[ 1 ], p[ 2 ], p[ 3 ] );
   if ( ( nStatus != OK ) || ( nNameLen < 2 ) || ( nNameLen >= sizeof( list_target_data.sS.achS_name ) ) )
   {
      /*
      ** no name assigned ? Use the IP address
      */
      sprintf( &list_target_data.sS.achS_name[ 0 ], "%d.%d.%d.%d", p[ 0 ], p[ 1 ], p[ 2 ], p[ 3 ] );
      list_target_data.sS.achS_name[ sizeof( list_target_data.sS.achS_name ) - 1 ] = '\0';
   }

   /*
   **  create the multicast table based on IP address
   */

   en_cd_CreateMcastTable( &NET_ipaddr, &NET_subnet );

}



#undef PROC
#define PROC "en_cd_ListTargetsReceived"

/*---------------------------------------------------------------------------
** en_cd_ListTargetsReceived( )
**---------------------------------------------------------------------------
*/

void en_cd_ListTargetsReceived( ECE * psEce, PKTBUF_P psPktBuf )
{

   ENCAPH          *psEncapHdr = ( ENCAPH * ) ( &psPktBuf->sEncap.sHdr );

   switch ( ECE_TYPE( psEce->sEid ) )
   {

   /*
   ** Process a request from a client for target ( server ) information
   */

   case ECE_TYPE_INBOUND:

      sEncapStats.lCommandsReceived++;

      /*
      ** Check length of command specific data. There shouldn't be any.
      */

      if ( psEncapHdr->iEncaph_length != 0 )
      {
         sEncapStats.lErrBadData++;
         en_cd_EncapErrorReply( psPktBuf, ENCAP_E_BADDATA, NULL, 0 );
      }

      else
      {
         if ( psEncapHdr->lEncaph_status == ENCAP_E_SUCCESS )
         {
            UC_CopyMem( ( caddr_t ) &psPktBuf->abData[ 0 ], ( caddr_t ) &list_target_data,
                  sizeof( list_target_data ) );
            psPktBuf->lLength = sizeof( list_target_data );
            psPktBuf->sEncap.sObj_list.iO_count = 1;
            psPktBuf->sEncap.lValid = PKTBUF_ENCAPV_OBJ;

            psEncapHdr->lEncaph_status = 0;
            psEncapHdr->iEncaph_length = ENCAP_OBJ_LIST_SIZE + psPktBuf->lLength;

            sEncapStats.lRepliesSent++;
            en_cd_SendEncapCommand( psPktBuf );
         }
         else
            PktBufFree( psPktBuf );
      }
      break;

   /*
   ** Silently ignore the command
   */

   case ECE_TYPE_OUTBOUND:

      if ( psEncapHdr->lEncaph_status == ENCAP_E_SUCCESS )
         sEncapStats.lRepliesReceived++;
      else
         sEncapStats.lRepliesReceivedErrs++;

      PktBufFree( psPktBuf );
      break;

   /*
   ** Not sure how this could happen, but we should crash on the error.
   */

   default:
      GS_LogEvent( CD_UNSUPPORTED_CONFIG_REQUEST,         /* Incorrect type code specified in ECE */
                  ECE_TYPE( psEce->sEid ),
                  0,
                  FATAL );
      break;
   }
}

#undef PROC
#define PROC "en_cd_ListIdentityReceived"

/*---------------------------------------------------------------------------
** en_cd_ListIdentityReceived( )
**---------------------------------------------------------------------------
*/

extern struct id_DataType id_s;
extern INT32 lEncapServerPort;
void en_cd_ListIdentityReceived( ECE * psEce, PKTBUF_P psPktBuf )
{
	ENCAPH          *psEncapHdr = ( ENCAPH * ) ( &psPktBuf->sEncap.sHdr );

	int aHdrSize;
	int aFSDataSize;
	int aProductNameSize;
	typedef struct s_list_identity_data_header{
		UINT16 ItemTypeCode;
		UINT16 ItemLength;
	}s_list_identity_data_header;

	typedef struct s_list_identity_data_without_ProductName{
		UINT16 EncapsulationProtocolVersion;
/*		struct s_SocketAddress{ */
			INT16   sin_family;
			UINT16  sin_port;
			UINT32  sin_addr;
			INT8 sin_zero[8];
/*		}SocketAddress; */
		UINT16 VendorId;
		UINT16 DeviceType;
		UINT16 ProductCode;
		INT8   Revision[2];
		UINT16 Status;
		UINT32 SerialNumber;
	}s_list_identity_data_without_ProductName;

	struct s_list_identity_data{
		s_list_identity_data_header              Hdr;
		s_list_identity_data_without_ProductName FSData;
		INT8                                     ProductNameSize;
		INT8                                     ProductName[128+1];
	}list_identity_data;

   switch ( ECE_TYPE( psEce->sEid ) )
   {

   /*
   ** Process a request from a client for a list of our identities
   */

   case ECE_TYPE_INBOUND:

      sEncapStats.lCommandsReceived++;

      /*
      ** Check length of command specific data. There shouldn't be any.
      */

      if ( psEncapHdr->iEncaph_length != 0 )
      {
         sEncapStats.lErrBadData++;
         en_cd_EncapErrorReply( psPktBuf, ENCAP_E_BADDATA, NULL, 0 );
      }

      else
      {
         if ( psEncapHdr->lEncaph_status == ENCAP_E_SUCCESS )
         {

/* list services
**            UC_CopyMem( ( caddr_t ) &psPktBuf->abData[ 0 ], ( caddr_t ) &list_services_data,
**                  sizeof( list_services_data ) );
**
**            psPktBuf->sEncap.sObj_list.iO_count = 1;
**            psPktBuf->lLength                   = sizeof( list_services_data );
**            psPktBuf->sEncap.lValid             = PKTBUF_ENCAPV_OBJ;
**            psEncapHdr->lEncaph_status          = 0;
**            psEncapHdr->iEncaph_length          = ENCAP_OBJ_LIST_SIZE + psPktBuf->lLength;

** list interfaces
**            psPktBuf->sEncap.sObj_list.iO_count = 0;   /* Currently not implemented *//*
**            psPktBuf->lLength                   = psPktBuf->sEncap.sObj_list.iO_count * ENCAP_OBJ_TARGET_SIZE;
**            psPktBuf->sEncap.lValid             = PKTBUF_ENCAPV_OBJ;
**            psEncapHdr->lEncaph_status          = 0;
**            psEncapHdr->iEncaph_length          = ENCAP_OBJ_LIST_SIZE + psPktBuf->lLength;
**

** list targets
**            UC_CopyMem( ( caddr_t ) &psPktBuf->abData[ 0 ], ( caddr_t ) &list_target_data,
**                  sizeof( list_target_data ) );
**
**            psPktBuf->sEncap.sObj_list.iO_count = 1;
**            psPktBuf->lLength                   = sizeof( list_target_data );
**            psPktBuf->sEncap.lValid             = PKTBUF_ENCAPV_OBJ;
**            psEncapHdr->lEncaph_status          = 0;
**            psEncapHdr->iEncaph_length          = ENCAP_OBJ_LIST_SIZE + psPktBuf->lLength;
*/

			/* ! */
			aHdrSize         = sizeof( list_identity_data.Hdr );
			aFSDataSize      = sizeof( list_identity_data.FSData );
			aProductNameSize = strlen( id_s.abProductName );

			/* ! */
			memset( &list_identity_data, 0, sizeof( list_identity_data ) );

			list_identity_data.Hdr.ItemTypeCode                    = 0x0c;
			list_identity_data.Hdr.ItemLength                      = aFSDataSize + 1 + aProductNameSize;   /* ! size of items that follows */
			list_identity_data.FSData.EncapsulationProtocolVersion = ENCAP_PROTOCOL_VERSION; 
			list_identity_data.FSData.sin_family                   = htons(AF_INET);                
			list_identity_data.FSData.sin_port                     = htons(lEncapServerPort);
			list_identity_data.FSData.sin_addr                     = list_target_data.sS.s_sock.lSin_addr;
/*			list_identity_data.FSData.sin_zero                     = ;                       */
			list_identity_data.FSData.VendorId                     = id_s.iVendorId;         
			list_identity_data.FSData.DeviceType                   = id_s.iProductType;      
			list_identity_data.FSData.ProductCode                  = id_s.iProductCode;      
			list_identity_data.FSData.Revision[0]                  = id_s.bMajorRev;         
			list_identity_data.FSData.Revision[1]                  = id_s.bMinorRev;         
			list_identity_data.FSData.Status                       = id_s.iStatus;           
			list_identity_data.FSData.SerialNumber                 = id_s.lSerialNumber;     
			list_identity_data.ProductNameSize                     = aProductNameSize;
			strcpy(list_identity_data.ProductName, id_s.abProductName );

			/* ! */
            UC_CopyMem( ( caddr_t ) &psPktBuf->abData[ 0 ], ( caddr_t ) &list_identity_data, aHdrSize+aFSDataSize+1+aProductNameSize );

            psPktBuf->sEncap.sObj_list.iO_count = 1;
            psPktBuf->lLength                   = aHdrSize+aFSDataSize+1+aProductNameSize;
            psPktBuf->sEncap.lValid             = PKTBUF_ENCAPV_OBJ;
            psEncapHdr->lEncaph_status          = 0;
            psEncapHdr->iEncaph_length          = ENCAP_OBJ_LIST_SIZE + psPktBuf->lLength;

            sEncapStats.lRepliesSent++;
            en_cd_SendEncapCommand( psPktBuf );

         }
         else
            PktBufFree( psPktBuf );
      }
      break;

   /*
   ** Silently ignore the command...
   */

   case ECE_TYPE_OUTBOUND:

      if ( psEncapHdr->lEncaph_status == ENCAP_E_SUCCESS )
         sEncapStats.lRepliesReceived++;
      else
         sEncapStats.lRepliesReceivedErrs++;

      PktBufFree( psPktBuf );
      break;

   /*
   ** Not sure how this could happen, but we should crash on the error.
   */
   default:
      GS_LogEvent( CD_UNSUPPORTED_CONFIG_REQUEST,         /* Incorrect type code specified in ECE */
                  ECE_TYPE( psEce->sEid ),
                  0,
                  FATAL );
      break;
   }

}

#undef PROC
#define PROC "en_cd_RegisterReceived"

/*---------------------------------------------------------------------------
** en_cd_RegisterReceived( )
**---------------------------------------------------------------------------
*/

void en_cd_RegisterReceived( ECE * psEce, PKTBUF_P psPktBuf )
{
   ENCAPH          *psEncapHdr = ( ENCAPH * ) ( &psPktBuf->sEncap.sHdr );
   EnCdMessageType EnCdMessage;
   OE_Q_ID        sOutputQ;

   switch ( ECE_TYPE( psEce->sEid ) )
   {

   /*
   ** Process a request from a client to register
   */

   case ECE_TYPE_INBOUND:
      {
         void           *data = NULL;
         INT32           data_len = 0;
         ENCAP_RC_DATA   *rc = psPktBuf->pData;
         INT32           status = ENCAP_E_SUCCESS;

         sEncapStats.lCommandsReceived++;

         if ( psEncapHdr->lEncaph_status != ENCAP_E_SUCCESS )
         {
            PktBufFree( psPktBuf );
            return;
         }

         do
         {
            /*
            ** Check the length of command specific data. If the length is
            ** correct, assume that the length in the ENCAP header matches the
            ** length for the PKTBUF data area.
            */

            if ( psEncapHdr->iEncaph_length != ENCAP_RC_DATA_SIZE )
            {
         

⌨️ 快捷键说明

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