📄 ecuserdefined_obj.c
字号:
/****************************************************************************
*****************************************************************************
**
** File Name
** ---------
**
** USERDEFINED_OBJ.C
**
*****************************************************************************
*****************************************************************************
**
** Description
** -----------
**
** This source module implements the Identity Object.
**
** This implementation of the object has been made as option parameter driven
** as possible. By changing the defined "device profile" in AB_ENV.h and
** AB_CFG.h, the application developer can modify the behavior of the
** Device Object.
** It should NOT be necessary to directly modify the code in this module.
**
*****************************************************************************
*****************************************************************************
**
** Source Change Indices
** ---------------------
**
** Porting: <none>0----<major> Customization: <none>0----<major>
**
*****************************************************************************
*****************************************************************************
** **
** ETHERNET/IP EXAMPLE CODE **
** COPYRIGHT (c) 2000-2005 ODVA (Open DeviceNet Vendor Association) **
** & ControlNet International Ltd. **
** **
** All rights reserved, except as specifically licensed in writing. **
** Use of the Ethernet/IP Example Protocol Software is subject to **
** ODVA's and ControlNet International's Terms of Use Agreement. **
** The following work constitutes example program code and is intended **
** merely to illustrate useful programming techniques. The user is **
** responsible for applying the code correctly. The code is provided **
** AS IS without warranty and is in no way guaranteed to be error-free. **
** **
*****************************************************************************
*****************************************************************************
*/
/****************************************************************************
*****************************************************************************
**
** Change Log
** ----------
**
**
*****************************************************************************
*****************************************************************************
*/
#include "ab.h"
#include "cd.h" /* Communications Device public interfaces */
#include "mr.h" /* Message Router public interfaces */
#include "cd_util.h"
#include "ECInterface.h"
#include "ECUserDefined_obj.h"
/***************************************************************************/
/****************************************************************************
*****************************************************************************
**
** Public Globals
**
*****************************************************************************
*****************************************************************************
*/
GS_MsgQueueType USERDEFINED_xQid;
/****************************************************************************
*****************************************************************************
**
** Private Globals
**
*****************************************************************************
*****************************************************************************
*/
/****************************************************************************
*****************************************************************************
**
** Public Services
**
*****************************************************************************
*****************************************************************************
*/
/*---------------------------------------------------------------------------
** USERDEFINED_Init()
**---------------------------------------------------------------------------
*/
StatusType UserDefined_Init( UINT16 iOptions )
{
GS_TaskSeedType sSeed;
MR_RegistrationTrrblType *pMrTrrbl;
unsigned int cc;
/*
** Allocate/Create all resources (except for tasks).
*/
if( iOptions & AB_CREATE_RESOURCE )
{
/*
** Create the task's request queue.
*/
USERDEFINED_xQid = GS_NewMsgQueue();
}
/*
** Initialize all internal data structures.
*/
if( iOptions & AB_INIT_RESOURCE )
{
/*
** Initialize the instance attributes to the default values.
*/
}
/*
** Create the task & associate it with the message queue created earlier.
*/
if( iOptions & AB_CREATE_TASK )
{
sSeed.pRoutine = UserDefined_ObjectTask;
sSeed.pParameter = NULL;
sSeed.pStack = NULL;
sSeed.iStackSize = USERDEFINED_STACK_SIZE;
sSeed.nPrio = USERDEFINED_TASK_PRIO;
sSeed.pTaskName = "USRD";
GS_AssociateTaskAndQueues( GS_NewTask( &sSeed ), USERDEFINED_xQid, GS_NO_QUEUE );
}
/*
** Final initialization after tasks are running.
*/
if( iOptions & AB_INIT_TASK )
{
/*
** Register ourselves with the message router.
*/
/* ! register user defined classes */
for( cc=0; cc<gUserDefined->itsClassesCount; cc++ ){
/* ! register class */
pMrTrrbl = GS_NewTrrbl( MR_RegistrationTrrblType );
pMrTrrbl->eRequest = TREQ_REGISTER_OBJECT;
pMrTrrbl->iClass = gUserDefined->itsClasses[cc].itsClassCode;
pMrTrrbl->iInstance = MR_CLASS_AND_INSTANCES;
pMrTrrbl->iPort = MR_ALL_PORTS;
pMrTrrbl->xQ = USERDEFINED_xQid;
GS_PutTrrbl( MR_xQid, pMrTrrbl );
}
}
return( SUCCESS );
} /* end of USERDEFINED_Init() */
/****************************************************************************
*****************************************************************************
**
** Private Services
**
*****************************************************************************
*****************************************************************************
*/
/*---------------------------------------------------------------------------
** UserDefined_ObjectTask()
**---------------------------------------------------------------------------
*/
TASKRETURN UserDefined_ObjectTask( TASKPARAM )
{
CB_ComBufType *pComBuf;
CI_IoiType *pIOI;
UINT8 bService;
UserDefined_upsTrrblType upsTrrbl;
unsigned int i;
t_Class *aClass;
/*
** Process request tribbles one at a time (in an endless task loop).
*/
while ( 1 )
{
/*
** Process tribbles one at a time.
** Make sure we've gotten an expected tribble.
*/
upsTrrbl.Generic = GS_TakeTrrbl( USERDEFINED_xQid );
/* ! find Class */
aClass = NULL;
for( i=0; i<gUserDefined->itsClassesCount; i++ ){
if( gUserDefined->itsClasses[i].itsClassCode==upsTrrbl.Packet->iClass ){
aClass = &gUserDefined->itsClasses[i];
break;
}
}
if( aClass==NULL ){
/* ! */
GS_LogEvent( UNKNOWN_TRRBL_REQUEST, upsTrrbl.Generic->eRequest, upsTrrbl.Generic, FATAL );
/* ! */
continue;
}
/* ! */
switch ( upsTrrbl.Generic->eRequest )
{
case TREQ_APP_OPEN:
/*
** App open (initial connection request notification).
*/
UserDefined_ProcessAppOpen( upsTrrbl.AppOpenClose );
continue;
case TREQ_RX_UNSCHEDULED_PACKET:
/*
** Unscheduled packet received. Just fall through to the
** packet processing code.
*/
break ;
case TREQ_APP_CLOSE:
/*
** Received an orphaned or null close, so just return the trrbl,
** let the CM take care of it.
*/
GS_ReturnTrrbl( upsTrrbl.Generic );
continue;
default:
GS_LogEvent( UNKNOWN_TRRBL_REQUEST, upsTrrbl.Generic->eRequest, upsTrrbl.Generic, FATAL );
continue;
} /* end of switch( pTrrbl->eRequest ) */
/*
** We've received a request packet.
** Is this a class or instance request, or something invalid.
*/
switch ( upsTrrbl.Packet->iInstance )
{
case 0:
UserDefined_ProcessClassRequest( aClass, upsTrrbl.Packet );
GS_ReturnTrrbl( upsTrrbl.Packet );
break;
default:
/* ! find instance */
for( i=0; i<aClass->itsInstancesCount; i++ )
if( aClass->itsInstances[i].itsInstanceCode==upsTrrbl.Packet->iInstance )
break; /* ! for */
/* ! */
if( i<aClass->itsInstancesCount )
if( !UserDefined_ProcessInstanceRequest( &aClass->itsInstances[i], upsTrrbl.Packet ) ){
GS_ReturnTrrbl( upsTrrbl.Packet );
continue;
}
/* ! */
pComBuf = upsTrrbl.Packet->pComBuf;
pIOI = CB_GetDataPtrComBuf( pComBuf );
bService = pIOI->bService;
CB_ClearComBuf( pComBuf );
CI_PrependReplyHeader( pComBuf, bService, CI_GRC_BAD_CLASS_INSTANCE, 0 );
GS_ReturnTrrbl( upsTrrbl.Packet );
/* ! */
break;
}
} /* end of while( 1 ) */
} /* end of UserDefined_ObjectTask() */
/*---------------------------------------------------------------------------
** UserDefined_ProcessAppOpen()
**---------------------------------------------------------------------------
*/
void UserDefined_ProcessAppOpen( CM_AppOpenCloseTrrblType *psTrrbl )
{
CM_ConnectionRecordType *psConnRecord;
/*
** Grab all of the interesting information from the tribble.
*/
psConnRecord = psTrrbl->psConnRecord;
if( CM_IsConnectionTypeNull( psConnRecord ) )
{
/*
** Just say YES, if Connection Type is NULL!
*/
psTrrbl->eStatus = SUCCESS;
}
else
{
/*
** Somebody's trying to connect to us. Just say NO,
** if Connection Type is not NULL!
*/
psTrrbl->eStatus = CM_UNCONNECTABLE_OBJECT;
}
GS_ReturnTrrbl( psTrrbl );
} /* end of UserDefined_ProcessAppOpen() */
/*---------------------------------------------------------------------------
** UserDefined_ProcessClassRequest()
**---------------------------------------------------------------------------
*/
void UserDefined_ProcessClassRequest( t_Class *theClass, CD_PacketTrrblType *pTrrbl )
{
CB_ComBufType *pComBuf;
CB_ComBufType *pComBufNew;
CI_IoiType *pIOI;
UINT8 bIOIsize;
UINT8 bService;
int aClassAttributeSize;
int aClassAttributesByteSize;
UINT8 *aClassAttributesBuf;
t_Attribute *aAttribute;
UINT8 bSegType;
UINT16 iAttribute,i; /* i: index in for-loop; H.F. 05-12-2002 */
UINT16 iERCAttributeID; /* H.F. 05-12-2002 */
#define ERROR_RET(code){ CB_ClearComBuf( pComBuf ); CI_PrependReplyHeader( pComBuf, bService, code, 0 ); return; }
/* error code with extended status; H.F. 05-12-2002 */
#define ERROR_RET_EXT(code){ CB_ClearComBuf( pComBuf ); CI_PrependReplyHeaderWithExtendedERC( pComBuf, bService, code, 1, &iERCAttributeID ); return; }
/*
** Valid tribble/combuf. Pull out the essential information.
*/
pComBuf = pTrrbl->pComBuf;
pIOI = CB_GetDataPtrComBuf( pComBuf );
bService = pIOI->bService;
bIOIsize = pIOI->bIoiSize;
/*
** Class request. Get attribute all is the only thing supported.
*/
/*
** If there is anything remaining in the IOI, we have a problem.
*/
switch ( bService ){
case CI_SC_GET_ATTR_ALL:
/* ! */
if( 0!=bIOIsize )
ERROR_RET( CI_GRC_BAD_PATH );
/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -