📄 en_cd.c
字号:
/****************************************************************************
*****************************************************************************
**
** File Name
** ---------
**
** EN_CD.C
**
*****************************************************************************
*****************************************************************************
**
** Description
** -----------
**
** TCPIP version of the device independent communications services.
** The device independent CD interface shields the upper level software
** from any device specific details.
**
*****************************************************************************
*****************************************************************************
**
** Source Change Indices
** ---------------------
**
** Porting Changes
**
** 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. **
** **
*****************************************************************************
*****************************************************************************
*/
#include "stdio.h"
#include "cd.h" /* Communications Device public interfaces */
#ifdef CD_EN_OBJECTS
#include "um.h" /* UCMM interfaces (for rx packet pre-routing) */
#include "cm.h" /* Connection Manager (for rx packet pre-routing) */
#include "en.h"
#include "um_util.h"
#include "cd_util.h"
#include "en_util.h"
/*
** start edits: October,13th 2005, H.F.
*/
#include "ad.h" /* Application Data Area manager public interfaces */
#include "bf.h" /* Buffer Fragment mapper public interfaces */
#include "ad_util.h"
/*
** end edits: October,13th 2005, H.F.
*/
#include "ECInterface.h"
/****************************************************************************
**
** Private Globals
**
*****************************************************************************
*/
extern cd_RadioactiveMaskType sRadioActiveMasks;
/****************************************************************************
**
** Public Globals
**
*****************************************************************************
*/
OE_Q_ID MngOutgoingEncapQueue;
volatile en_InternalDataType en_s;
extern ENCAP_OBJ_TARGET list_target_data;
/****************************************************************************
**
** Public Services
**
*****************************************************************************
*/
/*---------------------------------------------------------------------------
** EN_CD_ConfigTask()
**---------------------------------------------------------------------------
*/
TASKRETURN EN_CD_ConfigTask( TASKPARAM )
{
cd_upsTrrblType upsTrrbl;
int iOnline = 0;
cd_TransportRecordType *pTr;
/*
** Now enter the task loop to accept and process (and serialize) requests
** from other tasks for Communications Device Configuration operations.
*/
while (1) {
upsTrrbl.Generic = GS_TakeTrrbl(CD_s[CD_ETHERNET_PORT].xConfigQid);
upsTrrbl.Generic->eStatus = SUCCESS;
switch (upsTrrbl.Generic->eRequest) {
case TREQ_BIT_MSG:
GS_ReturnTrrbl(upsTrrbl.Generic);
break;
case TREQ_TX_CONFIG:
/*
** Submit a config packet to TCPIP stream B. The header was
** added to the packet before being sent here. It is assumed
** that the configuration Lpacket does not exceed 32 bytes.
**
** Make sure this config packet originated in the current state
*/
GS_DeleteTrrblAndComBuf(upsTrrbl.Packet);
GS_LogEvent(CD_UNSUPPORTED_CONFIG_REQUEST,
upsTrrbl.Generic->eRequest, upsTrrbl.Generic, FATAL);
break;
case TREQ_UPDATE_ERROR_LOG:
GS_ReturnTrrbl(upsTrrbl.Generic);
break;
case TREQ_RESERVE_TRANSPORTS:
/*
** Reserve transports for a connection.
*/
upsTrrbl.Generic->eStatus = cd_CommissionTransports(upsTrrbl.Tran);
GS_ReturnTrrbl(upsTrrbl.Generic);
break;
case TREQ_START_TRANSPORTS:
/*
** Start transports for a connection.
*/
upsTrrbl.Generic->eStatus = cd_CommissionTransports(upsTrrbl.Tran);
GS_ReturnTrrbl(upsTrrbl.Generic);
break;
case TREQ_DELETE_TRANSPORTS:
/*
** Delete transports for a connection.
*/
if ( ( upsTrrbl.Tran->psConnRecord->iPort == CD_ETHERNET_PORT ) &&
( ( upsTrrbl.Tran->psConnRecord->iProConnParams & CM_CP_TYPE_MASK ) == CM_CP_TYPE_MULTICAST ) )
{
/*
** Free the allocated IP Multicast address for a Class1 multicast
** producer connection.
*/
pTr = cd_LookupTransportRecord( CD_ETHERNET_PORT, upsTrrbl.Tran->psConnRecord->iProTransportId );
if( pTr )
{
/*
** Make sure this is the last consumer of this multicast address
** before we delete it
*/
if ( cd_NumConnSnLinkedToTransport( pTr ) == 1 )
{
en_cd_FreeIpMcastAddress( upsTrrbl.Tran->psConnRecord );
}
}
} /* End if ethernet */
/*
** start edits: October,11th 2005, H.F.
**
** new input in function call
**
cd_DeleteTransport(upsTrrbl.Tran->psConnRecord->iPort,
upsTrrbl.Tran->psConnRecord->iProTransportId,
upsTrrbl.Tran->psConnRecord->iConnectionSn);
**
*/
cd_DeleteTransport(upsTrrbl.Tran->psConnRecord->iPort,
upsTrrbl.Tran->psConnRecord->iProTransportId,
upsTrrbl.Tran->psConnRecord->iConnectionSn,
upsTrrbl.Tran->psConnRecord);
/*
** end edits: October,11th 2005, H.F.
*/
/*
** We need to drop the multicast group that we will be listening on
*/
if ( upsTrrbl.Tran->psConnRecord->iPort == CD_ETHERNET_PORT )
{
if( ( upsTrrbl.Tran->psConnRecord->iConConnParams & CM_CP_TYPE_MASK ) == CM_CP_TYPE_MULTICAST )
{
/* Drop the multicast listening group for this connection. If other connections
** are still listening the count will be decremented by one, and the multicast
** group will still be listened to. Note that in cd_util.c the multicast
** group is only joined once for each transport hence the need to check the
** number linked before we drop the multicast address. However, it is possible
** that more than one producer is using the same multicast group whcih is
** why we maintain a count for the number of times a multicast group
** is joined.
*/
if( upsTrrbl.Tran->psConnRecord->sEce.psMcast )
{
pTr = cd_LookupTransportRecord( CD_ETHERNET_PORT, upsTrrbl.Tran->psConnRecord->iConTransportId );
if( pTr )
{
/*
** Make sure this is the last local consumer of this multicast address
** before we delete it
*/
if ( cd_NumConnSnLinkedToTransport( pTr ) == 1 )
{
en_cd_DropMulticast(&upsTrrbl.Tran->psConnRecord->sEce.psMcast->sMc_addr);
}
}
GS_Free( upsTrrbl.Tran->psConnRecord->sEce.psMcast );
}
}
} /* End if an ethernet port */
/*
** start edits: October,11th 2005, H.F.
**
** new input in function call
**
cd_DeleteTransport(upsTrrbl.Tran->psConnRecord->iPort,
upsTrrbl.Tran->psConnRecord->iConTransportId,
upsTrrbl.Tran->psConnRecord->iConnectionSn);
**
*/
cd_DeleteTransport(upsTrrbl.Tran->psConnRecord->iPort,
upsTrrbl.Tran->psConnRecord->iConTransportId,
upsTrrbl.Tran->psConnRecord->iConnectionSn,
upsTrrbl.Tran->psConnRecord);
/*
** end edits: October,11th 2005, H.F.
*/
GS_ReturnTrrbl(upsTrrbl.Generic);
break;
case TREQ_TIMER_EXPIRED:
/*
** Rx transport timer expired.
** Process the timeout tribble and start to close the connection.
*/
cd_ProcessTimer( upsTrrbl.Timeout );
break;
case TREQ_GO_ONLINE:
/*
** Start off with the Netconfig task which will do the DNS etc. After this task
** is complete the other tasks for the ethernet CD are started
*/
if (iOnline == 0)
{
iOnline = 1;
}
GS_ReturnTrrbl(upsTrrbl.Generic);
break;
case TREQ_UPDATE_NET_PARAMS:
case TREQ_FORCED_LISTEN_ONLY:
case TREQ_RESET_AND_GO_ONLINE:
case TREQ_RESET_TO_OFFLINE:
case TREQ_SET_MAC_ID:
default:
GS_LogEvent(CD_UNSUPPORTED_CONFIG_REQUEST,
upsTrrbl.Generic->eRequest, upsTrrbl.Generic, FATAL);
break;
} /* end of switch on configuration tribble request code */
} /* end of while( 1 ) task loop */
} /* End of EN_CD_ConfigTask() */
/*---------------------------------------------------------------------------
** EN_Init()
**---------------------------------------------------------------------------
*/
StatusType EN_Init( UINT16 iOptions )
{
/*
** Allocate/Create all resources (except for tasks).
*/
if (iOptions & AB_CREATE_RESOURCE)
{
/*
** Initialize private data structure
*/
}
/*
** Initialize all internal data structures.
*/
if (iOptions & AB_INIT_RESOURCE)
{
}
/*
** Create the task & associate it with the message queue created earlier.
*/
if (iOptions & AB_CREATE_TASK)
{
} /* end if AB_CREATE_TASK */
/*
** Final initialization after tasks are running.
*/
if (iOptions & AB_INIT_TASK)
{
}
return (SUCCESS);
} /* End of EN_Init() */
/*---------------------------------------------------------------------------
** EN_CD_GetTransportBuffer()
**---------------------------------------------------------------------------
*/
UINT8 *EN_CD_GetTransportBuffer( UINT16 iTransport )
{
/*
** Unlike the controlnet version of the CML the ethernet will
** only use a single buffer per transport. Access to the
** buffer will be locked by a semaphore during a get. And unlocked
** with a put
*/
cd_TransportRecordType *pTr;
UINT8 *pBuffer;
UINT32 nStatus;
/*
** Lookup the channel record to get access to the buffer pointers.
*/
if ( ( pTr = cd_LookupTransportRecord( CD_ETHERNET_PORT, iTransport ) ) != NULL )
{
/*
** Check for availability of a scheduled Tx buffer
*/
nStatus = GS_WaitSemaphore( pTr->xSBufAccess );
if (nStatus != SUCCESS) /* Perhaps the transport is being deleted */
{
DBLN( "Unavailable GetTransportSemaphore, Transport" );
return( NULL );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -