Browse Source

Update ftp.c and hello.c to use the generic async_operations API.

tags/v0.9.3
Michael Brown 18 years ago
parent
commit
3a660f9b25
6 changed files with 112 additions and 26 deletions
  1. 8
    8
      src/include/gpxe/ftp.h
  2. 4
    3
      src/include/gpxe/hello.h
  3. 9
    7
      src/net/tcp/ftp.c
  4. 9
    8
      src/net/tcp/hello.c
  5. 41
    0
      src/tests/ftptest.c
  6. 41
    0
      src/tests/hellotest.c

+ 8
- 8
src/include/gpxe/ftp.h View File

8
  */
8
  */
9
 
9
 
10
 #include <stdint.h>
10
 #include <stdint.h>
11
+#include <gpxe/async.h>
11
 #include <gpxe/tcp.h>
12
 #include <gpxe/tcp.h>
12
 
13
 
14
+/** FTP default port */
15
+#define FTP_PORT 21
16
+
13
 /**
17
 /**
14
  * FTP states
18
  * FTP states
15
  *
19
  *
45
 	 * remote server.
49
 	 * remote server.
46
 	 */
50
 	 */
47
 	void ( *callback ) ( char *data, size_t len );
51
 	void ( *callback ) ( char *data, size_t len );
48
-	/** Completion indicator
49
-	 *
50
-	 * This will be set to a non-zero value when the transfer is
51
-	 * complete.  A negative value indicates an error.
52
-	 */
53
-	int complete;
52
+	/** Asynchronous operation for this FTP operation */
53
+	struct async_operation aop;
54
 
54
 
55
 	/** Current state */
55
 	/** Current state */
56
 	enum ftp_state state;
56
 	enum ftp_state state;
69
 	struct tcp_connection tcp_data;
69
 	struct tcp_connection tcp_data;
70
 };
70
 };
71
 
71
 
72
-extern void ftp_connect ( struct ftp_request *ftp );
72
+struct async_operation * ftp_get ( struct ftp_request *ftp );
73
 
73
 
74
-#endif
74
+#endif /* _GPXE_FTP_H */

+ 4
- 3
src/include/gpxe/hello.h View File

9
 
9
 
10
 #include <stdint.h>
10
 #include <stdint.h>
11
 #include <gpxe/tcp.h>
11
 #include <gpxe/tcp.h>
12
+#include <gpxe/async.h>
12
 
13
 
13
 enum hello_state {
14
 enum hello_state {
14
 	HELLO_SENDING_MESSAGE = 1,
15
 	HELLO_SENDING_MESSAGE = 1,
37
 	 * remote server.
38
 	 * remote server.
38
 	 */
39
 	 */
39
 	void ( *callback ) ( char *data, size_t len );
40
 	void ( *callback ) ( char *data, size_t len );
40
-	/** Connection complete indicator */
41
-	int complete;
41
+	/** Asynchronous operation */
42
+	struct async_operation aop;
42
 };
43
 };
43
 
44
 
44
-extern void hello_connect ( struct hello_request *hello );
45
+extern struct async_operation * say_hello ( struct hello_request *hello );
45
 
46
 
46
 #endif
47
 #endif

+ 9
- 7
src/net/tcp/ftp.c View File

4
 #include <vsprintf.h>
4
 #include <vsprintf.h>
5
 #include <assert.h>
5
 #include <assert.h>
6
 #include <errno.h>
6
 #include <errno.h>
7
+#include <gpxe/async.h>
7
 #include <gpxe/ftp.h>
8
 #include <gpxe/ftp.h>
8
 
9
 
9
 /** @file
10
 /** @file
70
  * Mark FTP request as complete
71
  * Mark FTP request as complete
71
  *
72
  *
72
  * @v ftp		FTP request
73
  * @v ftp		FTP request
73
- * @v complete		Completion indicator
74
+ * @v rc		Return status code
74
  *
75
  *
75
  */
76
  */
76
-static void ftp_complete ( struct ftp_request *ftp, int complete ) {
77
-	ftp->complete = complete;
77
+static void ftp_done ( struct ftp_request *ftp, int rc ) {
78
 	tcp_close ( &ftp->tcp_data );
78
 	tcp_close ( &ftp->tcp_data );
79
 	tcp_close ( &ftp->tcp );
79
 	tcp_close ( &ftp->tcp );
80
+	async_done ( &ftp->aop, rc );
80
 }
81
 }
81
 
82
 
82
 /**
83
 /**
145
 
146
 
146
  err:
147
  err:
147
 	/* Flag protocol error and close connections */
148
 	/* Flag protocol error and close connections */
148
-	ftp_complete ( ftp, -EPROTO );
149
+	ftp_done ( ftp, -EPROTO );
149
 }
150
 }
150
 
151
 
151
 /**
152
 /**
248
 static void ftp_closed ( struct tcp_connection *conn, int status ) {
249
 static void ftp_closed ( struct tcp_connection *conn, int status ) {
249
 	struct ftp_request *ftp = tcp_to_ftp ( conn );
250
 	struct ftp_request *ftp = tcp_to_ftp ( conn );
250
 
251
 
251
-	ftp_complete ( ftp, status ? status : 1 );
252
+	ftp_done ( ftp, status );
252
 }
253
 }
253
 
254
 
254
 /** FTP control channel operations */
255
 /** FTP control channel operations */
291
 	struct ftp_request *ftp = tcp_to_ftp_data ( conn );
292
 	struct ftp_request *ftp = tcp_to_ftp_data ( conn );
292
 
293
 
293
 	if ( status )
294
 	if ( status )
294
-		ftp_complete ( ftp, status );
295
+		ftp_done ( ftp, status );
295
 }
296
 }
296
 
297
 
297
 /**
298
 /**
327
  *
328
  *
328
  * @v ftp	FTP request
329
  * @v ftp	FTP request
329
  */
330
  */
330
-void ftp_connect ( struct ftp_request *ftp ) {
331
+struct async_operation * ftp_get ( struct ftp_request *ftp ) {
331
 	ftp->tcp.tcp_op = &ftp_tcp_operations;
332
 	ftp->tcp.tcp_op = &ftp_tcp_operations;
332
 	ftp->tcp_data.tcp_op = &ftp_data_tcp_operations;
333
 	ftp->tcp_data.tcp_op = &ftp_data_tcp_operations;
333
 	ftp->recvbuf = ftp->status_text;
334
 	ftp->recvbuf = ftp->status_text;
334
 	ftp->recvsize = sizeof ( ftp->status_text ) - 1;
335
 	ftp->recvsize = sizeof ( ftp->status_text ) - 1;
335
 	tcp_connect ( &ftp->tcp );
336
 	tcp_connect ( &ftp->tcp );
337
+	return &ftp->aop;
336
 }
338
 }

+ 9
- 8
src/net/tcp/hello.c View File

2
 #include <string.h>
2
 #include <string.h>
3
 #include <vsprintf.h>
3
 #include <vsprintf.h>
4
 #include <assert.h>
4
 #include <assert.h>
5
+#include <gpxe/async.h>
5
 #include <gpxe/hello.h>
6
 #include <gpxe/hello.h>
6
 
7
 
7
 /** @file
8
 /** @file
13
  * message (hello_request::message).  Any data received from the
14
  * message (hello_request::message).  Any data received from the
14
  * server will be passed to the callback function,
15
  * server will be passed to the callback function,
15
  * hello_request::callback(), and once the connection has been closed,
16
  * hello_request::callback(), and once the connection has been closed,
16
- * hello_request::complete will be set to a non-zero value.
17
+ * the asynchronous operation associated with the request will be
18
+ * marked as complete.
17
  *
19
  *
18
  * To use this code, do something like:
20
  * To use this code, do something like:
19
  *
21
  *
31
  *   hello.sin.sin_addr.s_addr = ... server IP address ...
33
  *   hello.sin.sin_addr.s_addr = ... server IP address ...
32
  *   hello.sin.sin_port = ... server port ...
34
  *   hello.sin.sin_port = ... server port ...
33
  *
35
  *
34
- *   hello_connect ( &hello );
35
- *   while ( ! hello.completed ) {
36
- *     run_tcpip();
37
- *   }
36
+ *   rc = async_wait ( say_hello ( &hello ) );
38
  *
37
  *
39
  * @endcode
38
  * @endcode
40
  *
39
  *
52
 static void hello_closed ( struct tcp_connection *conn, int status ) {
51
 static void hello_closed ( struct tcp_connection *conn, int status ) {
53
 	struct hello_request *hello = tcp_to_hello ( conn );
52
 	struct hello_request *hello = tcp_to_hello ( conn );
54
 
53
 
55
-	hello->complete = ( status ? status : 1 );
54
+	async_done ( &hello->aop, status );
56
 }
55
 }
57
 
56
 
58
 static void hello_connected ( struct tcp_connection *conn ) {
57
 static void hello_connected ( struct tcp_connection *conn ) {
92
 	hello->callback ( data, len );
91
 	hello->callback ( data, len );
93
 }
92
 }
94
 
93
 
95
-static void hello_senddata ( struct tcp_connection *conn ) {
94
+static void hello_senddata ( struct tcp_connection *conn,
95
+			     void *buf __unused, size_t len __unused ) {
96
 	struct hello_request *hello = tcp_to_hello ( conn );
96
 	struct hello_request *hello = tcp_to_hello ( conn );
97
 
97
 
98
 	tcp_send ( conn, hello->message, hello->remaining );
98
 	tcp_send ( conn, hello->message, hello->remaining );
111
  *
111
  *
112
  * @v hello	"Hello world" request
112
  * @v hello	"Hello world" request
113
  */
113
  */
114
-void hello_connect ( struct hello_request *hello ) {
114
+struct async_operation * say_hello ( struct hello_request *hello ) {
115
 	hello->tcp.tcp_op = &hello_tcp_operations;
115
 	hello->tcp.tcp_op = &hello_tcp_operations;
116
 	tcp_connect ( &hello->tcp );
116
 	tcp_connect ( &hello->tcp );
117
+	return &hello->aop;
117
 }
118
 }

+ 41
- 0
src/tests/ftptest.c View File

1
+#include <stdint.h>
2
+#include <string.h>
3
+#include <byteswap.h>
4
+#include <console.h>
5
+#include <vsprintf.h>
6
+#include <gpxe/async.h>
7
+#include <gpxe/ftp.h>
8
+
9
+static void test_ftp_callback ( char *data, size_t len ) {
10
+	unsigned int i;
11
+	char c;
12
+
13
+	for ( i = 0 ; i < len ; i++ ) {
14
+		c = data[i];
15
+		if ( c == '\r' ) {
16
+			/* Print nothing */
17
+		} else if ( ( c == '\n' ) || ( c >= 32 ) || ( c <= 126 ) ) {
18
+			putchar ( c );
19
+		} else {
20
+			putchar ( '.' );
21
+		}
22
+	}
23
+}
24
+
25
+void test_ftp ( struct in_addr server, const char *filename ) {
26
+	struct ftp_request ftp;
27
+	int rc;
28
+
29
+	printf ( "FTP fetching %s:%s\n", inet_ntoa ( server ), filename );
30
+	
31
+	memset ( &ftp, 0, sizeof ( ftp ) );
32
+	ftp.tcp.sin.sin_addr.s_addr = server.s_addr;
33
+	ftp.tcp.sin.sin_port = htons ( FTP_PORT );
34
+	ftp.filename = filename;
35
+	ftp.callback = test_ftp_callback;
36
+
37
+	rc = async_wait ( ftp_get ( &ftp ) );
38
+	if ( rc ) {
39
+		printf ( "FTP fetch failed\n" );
40
+	}
41
+}

+ 41
- 0
src/tests/hellotest.c View File

1
+#include <stdint.h>
2
+#include <string.h>
3
+#include <byteswap.h>
4
+#include <console.h>
5
+#include <vsprintf.h>
6
+#include <gpxe/async.h>
7
+#include <gpxe/hello.h>
8
+
9
+static void test_hello_callback ( char *data, size_t len ) {
10
+	unsigned int i;
11
+	char c;
12
+
13
+	for ( i = 0 ; i < len ; i++ ) {
14
+		c = data[i];
15
+		if ( c == '\r' ) {
16
+			/* Print nothing */
17
+		} else if ( ( c == '\n' ) || ( c >= 32 ) || ( c <= 126 ) ) {
18
+			putchar ( c );
19
+		} else {
20
+			putchar ( '.' );
21
+		}
22
+	}
23
+}
24
+
25
+void test_hello ( struct sockaddr_in *server, const char *message ) {
26
+	struct hello_request hello;
27
+	int rc;
28
+
29
+	printf ( "Saying \"%s\" to %s:%d\n", message,
30
+		 inet_ntoa ( server->sin_addr ), ntohs ( server->sin_port ) );
31
+	
32
+	memset ( &hello, 0, sizeof ( hello ) );
33
+	hello.tcp.sin = *server;
34
+	hello.message = message;
35
+	hello.callback = test_hello_callback;
36
+
37
+	rc = async_wait ( say_hello ( &hello ) );
38
+	if ( rc ) {
39
+		printf ( "HELLO fetch failed\n" );
40
+	}
41
+}

Loading…
Cancel
Save