]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcMtftp.c
Roll back the DEBUG mask change which cause SerialIo read_conf test item failure.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / UefiPxeBcDxe / PxeBcMtftp.c
1 /** @file
2 PxeBc MTFTP functions.
3
4 Copyright (c) 2007, Intel Corporation.<BR>
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #include "PxeBcImpl.h"
16
17 VOID *TokenContext = NULL;
18
19 CHAR8 *mMtftpOptions[PXE_MTFTP_OPTION_MAXIMUM_INDEX] = {
20 "blksize",
21 "timeout",
22 "tsize",
23 "multicast"
24 };
25
26
27 /**
28 This is a callback function when packets received/transmitted in Mtftp driver.
29
30 A callback function that is provided by the caller to intercept
31 the EFI_MTFTP4_OPCODE_DATA or EFI_MTFTP4_OPCODE_DATA8 packets processed in the
32 EFI_MTFTP4_PROTOCOL.ReadFile() function, and alternatively to intercept
33 EFI_MTFTP4_OPCODE_OACK or EFI_MTFTP4_OPCODE_ERROR packets during a call to
34 EFI_MTFTP4_PROTOCOL.ReadFile(), WriteFile() or ReadDirectory().
35
36 @param This Pointer to Mtftp protocol instance
37 @param Token Pointer to Mtftp token
38 @param PacketLen Length of Mtftp packet
39 @param Packet Pointer to Mtftp packet
40
41 @retval EFI_SUCCESS Operation sucess
42 @retval EFI_ABORTED Abort transfer process
43
44 **/
45 EFI_STATUS
46 PxeBcCheckPacket (
47 IN EFI_MTFTP4_PROTOCOL *This,
48 IN EFI_MTFTP4_TOKEN *Token,
49 IN UINT16 PacketLen,
50 IN EFI_MTFTP4_PACKET *Packet
51 )
52 {
53 PXEBC_PRIVATE_DATA *Private;
54 EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL *Callback;
55 EFI_STATUS Status;
56
57 Private = (PXEBC_PRIVATE_DATA *) TokenContext;
58 Callback = Private->PxeBcCallback;
59 Status = EFI_SUCCESS;
60
61 if (Packet->OpCode == EFI_MTFTP4_OPCODE_ERROR) {
62 Private->Mode.TftpErrorReceived = TRUE;
63 Private->Mode.TftpError.ErrorCode = (UINT8) Packet->Error.ErrorCode;
64 AsciiStrnCpy (Private->Mode.TftpError.ErrorString, (CHAR8 *) Packet->Error.ErrorMessage, 127);
65 }
66
67 if (Callback != NULL) {
68
69 Status = Callback->Callback (
70 Callback,
71 Private->Function,
72 TRUE,
73 PacketLen,
74 (EFI_PXE_BASE_CODE_PACKET *) Packet
75 );
76 if (Status != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {
77
78 Status = EFI_ABORTED;
79 } else {
80
81 Status = EFI_SUCCESS;
82 }
83 }
84
85 return Status;
86 }
87
88
89 /**
90 This function is to get size of a file by Tftp.
91
92 @param Private Pointer to PxeBc private data
93 @param Config Pointer to Mtftp configuration data
94 @param Filename Pointer to file name
95 @param BlockSize Pointer to block size
96 @param BufferSize Pointer to buffer size
97
98 @retval EFI_SUCCESS Get the size of file success
99 @retval EFI_NOT_FOUND Parse the tftp ptions failed.
100 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
101 @retval Other Has not get the size of the file.
102
103 **/
104 EFI_STATUS
105 PxeBcTftpGetFileSize (
106 IN PXEBC_PRIVATE_DATA *Private,
107 IN EFI_MTFTP4_CONFIG_DATA *Config,
108 IN UINT8 *Filename,
109 IN UINTN *BlockSize,
110 IN OUT UINT64 *BufferSize
111 )
112 {
113 EFI_MTFTP4_PROTOCOL *Mtftp4;
114 EFI_MTFTP4_OPTION ReqOpt[2];
115 EFI_MTFTP4_PACKET *Packet;
116 EFI_MTFTP4_OPTION *Option;
117 UINT32 PktLen;
118 UINT8 OptBuf[128];
119 UINT32 OptCnt;
120 EFI_STATUS Status;
121
122 *BufferSize = 0;
123 Status = EFI_DEVICE_ERROR;
124 Mtftp4 = Private->Mtftp4;
125 Packet = NULL;
126 Option = NULL;
127 PktLen = 0;
128 OptCnt = 1;
129 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
130
131 Status = Mtftp4->Configure (Mtftp4, Config);
132 if (EFI_ERROR (Status)) {
133
134 return Status;
135 }
136
137 ReqOpt[0].OptionStr = (UINT8*)mMtftpOptions[PXE_MTFTP_OPTION_TSIZE_INDEX];
138 UtoA10 (0, (CHAR8 *) OptBuf);
139 ReqOpt[0].ValueStr = OptBuf;
140
141 if (BlockSize != NULL) {
142 ReqOpt[1].OptionStr = (UINT8*)mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
143 ReqOpt[1].ValueStr = ReqOpt[0].ValueStr + AsciiStrLen ((CHAR8 *) ReqOpt[0].ValueStr) + 1;
144 UtoA10 (*BlockSize, (CHAR8 *) ReqOpt[1].ValueStr);
145 OptCnt++;
146 }
147
148 Status = Mtftp4->GetInfo (
149 Mtftp4,
150 FALSE,
151 Filename,
152 NULL,
153 (UINT8) OptCnt,
154 ReqOpt,
155 &PktLen,
156 &Packet
157 );
158
159 if (EFI_ERROR (Status)) {
160 if (Packet->OpCode == EFI_MTFTP4_OPCODE_ERROR) {
161 Private->Mode.TftpErrorReceived = TRUE;
162 Private->Mode.TftpError.ErrorCode = (UINT8) Packet->Error.ErrorCode;
163 AsciiStrnCpy (
164 Private->Mode.TftpError.ErrorString,
165 (CHAR8 *) Packet->Error.ErrorMessage,
166 127
167 );
168 }
169 goto ON_ERROR;
170 }
171
172 OptCnt = 0;
173
174 Status = Mtftp4->ParseOptions (
175 Mtftp4,
176 PktLen,
177 Packet,
178 (UINT32 *) &OptCnt,
179 &Option
180 );
181
182 if (EFI_ERROR (Status)) {
183
184 goto ON_ERROR;
185 }
186
187 Status = EFI_NOT_FOUND;
188
189 while (OptCnt != 0) {
190
191 if (AsciiStrnCmp ((CHAR8 *) Option[OptCnt - 1].OptionStr, "tsize", 5) == 0) {
192
193 *BufferSize = AtoU64 (Option[OptCnt - 1].ValueStr);
194 Status = EFI_SUCCESS;
195 }
196
197 OptCnt--;
198 }
199
200 gBS->FreePool (Option);
201
202 ON_ERROR:
203
204 if (Packet != NULL) {
205 gBS->FreePool (Packet);
206 }
207
208 Mtftp4->Configure (Mtftp4, NULL);
209
210 return Status;
211 }
212
213
214 /**
215 This function is to get data of a file by Tftp.
216
217 @param Private Pointer to PxeBc private data
218 @param Config Pointer to Mtftp configuration data
219 @param Filename Pointer to file name
220 @param BlockSize Pointer to block size
221 @param BufferPtr Pointer to buffer
222 @param BufferSize Pointer to buffer size
223 @param DontUseBuffer Indicate whether with a receive buffer
224
225 @retval EFI_SUCCESS Read the data success from the special file.
226 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
227 @retval other Read data from file failed.
228
229 **/
230 EFI_STATUS
231 PxeBcTftpReadFile (
232 IN PXEBC_PRIVATE_DATA *Private,
233 IN EFI_MTFTP4_CONFIG_DATA *Config,
234 IN UINT8 *Filename,
235 IN UINTN *BlockSize,
236 IN UINT8 *BufferPtr,
237 IN OUT UINT64 *BufferSize,
238 IN BOOLEAN DontUseBuffer
239 )
240 {
241 EFI_MTFTP4_PROTOCOL *Mtftp4;
242 EFI_MTFTP4_TOKEN Token;
243 EFI_MTFTP4_OPTION ReqOpt[1];
244 UINT32 OptCnt;
245 UINT8 OptBuf[128];
246 EFI_STATUS Status;
247
248 Status = EFI_DEVICE_ERROR;
249 Mtftp4 = Private->Mtftp4;
250 OptCnt = 0;
251 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
252
253 Status = Mtftp4->Configure (Mtftp4, Config);
254 if (EFI_ERROR (Status)) {
255
256 return Status;
257 }
258
259 if (BlockSize != NULL) {
260
261 ReqOpt[0].OptionStr = (UINT8*) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
262 ReqOpt[0].ValueStr = OptBuf;
263 UtoA10 (*BlockSize, (CHAR8 *) ReqOpt[0].ValueStr);
264 OptCnt++;
265 }
266
267 Token.Event = NULL;
268 Token.OverrideData = NULL;
269 Token.Filename = Filename;
270 Token.ModeStr = NULL;
271 Token.OptionCount = OptCnt;
272 Token.OptionList = ReqOpt;
273 TokenContext = Private;
274
275 if (DontUseBuffer) {
276 Token.BufferSize = 0;
277 Token.Buffer = NULL;
278 } else {
279 Token.BufferSize = *BufferSize;
280 Token.Buffer = BufferPtr;
281 }
282
283 Token.CheckPacket = PxeBcCheckPacket;
284 Token.TimeoutCallback = NULL;
285 Token.PacketNeeded = NULL;
286
287 Status = Mtftp4->ReadFile (Mtftp4, &Token);
288
289 *BufferSize = Token.BufferSize;
290
291 Mtftp4->Configure (Mtftp4, NULL);
292
293 return Status;
294 }
295
296
297 /**
298 This function is put data of a file by Tftp.
299
300 @param Private Pointer to PxeBc private data
301 @param Config Pointer to Mtftp configuration data
302 @param Filename Pointer to file name
303 @param Overwrite Indicate whether with overwrite attribute
304 @param BlockSize Pointer to block size
305 @param BufferPtr Pointer to buffer
306 @param BufferSize Pointer to buffer size
307
308 @retval EFI_SUCCESS Write the data success into the special file.
309 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
310 @retval other Write data into file failed.
311
312 **/
313 EFI_STATUS
314 PxeBcTftpWriteFile (
315 IN PXEBC_PRIVATE_DATA *Private,
316 IN EFI_MTFTP4_CONFIG_DATA *Config,
317 IN UINT8 *Filename,
318 IN BOOLEAN Overwrite,
319 IN UINTN *BlockSize,
320 IN UINT8 *BufferPtr,
321 IN OUT UINT64 *BufferSize
322 )
323 {
324 EFI_MTFTP4_PROTOCOL *Mtftp4;
325 EFI_MTFTP4_TOKEN Token;
326 EFI_MTFTP4_OPTION ReqOpt[1];
327 UINT32 OptCnt;
328 UINT8 OptBuf[128];
329 EFI_STATUS Status;
330
331 Status = EFI_DEVICE_ERROR;
332 Mtftp4 = Private->Mtftp4;
333 OptCnt = 0;
334 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
335
336 Status = Mtftp4->Configure (Mtftp4, Config);
337 if (EFI_ERROR (Status)) {
338
339 return Status;
340 }
341
342 if (BlockSize != NULL) {
343
344 ReqOpt[0].OptionStr = (UINT8*) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
345 ReqOpt[0].ValueStr = OptBuf;
346 UtoA10 (*BlockSize, (CHAR8 *) ReqOpt[0].ValueStr);
347 OptCnt++;
348 }
349
350 Token.Event = NULL;
351 Token.OverrideData = NULL;
352 Token.Filename = Filename;
353 Token.ModeStr = NULL;
354 Token.OptionCount = OptCnt;
355 Token.OptionList = ReqOpt;
356 Token.BufferSize = *BufferSize;
357 Token.Buffer = BufferPtr;
358 Token.CheckPacket = PxeBcCheckPacket;
359 Token.TimeoutCallback = NULL;
360 Token.PacketNeeded = NULL;
361
362 Status = Mtftp4->WriteFile (Mtftp4, &Token);
363 *BufferSize = Token.BufferSize;
364
365 Mtftp4->Configure (Mtftp4, NULL);
366
367 return Status;
368 }
369
370
371 /**
372 This function is to get data(file) from a directory(may be a server) by Tftp.
373
374 @param Private Pointer to PxeBc private data.
375 @param Config Pointer to Mtftp configuration data.
376 @param Filename Pointer to file name.
377 @param BlockSize Pointer to block size.
378 @param BufferPtr Pointer to buffer.
379 @param BufferSize Pointer to buffer size.
380 @param DontUseBuffer Indicate whether with a receive buffer.
381
382 @retval EFI_SUCCES Get the data from the file included in directory success.
383 @retval EFI_DEVICE_ERROR The network device encountered an error during this operation.
384 @retval other Operation failed.
385
386 **/
387 EFI_STATUS
388 PxeBcTftpReadDirectory (
389 IN PXEBC_PRIVATE_DATA *Private,
390 IN EFI_MTFTP4_CONFIG_DATA *Config,
391 IN UINT8 *Filename,
392 IN UINTN *BlockSize,
393 IN UINT8 *BufferPtr,
394 IN OUT UINT64 *BufferSize,
395 IN BOOLEAN DontUseBuffer
396 )
397 {
398 EFI_MTFTP4_PROTOCOL *Mtftp4;
399 EFI_MTFTP4_TOKEN Token;
400 EFI_MTFTP4_OPTION ReqOpt[1];
401 UINT32 OptCnt;
402 UINT8 OptBuf[128];
403 EFI_STATUS Status;
404
405 Status = EFI_DEVICE_ERROR;
406 Mtftp4 = Private->Mtftp4;
407 OptCnt = 0;
408 Config->InitialServerPort = PXEBC_BS_DOWNLOAD_PORT;
409
410 Status = Mtftp4->Configure (Mtftp4, Config);
411 if (EFI_ERROR (Status)) {
412
413 return Status;
414 }
415
416 if (BlockSize != NULL) {
417
418 ReqOpt[0].OptionStr = (UINT8*) mMtftpOptions[PXE_MTFTP_OPTION_BLKSIZE_INDEX];
419 ReqOpt[0].ValueStr = OptBuf;
420 UtoA10 (*BlockSize, (CHAR8 *) ReqOpt[0].ValueStr);
421 OptCnt++;
422 }
423
424 Token.Event = NULL;
425 Token.OverrideData = NULL;
426 Token.Filename = Filename;
427 Token.ModeStr = NULL;
428 Token.OptionCount = OptCnt;
429 Token.OptionList = ReqOpt;
430 TokenContext = Private;
431
432 if (DontUseBuffer) {
433 Token.BufferSize = 0;
434 Token.Buffer = NULL;
435 } else {
436 Token.BufferSize = *BufferSize;
437 Token.Buffer = BufferPtr;
438 }
439
440 Token.CheckPacket = PxeBcCheckPacket;
441 Token.TimeoutCallback = NULL;
442 Token.PacketNeeded = NULL;
443
444 Status = Mtftp4->ReadDirectory (Mtftp4, &Token);
445
446 *BufferSize = Token.BufferSize;
447
448 Mtftp4->Configure (Mtftp4, NULL);
449
450 return Status;
451 }
452