Home | History | Annotate | Download | only in pxe
      1 #include "pxe.h"
      2 #if GPXE
      3 
      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  */
     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  */
     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