25#define IP4_ADDR_TO_STRING(IpAddr, IpAddrString) UnicodeSPrint ( \
40#define RX_FRAGMENT_SIZE 2048
54#define NUM_RX_TOKENS 16
55#define TOKEN_NEXT(Index) (((Index) + 1) % NUM_RX_TOKENS)
100 ASSERT (FragmentBuffer !=
NULL);
101 if (FragmentBuffer ==
NULL) {
102 DEBUG ((DEBUG_ERROR,
"TCP Fastboot out of resources"));
103 return EFI_OUT_OF_RESOURCES;
106 mRxData[mNextSubmitIndex].DataLength = RX_FRAGMENT_SIZE;
107 mRxData[mNextSubmitIndex].FragmentTable[0].FragmentLength = RX_FRAGMENT_SIZE;
108 mRxData[mNextSubmitIndex].FragmentTable[0].FragmentBuffer = FragmentBuffer;
110 Status = mTcpConnection->Receive (mTcpConnection, &mReceiveToken[mNextSubmitIndex]);
111 if (EFI_ERROR (Status)) {
112 DEBUG ((DEBUG_ERROR,
"TCP Receive: %r\n", Status));
116 mNextSubmitIndex = TOKEN_NEXT (mNextSubmitIndex);
137 Status = mTcpConnection->Configure (mTcpConnection,
NULL);
139 mTcpConnection =
NULL;
141 Status = mTcpListener->Accept (mTcpListener, &mAcceptToken);
142 if (EFI_ERROR (Status)) {
143 DEBUG ((DEBUG_ERROR,
"TCP Accept: %r\n", Status));
155 for (Index = 0; Index < NUM_RX_TOKENS; Index++) {
156 gBS->CloseEvent (mReceiveToken[Index].CompletionToken.Event);
175 ReceiveToken = &mReceiveToken[mNextReceiveIndex];
184 CloseReceiveEvents ();
186 Status = mTcpConnection->Close (mTcpConnection, &mCloseToken);
197 if (NewEntry ==
NULL) {
198 DEBUG ((DEBUG_ERROR,
"TCP Fastboot: Out of resources\n"));
202 mNextReceiveIndex = TOKEN_NEXT (mNextReceiveIndex);
204 if (!EFI_ERROR (Status)) {
206 = ReceiveToken->Packet.
RxData->FragmentTable[0].FragmentBuffer;
208 = ReceiveToken->Packet.
RxData->FragmentTable[0].FragmentLength;
211 SubmitRecieveToken ();
215 NewEntry->Buffer =
NULL;
216 NewEntry->BufferSize = 0;
218 DEBUG ((DEBUG_ERROR,
"\nTCP Fastboot Receive error: %r\n", Status));
223 Status =
gBS->SignalEvent (mReceiveEvent);
243 Status = AcceptToken->CompletionToken.Status;
245 if (EFI_ERROR (Status)) {
246 DEBUG ((DEBUG_ERROR,
"TCP Fastboot: Connection Error: %r\n", Status));
250 DEBUG ((DEBUG_ERROR,
"TCP Fastboot: Connection Received.\n"));
257 Status =
gBS->OpenProtocol (
258 AcceptToken->NewChildHandle,
259 &gEfiTcp4ProtocolGuid,
260 (VOID **)&mTcpConnection,
263 EFI_OPEN_PROTOCOL_GET_PROTOCOL
265 if (EFI_ERROR (Status)) {
266 DEBUG ((DEBUG_ERROR,
"Open TCP Connection: %r\n", Status));
270 mNextSubmitIndex = 0;
271 mNextReceiveIndex = 0;
273 for (Index = 0; Index < NUM_RX_TOKENS; Index++) {
274 Status =
gBS->CreateEvent (
279 &(mReceiveToken[Index].CompletionToken.Event)
284 for (Index = 0; Index < NUM_RX_TOKENS; Index++) {
285 SubmitRecieveToken ();
294TcpFastbootTransportStart (
303 CHAR16 IpAddrString[16];
327 mReceiveEvent = ReceiveEvent;
330 mTextOut->OutputString (mTextOut, L
"Initialising TCP Fastboot transport...\r\n");
336 Status =
gBS->LocateHandleBuffer (
338 &gEfiTcp4ServiceBindingProtocolGuid,
343 if (EFI_ERROR (Status)) {
344 DEBUG ((DEBUG_ERROR,
"Find TCP Service Binding: %r\n", Status));
349 NetDeviceHandle = HandleBuffer[0];
351 Status =
gBS->OpenProtocol (
353 &gEfiTcp4ServiceBindingProtocolGuid,
354 (VOID **)&mTcpServiceBinding,
357 EFI_OPEN_PROTOCOL_GET_PROTOCOL
359 if (EFI_ERROR (Status)) {
360 DEBUG ((DEBUG_ERROR,
"Open TCP Service Binding: %r\n", Status));
364 Status = mTcpServiceBinding->CreateChild (mTcpServiceBinding, &mTcpHandle);
365 if (EFI_ERROR (Status)) {
366 DEBUG ((DEBUG_ERROR,
"TCP ServiceBinding Create: %r\n", Status));
370 Status =
gBS->OpenProtocol (
372 &gEfiTcp4ProtocolGuid,
373 (VOID **)&mTcpListener,
376 EFI_OPEN_PROTOCOL_GET_PROTOCOL
378 if (EFI_ERROR (Status)) {
379 DEBUG ((DEBUG_ERROR,
"Open TCP Protocol: %r\n", Status));
386 for (Index = 0; Index < NUM_RX_TOKENS; Index++) {
387 mRxData[Index].UrgentFlag =
FALSE;
388 mRxData[Index].FragmentCount = 1;
389 mReceiveToken[Index].Packet.
RxData = &mRxData[Index];
393 mTxData.Urgent =
FALSE;
394 mTxData.FragmentCount = 1;
395 mTransmitToken.Packet.
TxData = &mTxData;
397 Status =
gBS->CreateEvent (
402 &mAcceptToken.CompletionToken.Event
406 Status =
gBS->CreateEvent (
411 &mCloseToken.CompletionToken.Event
419 Status = mTcpListener->Configure (mTcpListener, &TcpConfigData);
420 if (Status == EFI_NO_MAPPING) {
423 Status = mTcpListener->GetModeData (
434 Status = mTcpListener->Configure (mTcpListener, &TcpConfigData);
435 }
else if (EFI_ERROR (Status)) {
436 DEBUG ((DEBUG_ERROR,
"TCP Configure: %r\n", Status));
445 mTextOut->OutputString (mTextOut, L
"TCP Fastboot transport configured.");
446 mTextOut->OutputString (mTextOut, L
"\r\nIP address: ");
447 mTextOut->OutputString (mTextOut, IpAddrString);
448 mTextOut->OutputString (mTextOut, L
"\r\n");
454 Status = mTcpListener->Accept (mTcpListener, &mAcceptToken);
455 if (EFI_ERROR (Status)) {
456 DEBUG ((DEBUG_ERROR,
"TCP Accept: %r\n", Status));
460 mTextOut->OutputString (mTextOut, L
"TCP Fastboot transport initialised.\r\n");
468TcpFastbootTransportStop (
479 if (mTcpConnection !=
NULL) {
480 CloseReceiveEvents ();
482 CloseToken.AbortOnClose =
FALSE;
484 Status =
gBS->CreateEvent (0, 0,
NULL,
NULL, &CloseToken.CompletionToken.Event);
487 Status = mTcpConnection->Close (mTcpConnection, &CloseToken);
490 Status =
gBS->WaitForEvent (
492 &CloseToken.CompletionToken.Event,
503 Status = mTcpConnection->Configure (mTcpConnection,
NULL);
507 gBS->CloseEvent (mAcceptToken.CompletionToken.Event);
512 Status = mTcpListener->Configure (mTcpListener,
NULL);
515 Status = mTcpServiceBinding->DestroyChild (mTcpServiceBinding, mTcpHandle);
519 while (!
IsNull (&mPacketListHead, &Entry->Link)) {
551 if (EFI_ERROR (Status)) {
552 DEBUG ((DEBUG_ERROR,
"TCP Fastboot transmit result: %r\n", Status));
556 FreePool (mTransmitToken.Packet.
TxData->FragmentTable[0].FragmentBuffer);
560TcpFastbootTransportSend (
568 if (BufferSize > 512) {
569 return EFI_INVALID_PARAMETER;
578 Status =
gBS->CreateEvent (
587 mTxData.DataLength = BufferSize;
589 mTxData.FragmentTable[0].FragmentLength = BufferSize;
595 Status = mTcpConnection->Transmit (mTcpConnection, &mTransmitToken);
596 if (EFI_ERROR (Status)) {
597 DEBUG ((DEBUG_ERROR,
"TCP Transmit: %r\n", Status));
605TcpFastbootTransportReceive (
613 return EFI_NOT_READY;
618 if (Entry->Buffer ==
NULL) {
620 return EFI_DEVICE_ERROR;
623 *Buffer = Entry->Buffer;
624 *BufferSize = Entry->BufferSize;
633 TcpFastbootTransportStart,
634 TcpFastbootTransportStop,
635 TcpFastbootTransportSend,
636 TcpFastbootTransportReceive
640TcpFastbootTransportEntryPoint (
647 Status =
gBS->LocateProtocol (
648 &gEfiSimpleTextOutProtocolGuid,
652 if (EFI_ERROR (Status)) {
653 DEBUG ((DEBUG_ERROR,
"Fastboot: Open Text Output Protocol: %r\n", Status));
657 Status =
gBS->InstallProtocolInterface (
659 &gAndroidFastbootTransportProtocolGuid,
663 if (EFI_ERROR (Status)) {
664 DEBUG ((DEBUG_ERROR,
"Fastboot: Install transport Protocol: %r\n", Status));
BOOLEAN EFIAPI IsNull(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
BOOLEAN EFIAPI IsListEmpty(IN CONST LIST_ENTRY *ListHead)
LIST_ENTRY *EFIAPI GetNextNode(IN CONST LIST_ENTRY *List, IN CONST LIST_ENTRY *Node)
LIST_ENTRY *EFIAPI GetFirstNode(IN CONST LIST_ENTRY *List)
LIST_ENTRY *EFIAPI RemoveEntryList(IN CONST LIST_ENTRY *Entry)
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
LIST_ENTRY *EFIAPI InsertTailList(IN OUT LIST_ENTRY *ListHead, IN OUT LIST_ENTRY *Entry)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define FixedPcdGet32(TokenName)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
#define EFI_CONNECTION_FIN
EFI_IPv4_ADDRESS StationAddress
EFI_IP4_CONFIG_DATA ConfigData
EFI_TCP4_COMPLETION_TOKEN CompletionToken
EFI_TCP4_TRANSMIT_DATA * TxData
EFI_TCP4_RECEIVE_DATA * RxData