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

📄 ci_util.c

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

   pHeader = CB_GetDataPtrComBuf( pCombuf );

   /*
   ** Fill in the common details,
   ** then include the object status or not per its value.
   */

   pHeader->bService        = bRequestCode | CI_SC_REPLY_MASK;
   pHeader->bIoiSize        = 0;
   pHeader->bGenStatus      = bGenStatus;

   if( iERClength == 0 )
   {
      pHeader->bObjStatusSize = 0;
   }
   else
   {
      pHeader->bObjStatusSize =(UINT8)  iERClength;
      
      piLeObjStatus = &pHeader->iLeObjStatus;
      while( iERClength-- )
      {
         *piLeObjStatus = UC_iTOiLe( *piERC );
         piLeObjStatus++;
         piERC++;
      }
   }

} /* end of CI_PrependReplyHeaderWithExtendedERC() */



/*--------------------------------------------------------------------------
** CI_StripIoiPath()
**---------------------------------------------------------------------------
*/

void CI_StripIoiPath( CB_ComBufType *pComBuf, UINT16 iOffset )
{
   /*
   ** Shrink at the front for IOIs and in the middle for paths.
   */

   if( iOffset == 0 )
   {
      CB_ShrinkComBuf( pComBuf, CI_IoiPathSize( pComBuf, iOffset ) );
   }
   else
   {
      CB_ShrinkOffsetComBuf( pComBuf, iOffset, CI_IoiPathSize( pComBuf, iOffset ) );
   }

} /* end of CI_StripIoiPath() */



/****************************************************************************
**
** Private Services
**
*****************************************************************************
*/

/*---------------------------------------------------------------------------
** ci_ParseSegment()
**---------------------------------------------------------------------------
*/

UINT8 ci_ParseSegment( CB_ComBufType *pComBuf,
                       UINT16        *piOffset,
                       UINT8         *pbType,
                       UINT16        *piValue,
                       BOOL            fSize,
                       BOOL           fStrip )
{
   UINT8  *pbParse;
   UINT8  *pbSize;
   UINT16  iOffset;
   UINT16  iOffsetStrip;
   UINT16  iSize;

   /*
   ** Set up various pointers to interesting and useful places in the combuf.
   */

   iOffset = ( piOffset == NULL ) ? 0 : *piOffset;
   iOffsetStrip = iOffset;
   pbParse = pbSize = (UINT8*)(CB_GetDataPtrComBuf( pComBuf )) + iOffsetStrip;

   if( fSize )
   {
      iOffsetStrip += ( iOffset &  1 ) ? 1 : 2;
      pbParse      += ( iOffset &  1 ) ? 1 : 2;
      pbSize       += ( iOffset == 0 ) ? 1 : 0;
   }

   /*
   ** Check the size of the combuf versus what we're parsing.
   */

   if( fSize )
   {
      if( ( *pbSize == 0 ) ||
          ( ( *pbSize * 2 ) > ( CB_GetDataSizeComBuf( pComBuf ) - iOffsetStrip ) ) )
      {
         return( CI_GRC_BAD_PATH_SIZE );
      }
   }

   /*
   ** Get the segment type.
   */

   *pbType = *pbParse++;
   iSize = 0;

   switch( *pbType & CI_SEGMENT_TYPE_MASK )
   {
   case CI_PATH_SEGMENT:

      /*
	  ** check for multi-byte link address - return port number and link address length in piValue
      ** Note that the N_BIT bit set in pbType will indicate to the calling routine 
      ** that a multi-byte address has been found
      */
      if (*pbType & CI_PATH_SEG_N_BIT)
	  {
         /* port number in the high byte, link address length in low byte */
         *piValue = (*pbType & CI_PATH_SEG_PORT_MASK) << 8;
         *piValue |= *pbParse;

         /* size of segment includes link address and possible pad byte	*/
         iSize = 2 + *pbParse + (*pbParse & 1);
	  }

      /* single byte link address - return port number and link address in piValue */
      else
	  {
         /*
         ** Two pieces of data in a path segment.
 	     ** Return the port in the high byte of the value
         ** and the address in the low.
         */

	     *piValue = *pbType & CI_PATH_SEG_PORT_MASK;
 	     *piValue <<= 8;
         *piValue |= *pbParse;
         iSize = 2;
	  }
      break;


   case CI_LOGICAL_SEGMENT:

      /*
      ** First check for key segment.
      */

      if( *pbType == CI_LOGICAL_SEG_KEY )
      {
         /* Note: no change is needed to pbType */
        
         /*
         ** Electronic key segment.
         ** Just return the size in 16 bit words and the offset to the next segment.
         */

         *piValue = *pbParse;             /* Get size in words ( Only size of 4 dfined ) */
         iSize    = (*piValue << 1) + 2;  /* Convert to bytes and add seg and size bytes. */

         break; /* break out of switch statement */
      }

      /*
      ** Not a key segment, so
      ** Pull the appropriate value out of the packet for
      ** 8 and 16 bit logical segments.
      */

      switch( *pbType & CI_LOGICAL_SEG_FORMAT_MASK )
      {
      case CI_LOGICAL_SEG_8_BIT:

         *pbType &= CI_SEGMENT_TYPE_MASK | CI_LOGICAL_SEG_TYPE_MASK;
         *piValue = *pbParse;
         iSize = 2;
         break;


      case CI_LOGICAL_SEG_16_BIT:

         *pbType &= CI_SEGMENT_TYPE_MASK | CI_LOGICAL_SEG_TYPE_MASK;
         pbParse++;
         *piValue = UC_iLeTOi( *((UINT16*) pbParse) );
         iSize = 4;
         break;


      default:
         return( CI_GRC_BAD_PATH );
      }

      break;


   case CI_NETWORK_SEGMENT:

      /*
      ** Network segment value is the adjacent byte.
      */

      *piValue = *pbParse;
      iSize = 2;
      break;

   case CI_DATA_SEGMENT:

      switch( *pbType )
      {
      case CI_DATA_SEG_SIMPLE:
         /* Note: no change is needed to pbType */

         /*
         ** Just return the size in 16 bit words and the offset to the next segment.
         */

         *piValue = *pbParse;  /* Size in words */

         iSize = ( *piValue << 1 ) + 2; /* Convert size to bytes and add segment, and size bytes */

         break;

      case CI_DATA_SEG_SYMBOL:
         /* Note: no change is needed to pbType */
         
         /*
         ** Just return the size in bytes and the offset to the next segment.
         */

         *piValue = *pbParse;  /* Size in bytes */

         iSize = *piValue + ( *piValue & 1 ) + 2; /* Size, including pad, segment, and size bytes */

         break;

      default:

         *piValue = 0;
         iSize    = 0;
         break;
      }

      break;

   case CI_SYMBOLIC_SEGMENT:
   default:

      *pbType &= CI_SEGMENT_TYPE_MASK;
      *piValue = 0;
      iSize    = 0;
      break;
   }

   /*
   ** Optionally strip the segment from the packet.
   */

   if( fStrip )
   {
      /*
      ** Adjust the remaining size.
      */

      if( fSize )
      {
         *pbSize -= ( iSize / 2 );
      }

      if( iOffset == 0 )
      {
         /*
         ** Parsing from the start of the combuf.
         ** Remove the segment just parsed.
         */

         pbParse = CB_GetDataPtrComBuf( pComBuf );
         CB_ShrinkComBuf( pComBuf, iSize );

         if( fSize )
         {
            /*
            ** IOI being parsed.
            ** Replace the service code & adjusted size
            ** (which is still intact in the combuf where we started parsing).
            */

            CB_ShrinkComBuf( pComBuf, 2 );
            CB_PrependComBuf( pComBuf, pbParse, 2 );
         }
      }
      else
      {
         /*
         ** Parsing from the middle of the combuf.
         ** Remove the segment just parsed.
         */

         CB_ShrinkOffsetComBuf( pComBuf, iOffsetStrip, iSize );
      }
   }
   else
   {
      /*
      ** Adjust the parsing offset by the amount that would be stripped.
      */

      if( piOffset != NULL )
      {
         *piOffset += iSize;
      }
   }

   return( CI_GRC_SUCCESS );

} /* end of ci_ParseSegment() */



#endif  /* defined(CD_EN_OBJECTS) */

/****************************************************************************
**
** End of CI_UTIL.C
**
*****************************************************************************
*/

⌨️ 快捷键说明

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