Home | History | Annotate | Download | only in OobRx
      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