1 /** @file
2 Windows version of the OOB Transmit 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 <OobTx.h>
16
17 UINT8 mBuffer[8192];
18 UINT8 mOob[512];
19
20 /**
21 Transmit out-of-band messages to the remote system.
22
23 @param [in] ArgC Argument count
24 @param [in] ArgV Argument value array
25
26 @retval 0 Successfully operation
27 **/
28
29 int
OobTx(IN int ArgC,IN char ** ArgV)30 OobTx (
31 IN int ArgC,
32 IN char **ArgV
33 )
34 {
35 UINT32 BytesSent;
36 ssize_t BytesTransmitted;
37 UINT32 Index;
38 struct sockaddr_in LocalPort;
39 UINT32 OobInLine;
40 UINT16 PortNumber;
41 UINT32 RemoteAddress[4];
42 struct sockaddr_in RemotePort;
43 int RetVal;
44 UINT32 TransmittedAfter;
45 UINT32 TransmittedBefore;
46 UINT32 TransmittedOob;
47 SOCKET s;
48
49 //
50 // Create the socket
51 //
52 s = socket ( AF_INET, SOCK_STREAM, IPPROTO_TCP );
53 if ( -1 == s ) {
54 RetVal = GET_ERRNO;
55 printf ( "ERROR - socket error, errno: %d\r\n", RetVal );
56 }
57 else {
58 //
59 // Use for/break; instead of goto
60 //
61 for ( ; ; ) {
62 //
63 // Validate the arguments
64 //
65 if (( 2 > ArgC )
66 || ( 4 != sscanf ( ArgV[1],
67 "%d.%d.%d.%d",
68 &RemoteAddress[0],
69 &RemoteAddress[1],
70 &RemoteAddress[2],
71 &RemoteAddress[3]))
72 || ( 224 < RemoteAddress[0])
73 || ( 255 < RemoteAddress[1])
74 || ( 255 < RemoteAddress[2])
75 || ( 255 < RemoteAddress[3])
76 || (( 0 == RemoteAddress[0])
77 && ( 0 == RemoteAddress[1])
78 && ( 0 == RemoteAddress[2])
79 && ( 0 == RemoteAddress[3]))) {
80 printf ( "%s <remote IP address> [optional: enables in-line OOB]\r\n", ArgV[0]);
81 RetVal = EINVAL;
82 break;
83 }
84
85 //
86 // Bind the socket to a local port
87 //
88 memset ( &LocalPort, 0, sizeof ( LocalPort ));
89 SIN_LEN ( LocalPort ) = sizeof ( LocalPort );
90 SIN_FAMILY ( LocalPort ) = AF_INET;
91 SIN_ADDR ( LocalPort ) = 0;
92 SIN_PORT ( LocalPort ) = 0;
93 RetVal = bind ( s,
94 (struct sockaddr *)&LocalPort,
95 sizeof ( LocalPort ));
96 if ( -1 == RetVal ) {
97 RetVal = GET_ERRNO;
98 printf ( "ERROR - bind error, errno: %d\r\n", RetVal );
99 break;
100 }
101
102 //
103 // Specify the remote port
104 //
105 PortNumber = OOB_RX_PORT;
106 memset ( &RemotePort, 0, sizeof ( RemotePort ));
107 SIN_LEN ( RemotePort ) = sizeof ( RemotePort );
108 SIN_FAMILY ( RemotePort ) = AF_INET;
109 SIN_ADDR ( RemotePort ) = ( RemoteAddress[3] << 24 )
110 | ( RemoteAddress[2] << 16 )
111 | ( RemoteAddress[1] << 8 )
112 | RemoteAddress[0];
113 SIN_PORT ( RemotePort ) = htons ( PortNumber );
114
115 //
116 // Connect to the remote server
117 //
118 RetVal = connect ( s, (struct sockaddr *)&RemotePort, sizeof ( RemotePort ));
119 if ( -1 == RetVal ) {
120 RetVal = GET_ERRNO;
121 printf ( "ERROR - connect error, errno: %d\r\n", RetVal );
122 break;
123 }
124
125 //
126 // Select the OOB processing
127 //
128 OobInLine = ( 2 < ArgC );
129 RetVal = setsockopt ( s,
130 SOL_SOCKET,
131 SO_OOBINLINE,
132 (char *)&OobInLine,
133 sizeof ( OobInLine ));
134 if ( -1 == RetVal ) {
135 RetVal = GET_ERRNO;
136 printf ( "ERROR - setsockopt OOBINLINE error, errno: %d\r\n", RetVal );
137 break;
138 }
139 printf ( "%s\r\n", ( 0 != OobInLine ) ? "OOB messages are in-line"
140 : "OOB messages move to the head of the queue" );
141
142 //
143 // Initialize the messages
144 //
145 memset ( &mBuffer[0], 0, sizeof ( mBuffer ));
146 memset ( &mOob[0], 0x11, sizeof ( mOob ));
147
148 //
149 // Send the data before the out-of-band message
150 //
151 TransmittedBefore = 0;
152 for ( Index = 0; TX_MSGS_BEFORE > Index; Index++ ) {
153 BytesSent = 0;
154 do {
155 BytesTransmitted = send ( s,
156 &mBuffer[BytesSent],
157 sizeof ( mBuffer ) - BytesSent,
158 0 );
159 if ( -1 == BytesTransmitted ) {
160 RetVal = GET_ERRNO;
161 printf ( "ERROR - send before error, errno: %d\r\n", RetVal );
162 break;
163 }
164 BytesSent += (UINT32)BytesTransmitted;
165 RetVal = 0;
166 } while ( sizeof ( mBuffer ) > BytesSent );
167 if ( 0 != RetVal ) {
168 break;
169 }
170 TransmittedBefore += BytesSent;
171 }
172 if ( 0 != RetVal ) {
173 break;
174 }
175
176 //
177 // Send the out-of-band message
178 //
179 BytesSent = 0;
180 do {
181 BytesTransmitted = send ( s,
182 &mOob[BytesSent],
183 sizeof ( mOob ) - BytesSent,
184 MSG_OOB );
185 if ( -1 == BytesTransmitted ) {
186 RetVal = GET_ERRNO;
187 printf ( "ERROR - send OOB error, errno: %d\r\n", RetVal );
188 break;
189 }
190 BytesSent += (UINT32)BytesTransmitted;
191 RetVal = 0;
192 } while ( sizeof ( mOob ) > BytesSent );
193 if ( 0 != RetVal ) {
194 break;
195 }
196 TransmittedOob = BytesSent;
197
198 //
199 // Send the data after the out-of-band message
200 //
201 TransmittedAfter = 0;
202 for ( Index = 0; TX_MSGS_AFTER > Index; Index++ ) {
203 BytesSent = 0;
204 do {
205 BytesTransmitted = send ( s,
206 &mBuffer[BytesSent],
207 sizeof ( mBuffer ) - BytesSent,
208 0 );
209 if ( -1 == BytesTransmitted ) {
210 RetVal = GET_ERRNO;
211 printf ( "ERROR - send after error, errno: %d\r\n", RetVal );
212 break;
213 }
214 BytesSent += (UINT32)BytesTransmitted;
215 RetVal = 0;
216 } while ( sizeof ( mBuffer ) > BytesSent );
217 if ( 0 != RetVal ) {
218 break;
219 }
220 TransmittedAfter += BytesSent;
221 }
222
223 //
224 // Test completed successfully
225 //
226 if ( 0 == RetVal ) {
227 printf ( "Bytes before OOB: %8d\r\n", TransmittedBefore );
228 printf ( "Out-of-band bytes: %8d\r\n", TransmittedOob );
229 printf ( "Bytes after OOB: %8d\r\n", TransmittedAfter );
230 printf ( " --------\r\n" );
231 printf ( "Total Bytes: %8d\r\n", TransmittedBefore
232 + TransmittedOob
233 + TransmittedAfter );
234 }
235 break;
236 }
237
238 //
239 // Close the socket
240 //
241 CLOSE_SOCKET ( s );
242 }
243
244 //
245 // Return the operation status
246 //
247 return RetVal;
248 }
249