89 lines
2.3 KiB
C
89 lines
2.3 KiB
C
#include "pxe.h"
|
|
#if GPXE
|
|
|
|
static void gpxe_close_file(struct inode *inode)
|
|
{
|
|
struct pxe_pvt_inode *socket = PVT(inode);
|
|
static __lowmem struct s_PXENV_FILE_CLOSE file_close;
|
|
|
|
file_close.FileHandle = socket->tftp_remoteport;
|
|
pxe_call(PXENV_FILE_CLOSE, &file_close);
|
|
}
|
|
|
|
/**
|
|
* Get a fresh packet from a gPXE socket
|
|
* @param: inode -> Inode pointer
|
|
*
|
|
*/
|
|
static void gpxe_get_packet(struct inode *inode)
|
|
{
|
|
struct pxe_pvt_inode *socket = PVT(inode);
|
|
static __lowmem struct s_PXENV_FILE_READ file_read;
|
|
int err;
|
|
|
|
while (1) {
|
|
file_read.FileHandle = socket->tftp_remoteport;
|
|
file_read.Buffer = FAR_PTR(packet_buf);
|
|
file_read.BufferSize = PKTBUF_SIZE;
|
|
err = pxe_call(PXENV_FILE_READ, &file_read);
|
|
if (!err) /* successed */
|
|
break;
|
|
|
|
if (file_read.Status != PXENV_STATUS_TFTP_OPEN)
|
|
kaboom();
|
|
}
|
|
|
|
memcpy(socket->tftp_pktbuf, packet_buf, file_read.BufferSize);
|
|
|
|
socket->tftp_dataptr = socket->tftp_pktbuf;
|
|
socket->tftp_bytesleft = file_read.BufferSize;
|
|
socket->tftp_filepos += file_read.BufferSize;
|
|
|
|
if (socket->tftp_bytesleft == 0)
|
|
inode->size = socket->tftp_filepos;
|
|
|
|
/* if we're done here, close the file */
|
|
if (inode->size > socket->tftp_filepos)
|
|
return;
|
|
|
|
/* Got EOF, close it */
|
|
socket->tftp_goteof = 1;
|
|
gpxe_close_file(inode);
|
|
}
|
|
|
|
/**
|
|
* Open a url using gpxe
|
|
*
|
|
* @param:inode, the inode to store our state in
|
|
* @param:url, the url we want to open
|
|
*
|
|
* @out: open_file_t structure, stores in file->open_file
|
|
* @out: the lenght of this file, stores in file->file_len
|
|
*
|
|
*/
|
|
void gpxe_open(struct inode *inode, const char *url)
|
|
{
|
|
static __lowmem struct s_PXENV_FILE_OPEN file_open;
|
|
static char lowurl[2*FILENAME_MAX];
|
|
struct pxe_pvt_inode *socket = PVT(inode);
|
|
int err;
|
|
|
|
socket->tftp_pktbuf = malloc(PKTBUF_SIZE);
|
|
if (!socket->tftp_pktbuf)
|
|
return;
|
|
|
|
snprintf(lowurl, sizeof lowurl, "%s", url);
|
|
file_open.Status = PXENV_STATUS_BAD_FUNC;
|
|
file_open.FileName = FAR_PTR(lowurl);
|
|
err = pxe_call(PXENV_FILE_OPEN, &file_open);
|
|
if (err)
|
|
return;
|
|
|
|
socket->fill_buffer = gpxe_get_packet;
|
|
socket->close = gpxe_close_file;
|
|
socket->tftp_remoteport = file_open.FileHandle;
|
|
inode->size = -1; /* This is not an error */
|
|
}
|
|
|
|
#endif /* GPXE */
|