75 return EFI_OUT_OF_RESOURCES;
132 if (Range->Start > Last) {
138 if (Range->End > Last) {
163 IN BOOLEAN Completed,
164 OUT UINT64 *BlockCounter
171 NET_LIST_FOR_EACH (Entry, Head) {
178 if (Range->End < Num) {
198 if (Range->Start > Num) {
199 return EFI_NOT_FOUND;
200 }
else if (Range->Start == Num) {
213 if (Range->Round > 0) {
214 *BlockCounter += Range->Bound +
MultU64x32 (Range->Round - 1, (UINT32)(Range->Bound + 1)) + 1;
217 if (Range->Start > Range->Bound) {
222 if ((Range->Start > Range->End) || Completed) {
229 if (Range->End == Num) {
234 if (NewRange ==
NULL) {
235 return EFI_OUT_OF_RESOURCES;
238 Range->End = Num - 1;
246 return EFI_NOT_FOUND;
273 Udp6 = UdpIo->Protocol.Udp6;
278 Status =
gBS->CreateEvent (
285 if (EFI_ERROR (Status)) {
289 Status =
gBS->SetTimer (
292 MTFTP6_GET_MAPPING_TIMEOUT * MTFTP6_TICK_PER_SECOND
294 if (EFI_ERROR (Status)) {
301 while (EFI_ERROR (
gBS->CheckEvent (Event))) {
304 Status = Udp6->GetModeData (Udp6,
NULL, &Ip6Mode,
NULL,
NULL);
306 if (!EFI_ERROR (Status)) {
335 Status = Udp6->Configure (Udp6, UdpCfgData);
337 Status = EFI_NO_MAPPING;
345 gBS->CloseEvent (Event);
388 IN UINT16 ServerPort,
397 Udp6 = UdpIo->Protocol.Udp6;
398 Udp6Cfg = &(UdpIo->Config.Udp6);
430 Status = Udp6->Configure (Udp6, Udp6Cfg);
432 if (Status == EFI_NO_MAPPING) {
459 RETURN_STATUS Status;
465 UINTN FileNameLength;
467 UINTN OptionStrLength;
468 UINTN ValueStrLength;
470 Token = Instance->Token;
475 Mode = (UINT8 *)
"octet";
499 BufferLength = (UINT32)FileNameLength + (UINT32)ModeLength + 4;
501 for (Index = 0; Index < Token->
OptionCount; Index++) {
502 OptionStrLength =
AsciiStrLen ((CHAR8 *)Options[Index].OptionStr);
503 ValueStrLength =
AsciiStrLen ((CHAR8 *)Options[Index].ValueStr);
504 BufferLength += (UINT32)OptionStrLength + (UINT32)ValueStrLength + 2;
511 return EFI_OUT_OF_RESOURCES;
518 ASSERT (Packet !=
NULL);
520 Packet->
OpCode = HTONS (Operation);
521 BufferLength -=
sizeof (Packet->
OpCode);
526 BufferLength -= (UINT32)(FileNameLength + 1);
527 Cur += FileNameLength + 1;
528 Status =
AsciiStrCpyS ((CHAR8 *)Cur, BufferLength, (CHAR8 *)Mode);
530 BufferLength -= (UINT32)(ModeLength + 1);
531 Cur += ModeLength + 1;
536 for (Index = 0; Index < Token->
OptionCount; ++Index) {
537 OptionStrLength =
AsciiStrLen ((CHAR8 *)Options[Index].OptionStr);
538 ValueStrLength =
AsciiStrLen ((CHAR8 *)Options[Index].ValueStr);
540 Status =
AsciiStrCpyS ((CHAR8 *)Cur, BufferLength, (CHAR8 *)Options[Index].OptionStr);
542 BufferLength -= (UINT32)(OptionStrLength + 1);
543 Cur += OptionStrLength + 1;
545 Status =
AsciiStrCpyS ((CHAR8 *)Cur, BufferLength, (CHAR8 *)Options[Index].ValueStr);
547 BufferLength -= (UINT32)(ValueStrLength + 1);
548 Cur += ValueStrLength + 1;
554 if (Instance->LastPacket !=
NULL) {
558 Instance->LastPacket = Nbuf;
559 Instance->CurRetry = 0;
594 return EFI_OUT_OF_RESOURCES;
599 if (TftpError ==
NULL) {
601 return EFI_OUT_OF_RESOURCES;
612 if (Instance->LastPacket !=
NULL) {
616 Instance->LastPacket = Nbuf;
617 Instance->CurRetry = 0;
641 *(BOOLEAN *)Context =
TRUE;
668 Udp6 = Instance->UdpIo->Protocol.Udp6;
673 Instance->PacketToLive = Instance->IsMaster ? Instance->Timeout : (Instance->Timeout * 2);
676 ASSERT (Temp !=
NULL);
679 OpCode = NTOHS (Value);
687 Status = Udp6->Configure (Udp6,
NULL);
689 if (EFI_ERROR (Status)) {
696 Instance->ServerCmdPort,
697 &Instance->Config->StationIp,
698 Instance->Config->LocalPort
701 if (EFI_ERROR (Status)) {
708 Status = Udp6->GetModeData (Udp6, &Udp6CfgData,
NULL,
NULL,
NULL);
709 if (EFI_ERROR (Status)) {
713 NET_GET_REF (Packet);
715 Instance->IsTransmitted =
FALSE;
723 &Instance->IsTransmitted
726 if (EFI_ERROR (Status)) {
727 NET_PUT_REF (Packet);
734 gBS->RestoreTPL (Instance->OldTpl);
736 while (!Instance->IsTransmitted) {
740 Instance->OldTpl =
gBS->RaiseTPL (TPL_CALLBACK);
747 Status = Udp6->Configure (Udp6,
NULL);
749 if (EFI_ERROR (Status)) {
756 Instance->ServerDataPort,
766 Status = Udp6->GetModeData (Udp6, &Udp6CfgData,
NULL,
NULL,
NULL);
767 if (EFI_ERROR (Status)) {
771 if (Udp6CfgData.
RemotePort != Instance->ServerDataPort) {
772 Status = Udp6->Configure (Udp6,
NULL);
774 if (EFI_ERROR (Status)) {
781 Instance->ServerDataPort,
786 if (EFI_ERROR (Status)) {
791 NET_GET_REF (Packet);
793 Instance->IsTransmitted =
FALSE;
801 &Instance->IsTransmitted
804 if (EFI_ERROR (Status)) {
805 NET_PUT_REF (Packet);
811 gBS->RestoreTPL (Instance->OldTpl);
813 while (!Instance->IsTransmitted) {
817 Instance->OldTpl =
gBS->RaiseTPL (TPL_CALLBACK);
850 OpCode = NTOHS (Packet->OpCode);
857 Context->Status = EFI_TFTP_ERROR;
865 Context->Status = EFI_PROTOCOL_ERROR;
874 if (*(Context->Packet) ==
NULL) {
875 Context->Status = EFI_OUT_OF_RESOURCES;
879 *(Context->PacketLen) = PacketLen;
880 CopyMem (*(Context->Packet), Packet, PacketLen);
905 if (Instance->Token !=
NULL) {
906 Instance->Token->Status = Result;
907 if (Instance->Token->Event !=
NULL) {
908 gBS->SignalEvent (Instance->Token->Event);
911 Instance->Token =
NULL;
917 if (Instance->UdpIo !=
NULL) {
921 if (Instance->McastUdpIo !=
NULL) {
923 Instance->McastUdpIo->UdpHandle,
924 &gEfiUdp6ProtocolGuid,
925 Instance->McastUdpIo->Image,
929 Instance->McastUdpIo =
NULL;
935 if (Instance->LastPacket !=
NULL) {
937 Instance->LastPacket =
NULL;
940 NET_LIST_FOR_EACH_SAFE (Entry, Next, &Instance->BlkList) {
953 Instance->ServerCmdPort = 0;
954 Instance->ServerDataPort = 0;
955 Instance->McastPort = 0;
956 Instance->BlkSize = 0;
957 Instance->Operation = 0;
958 Instance->WindowSize = 1;
959 Instance->TotalBlock = 0;
960 Instance->AckedBlock = 0;
961 Instance->LastBlk = 0;
962 Instance->PacketToLive = 0;
963 Instance->MaxRetry = 0;
964 Instance->CurRetry = 0;
965 Instance->Timeout = 0;
966 Instance->IsMaster =
TRUE;
993 if ((This ==
NULL) ||
995 (Token->Filename ==
NULL) ||
996 ((Token->OptionCount != 0) && (Token->OptionList ==
NULL)) ||
1000 return EFI_INVALID_PARAMETER;
1007 (Token->Buffer ==
NULL) &&
1008 (Token->CheckPacket ==
NULL)
1011 return EFI_INVALID_PARAMETER;
1018 return EFI_INVALID_PARAMETER;
1021 Instance = MTFTP6_INSTANCE_FROM_THIS (This);
1023 if (Instance->Config ==
NULL) {
1024 return EFI_NOT_STARTED;
1027 if (Instance->Token !=
NULL) {
1028 return EFI_ACCESS_DENIED;
1032 Instance->OldTpl =
gBS->RaiseTPL (TPL_CALLBACK);
1034 Instance->Operation = OpCode;
1039 if (Token->OptionCount != 0) {
1044 Instance->Operation,
1048 if (EFI_ERROR (Status)) {
1056 Instance->Token = Token;
1058 Instance->ServerDataPort = 0;
1059 Instance->MaxRetry = Instance->Config->
TryCount;
1061 Instance->IsMaster =
TRUE;
1064 &Instance->ServerIp,
1069 if (Token->OverrideData !=
NULL) {
1070 Instance->ServerCmdPort = Token->OverrideData->ServerPort;
1071 Instance->MaxRetry = Token->OverrideData->TryCount;
1072 Instance->Timeout = Token->OverrideData->TimeoutValue;
1075 &Instance->ServerIp,
1076 &Token->OverrideData->ServerIp,
1084 if (Instance->ServerCmdPort == 0) {
1085 Instance->ServerCmdPort = MTFTP6_DEFAULT_SERVER_CMD_PORT;
1088 if (Instance->BlkSize == 0) {
1089 Instance->BlkSize = MTFTP6_DEFAULT_BLK_SIZE;
1092 if (Instance->WindowSize == 0) {
1093 Instance->WindowSize = MTFTP6_DEFAULT_WINDOWSIZE;
1096 if (Instance->MaxRetry == 0) {
1097 Instance->MaxRetry = MTFTP6_DEFAULT_MAX_RETRY;
1100 if (Instance->Timeout == 0) {
1101 Instance->Timeout = MTFTP6_DEFAULT_TIMEOUT;
1104 Token->Status = EFI_NOT_READY;
1123 Status = EFI_DEVICE_ERROR;
1127 if (EFI_ERROR (Status)) {
1134 gBS->RestoreTPL (Instance->OldTpl);
1136 if (Token->Event ==
NULL) {
1137 while (Token->Status == EFI_NOT_READY) {
1141 return Token->Status;
1149 gBS->RestoreTPL (Instance->OldTpl);
1181 NET_LIST_FOR_EACH_SAFE (Entry, Next, &Service->Children) {
1184 if (Instance->Token ==
NULL) {
1188 if (Instance->PacketToLive > 0) {
1189 Instance->PacketToLive--;
1193 Instance->CurRetry++;
1194 Token = Instance->Token;
1202 if (EFI_ERROR (Status)) {
1206 (UINT8 *)
"User aborted the transfer in time out"
1217 if (Instance->CurRetry < Instance->MaxRetry) {
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
UINT64 EFIAPI MultU64x32(IN UINT64 Multiplicand, IN UINT32 Multiplier)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
RETURN_STATUS EFIAPI AsciiStrCpyS(OUT CHAR8 *Destination, IN UINTN DestMax, IN CONST CHAR8 *Source)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define ASSERT_EFI_ERROR(StatusParameter)
#define EFI_MTFTP6_OPCODE_ERROR
The MTFTPv6 packet is an error packet.
#define EFI_MTFTP6_OPCODE_OACK
The MTFTPv6 packet is an option acknowledgement packet.
#define EFI_MTFTP6_OPCODE_WRQ
The MTFTPv6 packet is a write request.
#define EFI_MTFTP6_OPCODE_RRQ
The MTFTPv6 packet is a read request.
#define EFI_MTFTP6_ERRORCODE_REQUEST_DENIED
#define EFI_MTFTP6_OPCODE_DIR
The MTFTPv6 packet is a directory query packet.
EFI_STATUS Mtftp6ParseExtensionOption(IN EFI_MTFTP6_OPTION *Options, IN UINT32 Count, IN BOOLEAN IsRequest, IN UINT16 Operation, IN MTFTP6_EXT_OPTION_INFO *ExtInfo)
EFI_STATUS Mtftp6RrqStart(IN MTFTP6_INSTANCE *Instance, IN UINT16 Operation)
EFI_STATUS Mtftp6RemoveBlockNum(IN LIST_ENTRY *Head, IN UINT16 Num, IN BOOLEAN Completed, OUT UINT64 *BlockCounter)
EFI_STATUS Mtftp6SendError(IN MTFTP6_INSTANCE *Instance, IN UINT16 ErrCode, IN UINT8 *ErrInfo)
EFI_STATUS EFIAPI Mtftp6CheckPacket(IN EFI_MTFTP6_PROTOCOL *This, IN EFI_MTFTP6_TOKEN *Token, IN UINT16 PacketLen, IN EFI_MTFTP6_PACKET *Packet)
EFI_STATUS Mtftp6GetMapping(IN UDP_IO *UdpIo, IN EFI_UDP6_CONFIG_DATA *UdpCfgData)
EFI_STATUS EFIAPI Mtftp6ConfigDummyUdpIo(IN UDP_IO *UdpIo, IN VOID *Context)
EFI_STATUS Mtftp6TransmitPacket(IN MTFTP6_INSTANCE *Instance, IN NET_BUF *Packet)
EFI_STATUS Mtftp6SendRequest(IN MTFTP6_INSTANCE *Instance, IN UINT16 Operation)
INTN Mtftp6GetNextBlockNum(IN LIST_ENTRY *Head)
VOID EFIAPI Mtftp6OnPacketSent(IN NET_BUF *Packet, IN UDP_END_POINT *UdpEpt, IN EFI_STATUS IoStatus, IN VOID *Context)
EFI_STATUS Mtftp6InitBlockRange(IN LIST_ENTRY *Head, IN UINT16 Start, IN UINT16 End)
MTFTP6_BLOCK_RANGE * Mtftp6AllocateRange(IN UINT16 Start, IN UINT16 End)
EFI_STATUS Mtftp6OperationStart(IN EFI_MTFTP6_PROTOCOL *This, IN EFI_MTFTP6_TOKEN *Token, IN UINT16 OpCode)
VOID Mtftp6SetLastBlockNum(IN LIST_ENTRY *Head, IN UINT16 Last)
VOID EFIAPI Mtftp6OnTimerTick(IN EFI_EVENT Event, IN VOID *Context)
VOID Mtftp6OperationClean(IN MTFTP6_INSTANCE *Instance, IN EFI_STATUS Result)
EFI_STATUS Mtftp6ConfigUdpIo(IN UDP_IO *UdpIo, IN EFI_IPv6_ADDRESS *ServerIp, IN UINT16 ServerPort, IN EFI_IPv6_ADDRESS *LocalIp, IN UINT16 LocalPort)
EFI_STATUS Mtftp6WrqStart(IN MTFTP6_INSTANCE *Instance, IN UINT16 Operation)
VOID EFIAPI NetbufFree(IN NET_BUF *Nbuf)
BOOLEAN EFIAPI NetIp6IsValidUnicast(IN EFI_IPv6_ADDRESS *Ip6)
VOID EFIAPI NetListInsertAfter(IN OUT LIST_ENTRY *PrevEntry, IN OUT LIST_ENTRY *NewEntry)
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 UdpIoCleanIo(IN UDP_IO *UdpIo)
EFI_STATUS EFIAPI UdpIoSendDatagram(IN UDP_IO *UdpIo, IN NET_BUF *Packet, IN UDP_END_POINT *EndPoint OPTIONAL, IN EFI_IP_ADDRESS *Gateway OPTIONAL, IN UDP_IO_CALLBACK CallBack, IN VOID *Context)
EFI_STATUS EFIAPI UdpIoFreeIo(IN UDP_IO *UdpIo)
EFI_MTFTP6_TIMEOUT_CALLBACK TimeoutCallback
EFI_MTFTP6_OPTION * OptionList
EFI_IP6_NEIGHBOR_CACHE * NeighborCache
EFI_IP6_ICMP_TYPE * IcmpTypeList
EFI_IP6_ADDRESS_INFO * AddressList
EFI_IP6_ROUTE_TABLE * RouteTable
EFI_IPv6_ADDRESS * GroupTable
EFI_IP6_ADDRESS_INFO * PrefixTable
EFI_IPv6_ADDRESS ServerIp
BOOLEAN AcceptPromiscuous
BOOLEAN AllowDuplicatePort
EFI_IPv6_ADDRESS RemoteAddress
EFI_IPv6_ADDRESS StationAddress
EFI_MTFTP6_REQ_HEADER Rrq
Read request packet header.
EFI_MTFTP6_ERROR_HEADER Error
Error packet header.
UINT16 OpCode
Type of packets as defined by the MTFTPv6 packet opcodes.