summaryrefslogtreecommitdiff
path: root/core/fs/pxe/tcp.c
blob: 528fbce840bc2fd2fc61156f08d308d9c9ee9cd3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/* ----------------------------------------------------------------------- *
 *
 *   Copyright 2011 Intel Corporation; author: H. Peter Anvin
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 *   Boston MA 02110-1301, USA; either version 2 of the License, or
 *   (at your option) any later version; incorporated herein by reference.
 *
 * ----------------------------------------------------------------------- */

/*
 * tcp.c
 *
 * Common operations for TCP-based network protocols
 */

#include <lwip/api.h>
#include "pxe.h"
#include "../../../version.h"
#include "url.h"

void tcp_close_file(struct inode *inode)
{
    struct pxe_pvt_inode *socket = PVT(inode);

    if (socket->private.conn) {
	netconn_delete(socket->private.conn);
	socket->private.conn = NULL;
    }
    if (socket->private.buf) {
	netbuf_delete(socket->private.buf);
        socket->private.buf = NULL;
    }
}

void tcp_fill_buffer(struct inode *inode)
{
    struct pxe_pvt_inode *socket = PVT(inode);
    void *data;
    u16_t len;
    err_t err;

    /* Clean up or advance an inuse netbuf */
    if (socket->private.buf) {
	if (netbuf_next(socket->private.buf) < 0) {
	    netbuf_delete(socket->private.buf);
	    socket->private.buf = NULL;
	}
    }
    /* If needed get a new netbuf */
    if (!socket->private.buf) {
	err = netconn_recv(socket->private.conn, &(socket->private.buf));
	if (!socket->private.buf || err) {
	    socket->tftp_goteof = 1;
	    if (inode->size == -1)
		inode->size = socket->tftp_filepos;
	    socket->ops->close(inode);
	    return;
	}
    }
    /* Report the current fragment of the netbuf */
    err = netbuf_data(socket->private.buf, &data, &len);
    if (err) {
	printf("netbuf_data err: %d\n", err);
	kaboom();
    }
    socket->tftp_dataptr = data;
    socket->tftp_filepos += len;
    socket->tftp_bytesleft = len;
    return;
}

const struct pxe_conn_ops tcp_conn_ops = {
    .fill_buffer	= tcp_fill_buffer,
    .close		= tcp_close_file,
};