iPXE
efi_download.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2010 VMware, Inc. All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18 
19 FILE_LICENCE ( GPL2_OR_LATER );
20 FILE_SECBOOT ( PERMITTED );
21 
22 #include <stdlib.h>
23 #include <string.h>
24 #include <errno.h>
25 #include <ipxe/open.h>
26 #include <ipxe/process.h>
27 #include <ipxe/iobuf.h>
28 #include <ipxe/xfer.h>
29 #include <ipxe/efi/efi.h>
30 #include <ipxe/efi/efi_snp.h>
31 #include <ipxe/efi/efi_download.h>
32 
33 /** iPXE download protocol GUID */
36 
37 /** A single in-progress file */
39  /** Data transfer interface that provides downloaded data */
40  struct interface xfer;
41 
42  /** Current file position */
43  size_t pos;
44 
45  /** Data callback */
47 
48  /** Finish callback */
50 
51  /** Callback context */
52  void *context;
53 };
54 
55 /* xfer interface */
56 
57 /**
58  * Transfer finished or was aborted
59  *
60  * @v file Data transfer file
61  * @v rc Reason for close
62  */
63 static void efi_download_close ( struct efi_download_file *file, int rc ) {
64 
65  file->finish_callback ( file->context, EFIRC ( rc ) );
66 
67  intf_shutdown ( &file->xfer, rc );
68 
70 }
71 
72 /**
73  * Process received data
74  *
75  * @v file Data transfer file
76  * @v iobuf I/O buffer
77  * @v meta Data transfer metadata
78  * @ret rc Return status code
79  */
80 static int efi_download_deliver_iob ( struct efi_download_file *file,
81  struct io_buffer *iobuf,
82  struct xfer_metadata *meta ) {
83  EFI_STATUS efirc;
84  size_t len = iob_len ( iobuf );
85  int rc;
86 
87  /* Calculate new buffer position */
88  if ( meta->flags & XFER_FL_ABS_OFFSET )
89  file->pos = 0;
90  file->pos += meta->offset;
91 
92  /* Call out to the data handler */
93  if ( ( efirc = file->data_callback ( file->context, iobuf->data,
94  len, file->pos ) ) != 0 ) {
95  rc = -EEFI ( efirc );
96  goto err_callback;
97  }
98 
99  /* Update current buffer position */
100  file->pos += len;
101 
102  /* Success */
103  rc = 0;
104 
105  err_callback:
106  free_iob ( iobuf );
107  return rc;
108 }
109 
110 /** Data transfer interface operations */
114 };
115 
116 /** EFI download data transfer interface descriptor */
119 
120 /**
121  * Start downloading a file, and register callback functions to handle the
122  * download.
123  *
124  * @v This iPXE Download Protocol instance
125  * @v Url URL to download from
126  * @v DataCallback Callback that will be invoked when data arrives
127  * @v FinishCallback Callback that will be invoked when the download ends
128  * @v Context Context passed to the Data and Finish callbacks
129  * @v File Token that can be used to abort the download
130  * @ret Status EFI status code
131  */
132 static EFI_STATUS EFIAPI
134  CHAR8 *Url,
135  IPXE_DOWNLOAD_DATA_CALLBACK DataCallback,
136  IPXE_DOWNLOAD_FINISH_CALLBACK FinishCallback,
137  VOID *Context,
138  IPXE_DOWNLOAD_FILE *File ) {
139  struct efi_download_file *file;
140  int rc;
141 
142  efi_snp_claim();
143 
144  file = malloc ( sizeof ( struct efi_download_file ) );
145  if ( file == NULL ) {
146  efi_snp_release();
147  return EFI_OUT_OF_RESOURCES;
148  }
149 
151  rc = xfer_open ( &file->xfer, LOCATION_URI_STRING, Url );
152  if ( rc ) {
153  free ( file );
154  efi_snp_release();
155  return EFIRC ( rc );
156  }
157 
158  file->pos = 0;
159  file->data_callback = DataCallback;
160  file->finish_callback = FinishCallback;
161  file->context = Context;
162  *File = file;
163  return EFI_SUCCESS;
164 }
165 
166 /**
167  * Forcibly abort downloading a file that is currently in progress.
168  *
169  * It is not safe to call this function after the Finish callback has executed.
170  *
171  * @v This iPXE Download Protocol instance
172  * @v File Token obtained from Start
173  * @v Status Reason for aborting the download
174  * @ret Status EFI status code
175  */
176 static EFI_STATUS EFIAPI
178  IPXE_DOWNLOAD_FILE File,
179  EFI_STATUS Status ) {
180  struct efi_download_file *file = File;
181 
182  efi_download_close ( file, -EEFI ( Status ) );
183  return EFI_SUCCESS;
184 }
185 
186 /**
187  * Poll for more data from iPXE. This function will invoke the registered
188  * callbacks if data is available or if downloads complete.
189  *
190  * @v This iPXE Download Protocol instance
191  * @ret Status EFI status code
192  */
193 static EFI_STATUS EFIAPI
195  step();
196  return EFI_SUCCESS;
197 }
198 
199 /** Publicly exposed iPXE download protocol */
202  .Abort = efi_download_abort,
203  .Poll = efi_download_poll
204 };
205 
206 /**
207  * Install iPXE download protocol
208  *
209  * @v handle EFI handle
210  * @ret rc Return status code
211  */
214  EFI_STATUS efirc;
215  int rc;
216 
218  &handle,
221  NULL );
222  if ( efirc ) {
223  rc = -EEFI ( efirc );
224  DBG ( "Could not install download protocol: %s\n",
225  strerror ( rc ) );
226  return rc;
227  }
228 
229  return 0;
230 }
231 
232 /**
233  * Uninstall iPXE download protocol
234  *
235  * @v handle EFI handle
236  */
239 
241  handle,
244 }
iPXE Download Protocol
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2099
An object interface operation.
Definition: interface.h:18
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition: interface.c:250
void efi_download_uninstall(EFI_HANDLE handle)
Uninstall iPXE download protocol.
Definition: efi_download.c:237
Data transfer metadata.
Definition: xfer.h:23
void intf_shutdown(struct interface *intf, int rc)
Shut down an object interface.
Definition: interface.c:279
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:175
static int efi_download_deliver_iob(struct efi_download_file *file, struct io_buffer *iobuf, struct xfer_metadata *meta)
Process received data.
Definition: efi_download.c:80
IPXE_DOWNLOAD_DATA_CALLBACK data_callback
Data callback.
Definition: efi_download.c:46
The iPXE Download Protocol.
Definition: efi_download.h:144
static struct interface_operation efi_xfer_operations[]
Data transfer interface operations.
Definition: efi_download.c:111
128 bit buffer containing a unique identifier value.
Definition: Base.h:216
#define XFER_FL_ABS_OFFSET
Offset is absolute.
Definition: xfer.h:48
Error codes.
PXENV_STATUS_t Status
PXE status code.
Definition: pxe_api.h:57
I/O buffers.
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition: iobuf.c:153
void * context
Callback context.
Definition: efi_download.c:52
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:2010
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:92
A single in-progress file.
Definition: efi_download.c:38
IPXE_DOWNLOAD_FINISH_CALLBACK finish_callback
Finish callback.
Definition: efi_download.c:49
#define EFI_OUT_OF_RESOURCES
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:124
VOID * IPXE_DOWNLOAD_FILE
Token to represent a currently downloading file.
Definition: efi_download.h:35
Data transfer interfaces.
IPXE_DOWNLOAD_START Start
Definition: efi_download.h:145
void(EFIAPI * IPXE_DOWNLOAD_FINISH_CALLBACK)(IN VOID *Context, IN EFI_STATUS Status)
Callback function that is invoked when the file is finished downloading, or when a connection unexpec...
Definition: efi_download.h:79
Location is a URI string.
Definition: open.h:35
An object interface.
Definition: interface.h:125
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
ring len
Length.
Definition: dwmac.h:231
An object interface descriptor.
Definition: interface.h:56
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
#define EFIAPI
EFI Boot Services Table.
Definition: UefiSpec.h:1931
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition: iobuf.h:160
FILE_LICENCE(GPL2_OR_LATER)
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition: interface.h:33
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:2011
static EFI_STATUS EFIAPI efi_download_poll(IPXE_DOWNLOAD_PROTOCOL *This __unused)
Poll for more data from iPXE.
Definition: efi_download.c:194
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition: efi_snp.h:100
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition: xfer.c:195
Processes.
Data transfer interface opening.
static struct interface_descriptor efi_download_file_xfer_desc
EFI download data transfer interface descriptor.
Definition: efi_download.c:117
FILE_SECBOOT(PERMITTED)
int xfer_open(struct interface *intf, int type,...)
Open location.
Definition: open.c:203
#define VOID
Undeclared type.
Definition: Base.h:272
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
static IPXE_DOWNLOAD_PROTOCOL ipxe_download_protocol_interface
Publicly exposed iPXE download protocol.
Definition: efi_download.c:200
EFI API.
size_t pos
Current file position.
Definition: efi_download.c:43
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition: interface.h:81
#define EFI_SUCCESS
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:115
char CHAR8
void * data
Start of data.
Definition: iobuf.h:53
static EFI_STATUS EFIAPI efi_download_start(IPXE_DOWNLOAD_PROTOCOL *This __unused, CHAR8 *Url, IPXE_DOWNLOAD_DATA_CALLBACK DataCallback, IPXE_DOWNLOAD_FINISH_CALLBACK FinishCallback, VOID *Context, IPXE_DOWNLOAD_FILE *File)
Start downloading a file, and register callback functions to handle the download.
Definition: efi_download.c:133
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:32
void step(void)
Single-step a single process.
Definition: process.c:99
struct interface xfer
Data transfer interface that provides downloaded data.
Definition: efi_download.c:40
#define IPXE_DOWNLOAD_PROTOCOL_GUID
Definition: efi_download.h:150
int efi_download_install(EFI_HANDLE handle)
Install iPXE download protocol.
Definition: efi_download.c:212
static void efi_download_close(struct efi_download_file *file, int rc)
Transfer finished or was aborted.
Definition: efi_download.c:63
EFI_SYSTEM_TABLE * efi_systab
iPXE EFI SNP interface
uint8_t meta
Metadata flags.
Definition: ena.h:14
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition: interface.h:204
uint16_t handle
Handle.
Definition: smbios.h:17
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
String functions.
EFI_STATUS(EFIAPI * IPXE_DOWNLOAD_DATA_CALLBACK)(IN VOID *Context, IN VOID *Buffer, IN UINTN BufferLength, IN UINTN FileOffset)
Callback function that is invoked when data arrives for a particular file.
Definition: efi_download.h:58
static EFI_GUID ipxe_download_protocol_guid
iPXE download protocol GUID
Definition: efi_download.c:35
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:167
Definition: efi.h:62
static EFI_STATUS EFIAPI efi_download_abort(IPXE_DOWNLOAD_PROTOCOL *This __unused, IPXE_DOWNLOAD_FILE File, EFI_STATUS Status)
Forcibly abort downloading a file that is currently in progress.
Definition: efi_download.c:177
A persistent I/O buffer.
Definition: iobuf.h:38