📄 en_sock.c
字号:
GS_DeleteTask( 0 );
}
for ( iConnIndex = 0;
iConnIndex < ( sizeof( sMulticastTbl ) / sizeof( sMulticastTbl[ 0 ] ) );
iConnIndex++ )
{
sMulticastTbl[ iConnIndex ].iSocket = lSockFd;
} /* End for connections in sMulticastTbl */
#endif
/*
** Assign an inbound connection id. Form the handle, idx is socket #
** Add in the lTotal number of connections
*/
sClass1Ece.sEid.u.type = ECE_TYPE_INBOUND;
sClass1Ece.lState = ECE_STATE_CONNECTED;
sClass1Ece.sEid.u.idx = lSockFd;
sClass1Ece.sEid.u.seq = lTotal_lECE_connects;
#ifndef _WIN32
sClass1Ece.sAddr.sin_len = sizeof( struct sockaddr_in );
#endif
/*
** Mark as UDP connection. lSockFd used primarily by the Start Class 1
** function to enable multicast reception
*/
sClass1Ece.lFlags = ECE_FLAG_NOSESSION;
sClass1Ece.lSockFd = lSockFd;
psPacketBuf = PktBufAlloc( ); /* Allocate message dynamically */
if ( psPacketBuf == NULL )
{
GS_LogEvent( EN_RESOURCE,
0,
0,
FATAL );
}
while ( 1 )
{
#if defined( WIN32 )
nt_Suspend( );
#endif
lBytesReceived = recvfrom(lSockFd,
( char * ) psPacketBuf->abData,
PKTBUF_MAX_DATA,
0,
( struct sockaddr * ) & sClientAddr,
&lSockAddrSize );
#if defined( WIN32 )
nt_Resume( );
#endif
psPacketBuf->pData = &psPacketBuf->abData;
psMsg = ( CPFHDR * ) psPacketBuf->pData;
if (( lBytesReceived == 0 ) || ( lBytesReceived == OE_ERROR ))
{
continue;
}
psPacketBuf->sEce.sAddr = sClientAddr;
psMsg->iAs_type = ENCAP_TO_HS( psMsg->iAs_type );
psMsg->iAs_length = ENCAP_TO_HS( psMsg->iAs_length );
psPacketBuf->lLength = lBytesReceived;
/*
** Parse the encapsulated Class1 packet
*/
en_cd_ParseClass1Packet( psPacketBuf );
} /* End forever */
} /* en_cd_Class1RecvTask */
/*---------------------------------------------------------------------------
** en_cd_UDPRecvTask( )
**---------------------------------------------------------------------------
*/
TASKRETURN en_cd_UDPRecvTask( TASKPARAM )
{
UINT32 lBytesReceived;
struct sockaddr_in sClientAddr;
ENCAPH *psEncapHdr;
PKTBUF *psPacketBuf;
UINT32 lSockAddrSize;
UINT32 lSockFd;
UINT32 lSendTaskId;
GS_TaskSeedType sSeed;
OE_Q_ID sSendTaskMsgQueue;
UINT32 nSendTaskPriority;
struct sockaddr_in sSrvrAddr;
lSockAddrSize = sizeof( struct sockaddr_in );
UC_SetMem( ( char * ) &sSrvrAddr, 0, sizeof( sSrvrAddr ) );
#ifndef _WIN32
sSrvrAddr.sin_len = ( UINT8 ) lSockAddrSize;
#endif
sSrvrAddr.sin_family = AF_INET;
sSrvrAddr.sin_addr.s_addr = htonl( INADDR_ANY );
sSrvrAddr.sin_port = htons( lEncapServerPort );
if ( ( lSockFd = socket( AF_INET, SOCK_DGRAM, 0 ) ) == OE_ERROR )
{
/*
** Need a socket to do anything, so fatal out
*/
GS_LogEvent( EN_SOCKET_ERR,
OE_SOCKET_ERRNO,
0,
FATAL );
GS_DeleteTask( 0 );
}
/*
** Bind the server to PORT, which the client knows
*/
if ( bind( lSockFd, ( struct sockaddr * ) & sSrvrAddr, sizeof( sSrvrAddr ) ) == OE_ERROR )
{
/*
** If we can't bind, no one can conect, fatal out
*/
GS_LogEvent( EN_BIND_ERR,
OE_SOCKET_ERRNO,
0,
FATAL );
GS_DeleteTask( 0 );
}
/*
** Assign an inbound connection id. Form the handle, idx is socket #
** Add in the lTotal number of connections
*/
UC_SetMem( &sUDPEce, 0, sizeof sUDPEce );
sUDPEce.sEid.u.type = ECE_TYPE_INBOUND;
sUDPEce.lState = ECE_STATE_CONNECTED;
sUDPEce.sEid.u.idx = lSockFd;
sUDPEce.sEid.u.seq = lTotal_lECE_connects;
#ifndef _WIN32
sUDPEce.sAddr.sin_len = sizeof( struct sockaddr_in );
#endif
sUDPEce.lFlags = ECE_FLAG_NOSESSION; /* Mark as UDP connection */
sUDPEce.lSockFd = lSockFd;
/*
** We need to create the message queue so we can pass it to
** the send task
*/
sSendTaskMsgQueue = OE_MsgQCreate( 100, /* Number of messages, */
sizeof( EnCdMessageType ),
MSG_Q_PRIORITY );
/*
** This is FATAL we are in the beginning of the ball game and we are already
** having problems creating message queues. Further, this is a critical
** queue
**/
GS_LogEventIf( ( sSendTaskMsgQueue == 0 ),
EN_QUEUE_CR_ERR,
OE_SOCKET_ERRNO,
0,
FATAL );
sUDPEce.sOutputQ = sSendTaskMsgQueue;
nSendTaskPriority = UDP_SEND_TASK_PRIO;
sSeed.pRoutine = ( OE_pTaskFuncType ) en_cd_UDPEncapSendTask;
sSeed.pParameter = NULL;
sSeed.pStack = NULL;
sSeed.iStackSize = EN_SOCKET_STACK_SIZE;
sSeed.nPrio = nSendTaskPriority;
sSeed.pTaskName = "ISUDP";
lSendTaskId = GS_NewTask( &sSeed );
/*
** This is FATAL we are in the beginning of the ball game and we are already
** having problems creating tasks. And the DP send task is critical to the
** operation.
*/
GS_LogEventIf( ( lSendTaskId == 0 ),
EN_TASK_SP_ERR,
OE_SOCKET_ERRNO,
0,
FATAL );
sUDPEce.lSendTaskID = lSendTaskId;
while ( 1 )
{
psPacketBuf = PktBufAlloc( ); /* Allocate message dynamically */
if ( psPacketBuf == NULL )
{
GS_LogEvent( EN_RESOURCE,
0,
0,
WARNING );
OE_TaskDelay( MSEC2TICKS(1000) ); /* Delay for a second, maybe memory will
* be freed up */
continue; /* Back to the beginning of the while
* loop */
}
psEncapHdr = &psPacketBuf->sEncap.sHdr;
psPacketBuf->sOutputQ = sSendTaskMsgQueue;
#if defined( WIN32 )
nt_Suspend( );
#endif
lBytesReceived = recvfrom( lSockFd,
( char * ) psEncapHdr,
PKTBUF_MAX_DATA,
0,
( struct sockaddr * ) & sClientAddr,
&lSockAddrSize );
#if defined( WIN32 )
nt_Resume( );
#endif
/*
** Probably trouble. Getting off the recv call told old us the socket was
** ready to read, but actually read gives us 0 bytes. Probably shut down
** at the other end. We will shut down here too.
*/
if (( lBytesReceived == 0 ) || ( lBytesReceived == OE_ERROR ))
{
PktBufFree( psPacketBuf ); /* Free the buffer */
continue;
}
psPacketBuf->sEce.sAddr = sClientAddr;
/*
** Swap the byte ordering
*/
psEncapHdr->iEncaph_length = ENCAP_VALUE_SHORT( psEncapHdr->iEncaph_length );
psEncapHdr->iEncaph_command = ENCAP_VALUE_SHORT( psEncapHdr->iEncaph_command );
/*
** Parse the encap command
*/
en_cd_ProcessEncapMsg( &sUDPEce, psPacketBuf );
} /* End forever */
} /* en_cd_UDPRecvTask */
/*---------------------------------------------------------------------------
** en_cd_PostListen( )
**---------------------------------------------------------------------------
*/
UINT32 en_cd_PostListen( void )
{
UINT32 lFlagTrue = ~0;
INT32 lSize_buf;
UINT32 lSockFd, status;
struct sockaddr_in sSrv_addr;
if ( ( lSockFd = socket( PF_INET, SOCK_STREAM, 0 ) ) == OE_ERROR )
{
/*
** Socket error. Without a socket we cannot do anything
*/
GS_LogEvent( EN_SOCKET_ERR, OE_SOCKET_ERRNO,
0,
FATAL );
GS_DeleteTask( 0 );
}
UC_SetMem( ( char * ) &sSrv_addr, 0, sizeof( sSrv_addr ) );
sSrv_addr.sin_family = AF_INET;
sSrv_addr.sin_addr.s_addr = htonl( INADDR_ANY );
sSrv_addr.sin_port = htons( lEncapServerPort );
/*
** Bind the server to TCP_PORT, which the client knows
*/
status = setsockopt( lSockFd, SOL_SOCKET, SO_REUSEADDR, ( char * ) &lFlagTrue,
sizeof( lFlagTrue ) );
if ( status == OE_ERROR )
{
/*
** While some of the options are non-critical, having them fail this
** early in the game should be a cause for general alarm
*/
GS_LogEvent( EN_SOCKET_OPT,
OE_SOCKET_ERRNO,
0,
FATAL );
}
status = setsockopt( lSockFd, SOL_SOCKET, SO_KEEPALIVE, ( char * ) &lFlagTrue,
sizeof( lFlagTrue ) );
if ( status == OE_ERROR )
{
GS_LogEvent( EN_SOCKET_OPT,
OE_SOCKET_ERRNO,
0,
FATAL );
}
/*
** Get a size buffer at least large enough for a full packet, and also
** keep it a power of 2. Keep it at least 4k in size
*/
lSize_buf = TCP_RCV_BUF_SIZE;
while ( lSize_buf < PKTBUF_MAX_DATA )
{
lSize_buf <<= 1;
}
status = setsockopt( lSockFd, SOL_SOCKET, SO_SNDBUF, ( char * ) &lSize_buf,
sizeof( lSize_buf ) );
if ( status == OE_ERROR )
{
/*
** While some of the options are non-critical, having them fail this
** early in the game should be a cause for general alarm
*/
GS_LogEvent( EN_SOCKET_OPT, OE_SOCKET_ERRNO,
0,
FATAL );
}
status = setsockopt( lSockFd,
SOL_SOCKET,
SO_RCVBUF,
( char * ) &lSize_buf,
sizeof( lSize_buf ) );
if ( status == OE_ERROR )
{
/*
** While some of the options are non-critical, having them fail this
** early in the game should be a cause for general alarm
*/
GS_LogEvent( EN_SOCKET_OPT,
OE_SOCKET_ERRNO,
0,
FATAL );
}
if ( bind( lSockFd, ( struct sockaddr * ) & sSrv_addr, sizeof( sSrv_addr ) ) == OE_ERROR )
{
/*
** If we can't bind, no one can conect, fatal out
*/
GS_LogEvent( EN_BIND_ERR,
OE_SOCKET_ERRNO,
0,
FATAL );
GS_DeleteTask( 0 );
}
if ( listen( lSockFd, 5 ) == OE_ERROR )
{
/*
** If we can't bind, no one can conect, fatal out
*/
GS_LogEvent( EN_LISTEN_ERR,
OE_SOCKET_ERRNO,
0,
FATAL );
GS_DeleteTask( 0 );
}
return ( lSockFd );
} /* end en_cd_PostListen( ) */
/*---------------------------------------------------------------------------
** en_cd_PassiveWaitTask( )
**---------------------------------------------------------------------------
*/
TASKRETURN en_cd_PassiveWaitTask( TASKPARAM )
{
UINT8 achTaskName[32];
struct sockaddr_in sCli_addr;
ECE *psEce;
INT32 lSockFd, lSockFd2, lAddrLen;
GS_TaskSeedType sSeed;
OE_Q_ID sSendTaskMsgQueue;
INT32 nStatus;
UINT32 lTaskID;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -