📄 en_xport.c
字号:
/****************************************************************************
*****************************************************************************
**
** File Name
** ---------
**
** EN_XPORT.C
**
*****************************************************************************
*****************************************************************************
**
** Description
** -----------
**
** Transport management services for the TCPIP Interface.
**
*****************************************************************************
*****************************************************************************
**
** 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. **
** **
*****************************************************************************
*****************************************************************************
*/
#include "cd.h" /* Communications Device public interface */
#include "cm.h" /* Connection Manager public interfaces */
#include "nt.h"
#ifdef CD_EN_OBJECTS
#include "string.h"
#include "cd_util.h"
#include "en_util.h"
#include "en_xport.h" /* Ethernet transports */
#include "en.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 CPFHDR sCpfHdr;
extern cd_RadioactiveMaskType sRadioActiveMasks;
/****************************************************************************
**
** Public Services
**
*****************************************************************************
*/
/****************************************************************************
**
** Private Services
**
*****************************************************************************
*/
/*---------------------------------------------------------------------------
** en_cd_StartTransport( )
**---------------------------------------------------------------------------
*/
StatusType en_cd_StartTransport( cd_TransportRecordType * pTr )
{
StatusType eStatus;
BOOL fEntryFound = FALSE;
CPFHDR *msg;
/*
** Determine TCPIP ASIC Transport Type from Forward Open
** Transport Class and Trigger byte. Only support transport
** classes 1 and 3.
*/
switch ( pTr->iClass )
{
case CM_TCT_CLASS_1:
/*
** Allocate the dedicated transport buffers.
** Bail out if the allocation fails.
** Zero data size is a special case for producing heartbeats.
*/
pTr->iBufState = INITIAL;
/*
** Allocate temporary storage space for the xmit buffers
*/
pTr->pBufA = GS_Malloc( pTr->iDataSize + sizeof( pTr->iLeSeqCount ) );
pTr->xSBufAccess = GS_NewSemaphore( );
if ( ( pTr->pBufA == NULL ) ||
( pTr->xSBufAccess == NULL ) )
{
eStatus = CD_RESOURCE_UNAVAILABLE;
goto Bailout;
} /* End if buffer allocation test */
UC_SetMem(pTr->pBufA, 0, pTr->iDataSize + sizeof(pTr->iLeSeqCount));
pTr->pBufB = GS_Malloc(pTr->iDataSize + sizeof(pTr->iLeSeqCount) +
sizeof( CPFHDR ) );
if (pTr->pBufB == NULL)
{
GS_LogEvent(EN_RESOURCE,
0,
0,
FATAL);
goto Bailout;
} /* End if message == NULL */
msg = (CPFHDR *) (pTr->pBufB);
/*
** Copy the static template information and then the data...
*/
UC_CopyMem((char *) msg, (char *) &sCpfHdr, sizeof sCpfHdr);
*((UINT32 *) msg->aiAs_cid) = ENCAP_TO_PL(*(UINT32 *) pTr->abTxTag);
msg->iDs_length = ENCAP_TO_HS(pTr->iDataSize + 2); /* Include 2 bytes of Transport sequence count */
/*
** Invalidate buffer.
*/
*((UINT32 *) msg->aiAs_seq) = ~ENCAP_TO_PL(pTr->iSeqCount);
/*
** Fill the semaphore so we can "Get" a transport record
*/
GS_SetSemaphore( pTr->xSBufAccess );
/*
** If this is a bridged connection do not do any RPI related functions.
*/
/*jjw 8/22/00 */
if ( pTr->fBridged )
break; /* break out of class 1 functions */
if ( pTr->fServerConsumer ) /* Consumer */
{
} /* End if consumer */
else /* Producer */
{
/*
** Verify that a valid schedule request is being made
*/
/* jjw Verify the PIT and API parameters here */
if ( pTr->lProApi < (UINT32)GS_TICKPERIOD * 1000 ) /* The producer API is less than Timer */
{
eStatus = CD_UNSUPPORTED_BANDWIDTH;
goto Bailout;
} /* End if API */
/*
** Call the function to resend the data on an RPI basis directly.
** Quicker response than using a task, and less overhead. However
** it could overwhelm the system if to many low RPI connections
** exist
*/
pTr->xAPITimer = GS_NewTaskletPTimer( TIMER_CONTINUOUS,
( ( pTr->lProApi / 1000 ) - GS_TICKPERIOD ) * 2,
( pTr->lProApi / 1000 ) - GS_TICKPERIOD,
(FD_pFuncPType) en_cd_ProcessAPITxList,
pTr);
GS_StartTimer( pTr->xAPITimer );
} /* End if producer */
break;
case CM_TCT_CLASS_3:
break;
default:
/*
** Unsupported transport class.
*/
eStatus = CD_UNSUPPORTED_TRANSPORT;
goto Bailout;
} /* End of switch( pTr->iClass ) */
/*
** Transport configuration complete. This starts the transport.
*/
return ( SUCCESS );
Bailout:
/*
** Some sort of problem detected during setup.
** Free the buffers, the transport & toss the transport record.
** Don't forget to log a fault.
*/
GS_LogEvent( eStatus, pTr->iTransportId, pTr, WARNING );
en_cd_StopTransport( pTr );
return ( eStatus );
} /* End of en_cd_StartTransport( ) */
/*---------------------------------------------------------------------------
** en_cd_StopTransport( )
**---------------------------------------------------------------------------
*/
void en_cd_StopTransport( cd_TransportRecordType * pTr )
{
BOOL fEntryFound = FALSE;
/*
** Delete the screener / API TX list entries for this transport
*/
switch ( pTr->iClass )
{
case CM_TCT_CLASS_1:
if ( pTr->fServerConsumer ) /* Consumer */
{
} /* End if consumer */
else /* Producer */
{
/*
** Find the transport record in the SchTx List
*/
/*
** If this is a bridged connection do not do any API related functions.
*/
/*jjw 8/22/00*/
if ( !pTr->fBridged )
{
/*
** Non task mode does not have a tribble to delete
*/
if ( pTr->xAPITimer != NULL )
GS_DeleteTimer( pTr->xAPITimer );
}
} /* End if producer */
en_cd_FreeTransportBuffers(pTr);
break;
case CM_TCT_CLASS_3:
break;
} /* End of switch( pTr->iClass ) */
} /* End of en_cd_StopTransport( ) */
/*---------------------------------------------------------------------------
** en_cd_FreeTransportBuffers( )
**---------------------------------------------------------------------------
*/
StatusType en_cd_FreeTransportBuffers( cd_TransportRecordType * psTransportRecord )
{
/*
** If a API Tx buffer has been allocated for this transport, return it.
*/
if ( psTransportRecord->xSBufAccess != NULL )
{
GS_WaitSemaphore( psTransportRecord->xSBufAccess );
GS_DeleteSemaphore( psTransportRecord->xSBufAccess );
psTransportRecord->xSBufAccess = NULL;
}
if ( psTransportRecord->pBufA != NULL )
{
GS_Free( psTransportRecord->pBufA );
psTransportRecord->pBufA = NULL;
}
if (psTransportRecord->pBufB != NULL)
{
GS_Free(psTransportRecord->pBufB);
psTransportRecord->pBufB = NULL;
}
return ( SUCCESS );
} /* end of en_cd_FreeTransportBuffers( ) */
/*---------------------------------------------------------------------------
** en_cd_ProcessAPITxList( )
**---------------------------------------------------------------------------
*/
void en_cd_ProcessAPITxList( cd_TransportRecordType *pTransport )
{
UINT16 iNumBytesCopied;
if( ( pTransport->iBufState < A_CURRENT_B_FREE ) )
return;
/*
** Time to send this message, it has met or exceeded its API
*/
/*
** Get access to the buffer
*/
if( EN_CD_GetTransportBuffer( pTransport->iTransportId ) == NULL )
return; /* skip the rest of the processing */
if( pTransport->pTxCopyFunction )
{
/*
** Call producer copy function using a pointer
**
** Here we request that iDataSize bytes be copied.
** However, the actual number of bytes transfered is returned by
** the function. The returned value could be zero, indicating
** that no data is to be sent. In that case, continue with the next
** item on the list.
**
** Note that pTxBuffer->pData is a pointer to where to put the
** transport sequence count and pTxBuffer->pData + 2 is a pointer to where
** to put the data.
*/
iNumBytesCopied = ( pTransport->pTxCopyFunction )
( pTransport->xTxAppHandle, /* Parameter for copy function */
(LeUINT16*) pTransport->pBufA, /* Pointer to transport sequence count */
(UINT8*)(pTransport->pBufA + 2), /* Pointer to start of data */
pTransport->iDataSize ); /* Data length */
if ( iNumBytesCopied == 0xFFFF )
{
EN_CD_PutTransportBuffer( pTransport->iTransportId );
return; /* skip the rest of the processing */
}
/*
** Change endian of the transport sequence number
*/
*(UINT16*) pTransport->pBufA = ENCAP_VALUE_SHORT(*(UINT16*) pTransport->pBufA );
} /* end if copy function */
en_cd_Class1TxPacket( pTransport->pBufA, pTransport ); /* xmit data */
/*
** start edits: October,13th 2005, H.F.:
**
** update data after transmission
** (NOTE: An ad_ResyncCommAndAppBufs() call before executing
** en_cd_Class1TxPacket() does not work!)
*/
GS_PutMsgQueueBits( AD_xQid, AD_BIT_MSG_SENT_PRO );
/*
** end edits: October,13th 2005, H.F.
*/
} /* end of en_cd_ProcessAPITxList */
#endif /* CD_EN_OBJECTS */
/****************************************************************************
**
** End of EN_XPORT.C
**
*****************************************************************************
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -