1 /** @file 2 Windows version of the OOB Receive application 3 4 Copyright (c) 2011-2012, Intel Corporation 5 All rights reserved. This program and the accompanying materials 6 are licensed and made available under the terms and conditions of the BSD License 7 which accompanies this distribution. The full text of the license may be found at 8 http://opensource.org/licenses/bsd-license.php 9 10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 13 **/ 14 15 #include <OobRx.h> 16 17 UINT8 mBuffer[65536]; 18 19 20 /** 21 Run the OOB receive application 22 23 @param [in] ArgC Argument count 24 @param [in] ArgV Argument value array 25 26 @retval 0 Successfully operation 27 **/ 28 int 29 OobRx ( 30 IN int ArgC, 31 IN char **ArgV 32 ) 33 { 34 SOCKET a; 35 ssize_t BytesReceived; 36 struct sockaddr_in LocalPort; 37 UINT32 OobInLine; 38 UINT16 PortNumber; 39 struct timeval ReceiveTimeout; 40 struct sockaddr_in RemotePort; 41 socklen_t RemotePortLength; 42 int RetVal; 43 SOCKET s; 44 UINT32 TransmittedBefore; 45 UINT32 TransmittedDuring; 46 UINT32 TransmittedOob; 47 UINT32 TransmittedAfter; 48 UINT32 * pTransmittedBytes; 49 50 // 51 // Create the socket 52 // 53 s = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP ); 54 if ( -1 == s ) { 55 RetVal = GET_ERRNO; 56 printf ( "ERROR - socket error, errno: %d\r\n", RetVal ); 57 } 58 else { 59 // 60 // Use for/break; instead of goto 61 // 62 for ( ; ; ) { 63 // 64 // Bind the socket to a known port 65 // 66 PortNumber = OOB_RX_PORT; 67 memset ( &LocalPort, 0, sizeof ( LocalPort )); 68 SIN_LEN ( LocalPort ) = sizeof ( LocalPort ); 69 SIN_FAMILY ( LocalPort ) = AF_INET; 70 SIN_ADDR ( LocalPort ) = 0; 71 SIN_PORT ( LocalPort ) = htons ( PortNumber ); 72 RetVal = bind ( s, 73 (struct sockaddr *)&LocalPort, 74 sizeof ( LocalPort )); 75 if ( -1 == RetVal ) { 76 RetVal = GET_ERRNO; 77 printf ( "ERROR - bind error, errno: %d\r\n", RetVal ); 78 break; 79 } 80 81 // 82 // Make the port available on the server 83 // 84 RetVal = listen ( s, 2 ); 85 if ( -1 == RetVal ) { 86 RetVal = GET_ERRNO; 87 printf ( "ERROR - listen error, errno: %d\r\n", RetVal ); 88 break; 89 } 90 91 // 92 // Wait for a connection to the known port 93 // 94 RemotePortLength = sizeof ( RemotePort ); 95 a = accept ( s, 96 (struct sockaddr *)&RemotePort, 97 &RemotePortLength ); 98 if ( -1 == a ) { 99 RetVal = GET_ERRNO; 100 printf ( "ERROR - accept error, errno: %d\r\n", RetVal ); 101 break; 102 } 103 104 // 105 // Use for/break instead of goto 106 // 107 for ( ; ; ) { 108 // 109 // Set the receive timeout 110 // 111 ReceiveTimeout.tv_sec = 0; 112 ReceiveTimeout.tv_usec = 20 * 1000; 113 RetVal = setsockopt ( a, 114 SOL_SOCKET, 115 SO_RCVTIMEO, 116 (char *)&ReceiveTimeout, 117 sizeof ( ReceiveTimeout )); 118 if ( -1 == RetVal ) { 119 RetVal = GET_ERRNO; 120 printf ( "ERROR - setsockopt RCVTIMEO error, errno: %d\r\n", RetVal ); 121 break; 122 } 123 124 // 125 // Select the OOB processing 126 // 127 OobInLine = ( 1 < ArgC ); 128 RetVal = setsockopt ( s, 129 SOL_SOCKET, 130 SO_OOBINLINE, 131 (char *)&OobInLine, 132 sizeof ( OobInLine )); 133 if ( -1 == RetVal ) { 134 RetVal = GET_ERRNO; 135 printf ( "ERROR - setsockopt OOBINLINE error, errno: %d\r\n", RetVal ); 136 break; 137 } 138 printf ( "%s\r\n", ( 0 != OobInLine ) ? "OOB messages are in-line" 139 : "OOB messages move to the head of the queue" ); 140 141 // 142 // Receive data from the remote system 143 // 144 TransmittedBefore = 0; 145 TransmittedOob = 0; 146 TransmittedDuring = 0; 147 TransmittedAfter = 0; 148 pTransmittedBytes = &TransmittedBefore; 149 do { 150 // 151 // Attempt to receive OOB data 152 // 153 BytesReceived = recv ( a, &mBuffer[0], sizeof ( mBuffer ), MSG_OOB ); 154 RetVal = (UINT32)BytesReceived; 155 if ( 0 < BytesReceived ) { 156 // 157 // Display the received OOB data 158 // 159 printf ( "%5Ld OOB bytes received\r\n", (UINT64)BytesReceived ); 160 161 // 162 // Account for the bytes received 163 // 164 TransmittedOob += RetVal; 165 *pTransmittedBytes += TransmittedAfter; 166 TransmittedAfter = 0; 167 pTransmittedBytes = &TransmittedDuring; 168 } 169 else if ( -1 == BytesReceived ) { 170 // 171 // Check for connection timeout 172 // 173 RetVal = GET_ERRNO; 174 if ( RX_TIMEOUT_ERROR != RetVal ) { 175 // 176 // Receive error 177 // 178 printf ( "ERROR - recv OOB error, errno: %d\r\n", RetVal ); 179 break; 180 } 181 182 // 183 // Ignore the timeout 184 // Try to receive normal data instead 185 // 186 BytesReceived = recv ( a, &mBuffer[0], sizeof ( mBuffer ), 0 ); 187 RetVal = (UINT32)BytesReceived; 188 if ( 0 < BytesReceived ) { 189 // 190 // Display the received data 191 // 192 printf ( "%4Ld bytes received\r\n", (UINT64)BytesReceived ); 193 194 // 195 // Account for the bytes received 196 // 197 TransmittedAfter += RetVal; 198 } 199 else if ( -1 == BytesReceived ) { 200 // 201 // Check for a timeout 202 // 203 RetVal = GET_ERRNO; 204 if ( RX_TIMEOUT_ERROR != RetVal ) { 205 printf ( "ERROR - recv error, errno: %d\r\n", RetVal ); 206 break; 207 } 208 } 209 } 210 } while ( 0 != RetVal ); 211 212 // 213 // Display the bytes received 214 // 215 if ( 0 == RetVal ) { 216 printf ( "Bytes before OOB: %8d\r\n", TransmittedBefore ); 217 if ( 0 != TransmittedDuring ) { 218 printf ( "Bytes during OOB: %8d\r\n", TransmittedDuring ); 219 } 220 printf ( "Out-of-band bytes: %8d\r\n", TransmittedOob ); 221 printf ( "Bytes after OOB: %8d\r\n", TransmittedAfter ); 222 printf ( " --------\r\n" ); 223 printf ( "Total Bytes: %8d\r\n", TransmittedBefore 224 + TransmittedDuring 225 + TransmittedOob 226 + TransmittedAfter ); 227 } 228 229 // 230 // Test complete 231 // 232 break; 233 } 234 235 // 236 // Close the test socket 237 // 238 CLOSE_SOCKET ( a ); 239 break; 240 } 241 242 // 243 // Close the socket 244 // 245 CLOSE_SOCKET ( s ); 246 printf ( "Socket closed\r\n" ); 247 } 248 249 // 250 // Return the operation status 251 // 252 return RetVal; 253 } 254