1#include "pxe.h"
2#if GPXE
3
4static void gpxe_close_file(struct inode *inode)
5{
6    struct pxe_pvt_inode *socket = PVT(inode);
7    static __lowmem struct s_PXENV_FILE_CLOSE file_close;
8
9    file_close.FileHandle = socket->tftp_remoteport;
10    pxe_call(PXENV_FILE_CLOSE, &file_close);
11}
12
13/**
14 * Get a fresh packet from a gPXE socket
15 * @param: inode -> Inode pointer
16 *
17 */
18static void gpxe_get_packet(struct inode *inode)
19{
20    struct pxe_pvt_inode *socket = PVT(inode);
21    static __lowmem struct s_PXENV_FILE_READ file_read;
22    int err;
23
24    while (1) {
25        file_read.FileHandle  = socket->tftp_remoteport;
26        file_read.Buffer      = FAR_PTR(packet_buf);
27        file_read.BufferSize  = PKTBUF_SIZE;
28        err = pxe_call(PXENV_FILE_READ, &file_read);
29        if (!err)  /* successed */
30            break;
31
32        if (file_read.Status != PXENV_STATUS_TFTP_OPEN)
33	    kaboom();
34    }
35
36    memcpy(socket->tftp_pktbuf, packet_buf, file_read.BufferSize);
37
38    socket->tftp_dataptr   = socket->tftp_pktbuf;
39    socket->tftp_bytesleft = file_read.BufferSize;
40    socket->tftp_filepos  += file_read.BufferSize;
41
42    if (socket->tftp_bytesleft == 0)
43        inode->size = socket->tftp_filepos;
44
45    /* if we're done here, close the file */
46    if (inode->size > socket->tftp_filepos)
47        return;
48
49    /* Got EOF, close it */
50    socket->tftp_goteof = 1;
51    gpxe_close_file(inode);
52}
53
54/**
55 * Open a url using gpxe
56 *
57 * @param:inode, the inode to store our state in
58 * @param:url, the url we want to open
59 *
60 * @out: open_file_t structure, stores in file->open_file
61 * @out: the lenght of this file, stores in file->file_len
62 *
63 */
64void gpxe_open(struct inode *inode, const char *url)
65{
66    static __lowmem struct s_PXENV_FILE_OPEN file_open;
67    static char lowurl[2*FILENAME_MAX];
68    struct pxe_pvt_inode *socket = PVT(inode);
69    int err;
70
71    socket->tftp_pktbuf = malloc(PKTBUF_SIZE);
72    if (!socket->tftp_pktbuf)
73	return;
74
75    snprintf(lowurl, sizeof lowurl, "%s", url);
76    file_open.Status        = PXENV_STATUS_BAD_FUNC;
77    file_open.FileName      = FAR_PTR(lowurl);
78    err = pxe_call(PXENV_FILE_OPEN, &file_open);
79    if (err)
80	return;
81
82    socket->fill_buffer = gpxe_get_packet;
83    socket->close = gpxe_close_file;
84    socket->tftp_remoteport = file_open.FileHandle;
85    inode->size = -1; /* This is not an error */
86}
87
88#endif /* GPXE */
89