| /** @file | |
| Windows version of the OOB Receive application | |
| Copyright (c) 2011-2012, Intel Corporation | |
| All rights reserved. This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include <OobRx.h> | |
| UINT8 mBuffer[65536]; | |
| /** | |
| Run the OOB receive application | |
| @param [in] ArgC Argument count | |
| @param [in] ArgV Argument value array | |
| @retval 0 Successfully operation | |
| **/ | |
| int | |
| OobRx ( | |
| IN int ArgC, | |
| IN char **ArgV | |
| ) | |
| { | |
| SOCKET a; | |
| ssize_t BytesReceived; | |
| struct sockaddr_in LocalPort; | |
| UINT32 OobInLine; | |
| UINT16 PortNumber; | |
| struct timeval ReceiveTimeout; | |
| struct sockaddr_in RemotePort; | |
| socklen_t RemotePortLength; | |
| int RetVal; | |
| SOCKET s; | |
| UINT32 TransmittedBefore; | |
| UINT32 TransmittedDuring; | |
| UINT32 TransmittedOob; | |
| UINT32 TransmittedAfter; | |
| UINT32 * pTransmittedBytes; | |
| // | |
| // Create the socket | |
| // | |
| s = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP ); | |
| if ( -1 == s ) { | |
| RetVal = GET_ERRNO; | |
| printf ( "ERROR - socket error, errno: %d\r\n", RetVal ); | |
| } | |
| else { | |
| // | |
| // Use for/break; instead of goto | |
| // | |
| for ( ; ; ) { | |
| // | |
| // Bind the socket to a known port | |
| // | |
| PortNumber = OOB_RX_PORT; | |
| memset ( &LocalPort, 0, sizeof ( LocalPort )); | |
| SIN_LEN ( LocalPort ) = sizeof ( LocalPort ); | |
| SIN_FAMILY ( LocalPort ) = AF_INET; | |
| SIN_ADDR ( LocalPort ) = 0; | |
| SIN_PORT ( LocalPort ) = htons ( PortNumber ); | |
| RetVal = bind ( s, | |
| (struct sockaddr *)&LocalPort, | |
| sizeof ( LocalPort )); | |
| if ( -1 == RetVal ) { | |
| RetVal = GET_ERRNO; | |
| printf ( "ERROR - bind error, errno: %d\r\n", RetVal ); | |
| break; | |
| } | |
| // | |
| // Make the port available on the server | |
| // | |
| RetVal = listen ( s, 2 ); | |
| if ( -1 == RetVal ) { | |
| RetVal = GET_ERRNO; | |
| printf ( "ERROR - listen error, errno: %d\r\n", RetVal ); | |
| break; | |
| } | |
| // | |
| // Wait for a connection to the known port | |
| // | |
| RemotePortLength = sizeof ( RemotePort ); | |
| a = accept ( s, | |
| (struct sockaddr *)&RemotePort, | |
| &RemotePortLength ); | |
| if ( -1 == a ) { | |
| RetVal = GET_ERRNO; | |
| printf ( "ERROR - accept error, errno: %d\r\n", RetVal ); | |
| break; | |
| } | |
| // | |
| // Use for/break instead of goto | |
| // | |
| for ( ; ; ) { | |
| // | |
| // Set the receive timeout | |
| // | |
| ReceiveTimeout.tv_sec = 0; | |
| ReceiveTimeout.tv_usec = 20 * 1000; | |
| RetVal = setsockopt ( a, | |
| SOL_SOCKET, | |
| SO_RCVTIMEO, | |
| (char *)&ReceiveTimeout, | |
| sizeof ( ReceiveTimeout )); | |
| if ( -1 == RetVal ) { | |
| RetVal = GET_ERRNO; | |
| printf ( "ERROR - setsockopt RCVTIMEO error, errno: %d\r\n", RetVal ); | |
| break; | |
| } | |
| // | |
| // Select the OOB processing | |
| // | |
| OobInLine = ( 1 < ArgC ); | |
| RetVal = setsockopt ( s, | |
| SOL_SOCKET, | |
| SO_OOBINLINE, | |
| (char *)&OobInLine, | |
| sizeof ( OobInLine )); | |
| if ( -1 == RetVal ) { | |
| RetVal = GET_ERRNO; | |
| printf ( "ERROR - setsockopt OOBINLINE error, errno: %d\r\n", RetVal ); | |
| break; | |
| } | |
| printf ( "%s\r\n", ( 0 != OobInLine ) ? "OOB messages are in-line" | |
| : "OOB messages move to the head of the queue" ); | |
| // | |
| // Receive data from the remote system | |
| // | |
| TransmittedBefore = 0; | |
| TransmittedOob = 0; | |
| TransmittedDuring = 0; | |
| TransmittedAfter = 0; | |
| pTransmittedBytes = &TransmittedBefore; | |
| do { | |
| // | |
| // Attempt to receive OOB data | |
| // | |
| BytesReceived = recv ( a, &mBuffer[0], sizeof ( mBuffer ), MSG_OOB ); | |
| RetVal = (UINT32)BytesReceived; | |
| if ( 0 < BytesReceived ) { | |
| // | |
| // Display the received OOB data | |
| // | |
| printf ( "%5Ld OOB bytes received\r\n", (UINT64)BytesReceived ); | |
| // | |
| // Account for the bytes received | |
| // | |
| TransmittedOob += RetVal; | |
| *pTransmittedBytes += TransmittedAfter; | |
| TransmittedAfter = 0; | |
| pTransmittedBytes = &TransmittedDuring; | |
| } | |
| else if ( -1 == BytesReceived ) { | |
| // | |
| // Check for connection timeout | |
| // | |
| RetVal = GET_ERRNO; | |
| if ( RX_TIMEOUT_ERROR != RetVal ) { | |
| // | |
| // Receive error | |
| // | |
| printf ( "ERROR - recv OOB error, errno: %d\r\n", RetVal ); | |
| break; | |
| } | |
| // | |
| // Ignore the timeout | |
| // Try to receive normal data instead | |
| // | |
| BytesReceived = recv ( a, &mBuffer[0], sizeof ( mBuffer ), 0 ); | |
| RetVal = (UINT32)BytesReceived; | |
| if ( 0 < BytesReceived ) { | |
| // | |
| // Display the received data | |
| // | |
| printf ( "%4Ld bytes received\r\n", (UINT64)BytesReceived ); | |
| // | |
| // Account for the bytes received | |
| // | |
| TransmittedAfter += RetVal; | |
| } | |
| else if ( -1 == BytesReceived ) { | |
| // | |
| // Check for a timeout | |
| // | |
| RetVal = GET_ERRNO; | |
| if ( RX_TIMEOUT_ERROR != RetVal ) { | |
| printf ( "ERROR - recv error, errno: %d\r\n", RetVal ); | |
| break; | |
| } | |
| } | |
| } | |
| } while ( 0 != RetVal ); | |
| // | |
| // Display the bytes received | |
| // | |
| if ( 0 == RetVal ) { | |
| printf ( "Bytes before OOB: %8d\r\n", TransmittedBefore ); | |
| if ( 0 != TransmittedDuring ) { | |
| printf ( "Bytes during OOB: %8d\r\n", TransmittedDuring ); | |
| } | |
| printf ( "Out-of-band bytes: %8d\r\n", TransmittedOob ); | |
| printf ( "Bytes after OOB: %8d\r\n", TransmittedAfter ); | |
| printf ( " --------\r\n" ); | |
| printf ( "Total Bytes: %8d\r\n", TransmittedBefore | |
| + TransmittedDuring | |
| + TransmittedOob | |
| + TransmittedAfter ); | |
| } | |
| // | |
| // Test complete | |
| // | |
| break; | |
| } | |
| // | |
| // Close the test socket | |
| // | |
| CLOSE_SOCKET ( a ); | |
| break; | |
| } | |
| // | |
| // Close the socket | |
| // | |
| CLOSE_SOCKET ( s ); | |
| printf ( "Socket closed\r\n" ); | |
| } | |
| // | |
| // Return the operation status | |
| // | |
| return RetVal; | |
| } |