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