1 #include "pxe.h"
2 #if GPXE
3
gpxe_close_file(struct inode * inode)4 static 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 */
gpxe_get_packet(struct inode * inode)18 static 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 */
gpxe_open(struct inode * inode,const char * url)64 void 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