60 if (EFI_ERROR (Status)) {
66 if (EFI_ERROR (Status)) {
98 return EFI_OUT_OF_RESOURCES;
106 ASSERT (Ack !=
NULL);
108 Ack->
Ack.OpCode = HTONS (EFI_MTFTP4_OPCODE_ACK);
109 Ack->
Ack.Block[0] = HTONS (BlkNo);
112 if (!EFI_ERROR (Status)) {
113 Instance->AckedBlock = Instance->TotalBlock;
150 Token = Instance->Token;
151 Block = NTOHS (Packet->Data.Block);
152 DataLen = Len - MTFTP4_DATA_HEAD_LEN;
157 if (DataLen < Instance->BlkSize) {
159 Instance->LastBlock = Block;
172 if (Status == EFI_NOT_FOUND) {
174 }
else if (EFI_ERROR (Status)) {
179 Status = Token->
CheckPacket (&Instance->Mtftp4, Token, (UINT16)Len, Packet);
181 if (EFI_ERROR (Status)) {
184 EFI_MTFTP4_ERRORCODE_ILLEGAL_OPERATION,
185 (UINT8 *)
"User aborted download"
193 Start =
MultU64x32 (BlockCounter - 1, Instance->BlkSize);
195 if (Start + DataLen <= Token->BufferSize) {
196 CopyMem ((UINT8 *)Token->
Buffer + Start, Packet->Data.Data, DataLen);
201 if ((Instance->LastBlock == Block) && Completed) {
204 }
else if (Instance->LastBlock != 0) {
214 EFI_MTFTP4_ERRORCODE_DISK_FULL,
215 (UINT8 *)
"User provided memory block is too small"
218 return EFI_BUFFER_TOO_SMALL;
246 IN BOOLEAN Multicast,
247 OUT BOOLEAN *Completed
256 BlockNum = NTOHS (Packet->Data.Block);
259 ASSERT (Expected >= 0);
266 if (Instance->Master && (Expected != BlockNum)) {
275 if (EFI_ERROR (Status)) {
282 Instance->TotalBlock++;
288 if (!Instance->Master) {
300 if (Instance->Master || (Expected < 0)) {
308 BlockNum = Instance->LastBlock;
311 BlockNum = (UINT16)(Expected - 1);
314 if ((Instance->WindowSize == (Instance->TotalBlock - Instance->AckedBlock)) || (Expected < 0)) {
349 if ((Reply->Exist &~Request->Exist) != 0) {
357 if ((((Reply->Exist & MTFTP4_BLKSIZE_EXIST) != 0) && (Reply->BlkSize > Request->BlkSize)) ||
358 (((Reply->Exist & MTFTP4_WINDOWSIZE_EXIST) != 0) && (Reply->WindowSize > Request->WindowSize)) ||
359 (((Reply->Exist & MTFTP4_TIMEOUT_EXIST) != 0) && (Reply->Timeout != Request->Timeout))
370 if (((Reply->Exist & MTFTP4_MCAST_EXIST) != 0) && (This->McastIp != 0)) {
371 if ((Reply->McastIp != 0) && (Reply->McastIp != This->McastIp)) {
375 if ((Reply->McastPort != 0) && (Reply->McastPort != This->McastPort)) {
409 Config = &Instance->Config;
411 UdpConfig.AcceptBroadcast =
FALSE;
412 UdpConfig.AcceptPromiscuous =
FALSE;
413 UdpConfig.AcceptAnyPort =
FALSE;
414 UdpConfig.AllowDuplicatePort =
FALSE;
415 UdpConfig.TypeOfService = 0;
416 UdpConfig.TimeToLive = 64;
417 UdpConfig.DoNotFragment =
FALSE;
418 UdpConfig.ReceiveTimeout = 0;
419 UdpConfig.TransmitTimeout = 0;
420 UdpConfig.UseDefaultAddress = Config->UseDefaultSetting;
421 IP4_COPY_ADDRESS (&UdpConfig.StationAddress, &Config->StationIp);
422 IP4_COPY_ADDRESS (&UdpConfig.SubnetMask, &Config->SubnetMask);
423 UdpConfig.StationPort = Instance->McastPort;
424 UdpConfig.RemotePort = 0;
426 Ip = HTONL (Instance->ServerIp);
427 IP4_COPY_ADDRESS (&UdpConfig.RemoteAddress, &Ip);
429 Status = McastIo->Protocol.Udp4->Configure (McastIo->Protocol.Udp4, &UdpConfig);
431 if (EFI_ERROR (Status)) {
435 if (!Config->UseDefaultSetting &&
436 !EFI_IP4_EQUAL (&mZeroIp4Addr, &Config->GatewayIp))
442 Status = McastIo->Protocol.Udp4->Routes (
443 McastIo->Protocol.Udp4,
450 if (EFI_ERROR (Status)) {
451 McastIo->Protocol.Udp4->Configure (McastIo->Protocol.Udp4,
NULL);
459 Ip = HTONL (Instance->McastIp);
460 IP4_COPY_ADDRESS (&Group, &Ip);
462 return McastIo->Protocol.Udp4->Groups (McastIo->Protocol.Udp4,
TRUE, &Group);
487 IN BOOLEAN Multicast,
488 OUT BOOLEAN *Completed
503 ASSERT (Expected != -1);
505 if (Instance->Master && (Expected != 1)) {
516 if (EFI_ERROR (Status) ||
522 if (Status != EFI_OUT_OF_RESOURCES) {
525 EFI_MTFTP4_ERRORCODE_ILLEGAL_OPERATION,
526 (UINT8 *)
"Malformatted OACK packet"
530 return EFI_TFTP_ERROR;
533 if ((Reply.Exist & MTFTP4_MCAST_EXIST) != 0) {
539 Instance->Master = Reply.Master;
541 if (Instance->McastIp == 0) {
542 if ((Reply.McastIp == 0) || (Reply.McastPort == 0)) {
545 EFI_MTFTP4_ERRORCODE_ILLEGAL_OPERATION,
546 (UINT8 *)
"Illegal multicast setting"
549 return EFI_TFTP_ERROR;
555 Instance->McastIp = Reply.McastIp;
556 Instance->McastPort = Reply.McastPort;
557 if (Instance->McastUdpPort ==
NULL) {
559 Instance->Service->Controller,
560 Instance->Service->Image,
565 if (Instance->McastUdpPort !=
NULL) {
566 Status =
gBS->OpenProtocol (
567 Instance->McastUdpPort->UdpHandle,
568 &gEfiUdp4ProtocolGuid,
570 Instance->Service->Image,
572 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
574 if (EFI_ERROR (Status)) {
576 Instance->McastUdpPort =
NULL;
577 return EFI_DEVICE_ERROR;
582 if (Instance->McastUdpPort ==
NULL) {
583 return EFI_DEVICE_ERROR;
588 if (EFI_ERROR (Status)) {
591 EFI_MTFTP4_ERRORCODE_ACCESS_VIOLATION,
592 (UINT8 *)
"Failed to create socket to receive multicast packet"
601 if (Reply.BlkSize != 0) {
602 Instance->BlkSize = Reply.BlkSize;
605 if (Reply.WindowSize != 0) {
606 Instance->WindowSize = Reply.WindowSize;
609 if (Reply.Timeout != 0) {
610 Instance->Timeout = Reply.Timeout;
614 Instance->Master =
TRUE;
616 if (Reply.BlkSize != 0) {
617 Instance->BlkSize = Reply.BlkSize;
620 if (Reply.WindowSize != 0) {
621 Instance->WindowSize = Reply.WindowSize;
624 if (Reply.Timeout != 0) {
625 Instance->Timeout = Reply.Timeout;
663 NET_CHECK_SIGNATURE (Instance, MTFTP4_PROTOCOL_SIGNATURE);
670 if (EFI_ERROR (IoStatus)) {
675 ASSERT (UdpPacket !=
NULL);
680 Multicast = (BOOLEAN)(EndPoint->LocalAddr.Addr[0] == Instance->McastIp);
682 if (UdpPacket->TotalSize < MTFTP4_OPCODE_LEN) {
692 if (EndPoint->RemotePort != Instance->ConnectedPort) {
693 if (Instance->ConnectedPort != 0) {
696 Instance->ConnectedPort = EndPoint->RemotePort;
703 Len = UdpPacket->TotalSize;
705 if (UdpPacket->BlockOpNum > 1) {
708 if (Packet ==
NULL) {
709 Status = EFI_OUT_OF_RESOURCES;
713 NetbufCopy (UdpPacket, 0, Len, (UINT8 *)Packet);
716 ASSERT (Packet !=
NULL);
719 Opcode = NTOHS (Packet->
OpCode);
726 ((Opcode == EFI_MTFTP4_OPCODE_OACK) || (Opcode == EFI_MTFTP4_OPCODE_ERROR)))
735 if (EFI_ERROR (Status)) {
739 if (Opcode != EFI_MTFTP4_OPCODE_ERROR) {
742 EFI_MTFTP4_ERRORCODE_REQUEST_DENIED,
743 (UINT8 *)
"User aborted the transfer"
747 Status = EFI_ABORTED;
753 case EFI_MTFTP4_OPCODE_DATA:
754 if ((Len > (UINT32)(MTFTP4_DATA_HEAD_LEN + Instance->BlkSize)) ||
755 (Len < (UINT32)MTFTP4_DATA_HEAD_LEN))
763 case EFI_MTFTP4_OPCODE_OACK:
764 if (Multicast || (Len <= MTFTP4_OPCODE_LEN)) {
771 case EFI_MTFTP4_OPCODE_ERROR:
772 Status = EFI_TFTP_ERROR;
785 if ((Packet !=
NULL) && (UdpPacket->BlockOpNum > 1)) {
789 if (UdpPacket !=
NULL) {
793 if (!EFI_ERROR (Status) && !Completed) {
801 if (EFI_ERROR (Status) || Completed) {
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID Mtftp4CleanOperation(IN OUT MTFTP4_PROTOCOL *Instance, IN EFI_STATUS Result)
EFI_STATUS Mtftp4ParseOptionOack(IN EFI_MTFTP4_PACKET *Packet, IN UINT32 PacketLen, IN UINT16 Operation, OUT MTFTP4_OPTION *MtftpOption)
EFI_STATUS Mtftp4RrqStart(IN MTFTP4_PROTOCOL *Instance, IN UINT16 Operation)
EFI_STATUS Mtftp4RrqHandleOack(IN OUT MTFTP4_PROTOCOL *Instance, IN EFI_MTFTP4_PACKET *Packet, IN UINT32 Len, IN BOOLEAN Multicast, OUT BOOLEAN *Completed)
EFI_STATUS Mtftp4RrqHandleData(IN MTFTP4_PROTOCOL *Instance, IN EFI_MTFTP4_PACKET *Packet, IN UINT32 Len, IN BOOLEAN Multicast, OUT BOOLEAN *Completed)
BOOLEAN Mtftp4RrqOackValid(IN MTFTP4_PROTOCOL *This, IN MTFTP4_OPTION *Reply, IN MTFTP4_OPTION *Request)
EFI_STATUS Mtftp4RrqSaveBlock(IN OUT MTFTP4_PROTOCOL *Instance, IN EFI_MTFTP4_PACKET *Packet, IN UINT32 Len)
EFI_STATUS EFIAPI Mtftp4RrqConfigMcastPort(IN UDP_IO *McastIo, IN VOID *Context)
VOID EFIAPI Mtftp4RrqInput(IN NET_BUF *UdpPacket, IN UDP_END_POINT *EndPoint, IN EFI_STATUS IoStatus, IN VOID *Context)
EFI_STATUS Mtftp4RrqSendAck(IN MTFTP4_PROTOCOL *Instance, IN UINT16 BlkNo)
EFI_STATUS Mtftp4InitBlockRange(IN LIST_ENTRY *Head, IN UINT16 Start, IN UINT16 End)
VOID Mtftp4SetLastBlockNum(IN LIST_ENTRY *Head, IN UINT16 Last)
EFI_STATUS Mtftp4SendRequest(IN MTFTP4_PROTOCOL *Instance)
VOID Mtftp4SetTimeout(IN OUT MTFTP4_PROTOCOL *Instance)
INTN Mtftp4GetNextBlockNum(IN LIST_ENTRY *Head)
EFI_STATUS Mtftp4SendError(IN MTFTP4_PROTOCOL *Instance, IN UINT16 ErrCode, IN UINT8 *ErrInfo)
EFI_STATUS Mtftp4RemoveBlockNum(IN LIST_ENTRY *Head, IN UINT16 Num, IN BOOLEAN Completed, OUT UINT64 *BlockCounter)
EFI_STATUS Mtftp4SendPacket(IN OUT MTFTP4_PROTOCOL *Instance, IN OUT NET_BUF *Packet)
VOID EFIAPI NetbufFree(IN NET_BUF *Nbuf)
UINT32 EFIAPI NetbufCopy(IN NET_BUF *Nbuf, IN UINT32 Offset, IN UINT32 Len, IN UINT8 *Dest)
NET_BUF *EFIAPI NetbufAlloc(IN UINT32 Len)
UINT8 *EFIAPI NetbufAllocSpace(IN OUT NET_BUF *Nbuf, IN UINT32 Len, IN BOOLEAN FromHead)
UINT8 *EFIAPI NetbufGetByte(IN NET_BUF *Nbuf, IN UINT32 Offset, OUT UINT32 *Index OPTIONAL)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
EFI_STATUS EFIAPI UdpIoRecvDatagram(IN UDP_IO *UdpIo, IN UDP_IO_CALLBACK CallBack, IN VOID *Context, IN UINT32 HeadLen)
EFI_STATUS EFIAPI UdpIoFreeIo(IN UDP_IO *UdpIo)
UDP_IO *EFIAPI UdpIoCreateIo(IN EFI_HANDLE Controller, IN EFI_HANDLE ImageHandle, IN UDP_IO_CONFIG Configure, IN UINT8 UdpVersion, IN VOID *Context)
EFI_MTFTP4_CHECK_PACKET CheckPacket
EFI_MTFTP4_ACK_HEADER Ack