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 */ |
---|