• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
OobRx(IN int ArgC,IN char ** ArgV)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