3 Copyright (c) 2005 - 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
24 Get the length of the data that can be retrieved from the socket
27 @param SockBuffer Pointer to the socket receive buffer.
28 @param IsUrg Pointer to a BOOLEAN variable. If TRUE the data is
30 @param BufLen The maximum length of the data buffer to store the
31 received data in socket layer.
33 @return The length of the data can be retreived.
38 IN SOCK_BUFFER
*SockBuffer
,
44 Process the send token.
46 @param Sock Pointer to the socket.
68 Get the length of the data that can be retrieved from the socket
71 @param SockBuffer Pointer to the socket receive buffer.
72 @param IsUrg Pointer to a BOOLEAN variable. If TRUE the data is
74 @param BufLen The maximum length of the data buffer to store the
75 received data in socket layer.
77 @return The length of the data can be retreived.
82 IN SOCK_BUFFER
*SockBuffer
,
89 TCP_RSV_DATA
*TcpRsvData
;
92 ASSERT ((SockBuffer
!= NULL
) && (IsUrg
!= NULL
) && (BufLen
> 0));
94 RcvBufEntry
= SockBufFirst (SockBuffer
);
95 ASSERT (RcvBufEntry
!= NULL
);
97 TcpRsvData
= (TCP_RSV_DATA
*) RcvBufEntry
->ProtoData
;
99 *IsUrg
= (BOOLEAN
) ((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
101 if (*IsUrg
&& TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
) {
103 DataLen
= MIN (TcpRsvData
->UrgLen
, BufLen
);
105 if (DataLen
< TcpRsvData
->UrgLen
) {
106 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- DataLen
;
108 TcpRsvData
->UrgLen
= 0;
115 DataLen
= RcvBufEntry
->TotalSize
;
117 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
119 while ((BufLen
> DataLen
) && (RcvBufEntry
!= NULL
)) {
121 TcpRsvData
= (TCP_RSV_DATA
*) RcvBufEntry
->ProtoData
;
123 Urg
= (BOOLEAN
) ((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
129 if (*IsUrg
&& TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
) {
131 if (TcpRsvData
->UrgLen
+ DataLen
< BufLen
) {
132 TcpRsvData
->UrgLen
= 0;
134 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- (BufLen
- DataLen
);
137 return MIN (TcpRsvData
->UrgLen
+ DataLen
, BufLen
);
141 DataLen
+= RcvBufEntry
->TotalSize
;
143 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
146 DataLen
= MIN (BufLen
, DataLen
);
152 Copy data from socket buffer to application provided receive buffer.
154 @param Sock Pointer to the socket.
155 @param TcpRxData Pointer to the application provided receive buffer.
156 @param RcvdBytes The maximum length of the data can be copied.
157 @param IsOOB If TURE the data is OOB, else the data is normal.
171 EFI_TCP4_RECEIVE_DATA
*RxData
;
172 EFI_TCP4_FRAGMENT_DATA
*Fragment
;
174 RxData
= (EFI_TCP4_RECEIVE_DATA
*) TcpRxData
;
178 ASSERT (RxData
->DataLength
>= RcvdBytes
);
180 RxData
->DataLength
= RcvdBytes
;
181 RxData
->UrgentFlag
= IsOOB
;
183 for (Index
= 0; (Index
< RxData
->FragmentCount
) && (RcvdBytes
> 0); Index
++) {
185 Fragment
= &RxData
->FragmentTable
[Index
];
186 CopyBytes
= MIN ((UINT32
) (Fragment
->FragmentLength
), RcvdBytes
);
189 Sock
->RcvBuffer
.DataQueue
,
192 Fragment
->FragmentBuffer
195 Fragment
->FragmentLength
= CopyBytes
;
196 RcvdBytes
-= CopyBytes
;
203 Get received data from the socket layer to the receive token.
205 @param Sock Pointer to the socket.
206 @param RcvToken Pointer to the application provided receive token.
208 @return The length of data received in this token.
212 SockProcessRcvToken (
214 IN SOCK_IO_TOKEN
*RcvToken
217 UINT32 TokenRcvdBytes
;
218 EFI_TCP4_RECEIVE_DATA
*RxData
;
221 ASSERT (Sock
!= NULL
);
223 ASSERT (SOCK_STREAM
== Sock
->Type
);
225 RxData
= RcvToken
->Packet
.RxData
;
227 TokenRcvdBytes
= SockTcpDataToRcv (
230 (UINT32
) RxData
->DataLength
234 // Copy data from RcvBuffer of socket to user
235 // provided RxData and set the fields in TCP RxData
237 SockSetTcpRxData (Sock
, RxData
, TokenRcvdBytes
, IsUrg
);
239 SOCK_TRIM_RCV_BUFF (Sock
, TokenRcvdBytes
);
240 SIGNAL_TOKEN (&(RcvToken
->Token
), EFI_SUCCESS
);
242 return TokenRcvdBytes
;
247 Process the TCP send data, buffer the tcp txdata and append
248 the buffer to socket send buffer,then try to send it.
250 @param Sock Pointer to the socket.
251 @param TcpTxData Pointer to the tcp txdata.
253 @retval EFI_SUCCESS The operation is completed successfully.
254 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
258 SockProcessTcpSndData (
265 EFI_TCP4_TRANSMIT_DATA
*TxData
;
267 TxData
= (EFI_TCP4_TRANSMIT_DATA
*) TcpTxData
;
270 // transform this TxData into a NET_BUFFER
271 // and insert it into Sock->SndBuffer
273 SndData
= NetbufFromExt (
274 (NET_FRAGMENT
*) TxData
->FragmentTable
,
275 (UINT32
) TxData
->FragmentCount
,
282 if (NULL
== SndData
) {
283 DEBUG ((EFI_D_ERROR
, "SockKProcessSndData: Failed to"
284 " call NetBufferFromExt\n"));
286 return EFI_OUT_OF_RESOURCES
;
289 NetbufQueAppend (Sock
->SndBuffer
.DataQueue
, SndData
);
292 // notify the low layer protocol to handle this send token
294 if (TxData
->Urgent
) {
295 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDURG
, NULL
);
297 if (EFI_ERROR (Status
)) {
303 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDPUSH
, NULL
);
305 if (EFI_ERROR (Status
)) {
311 // low layer protocol should really handle the sending
312 // process when catching SOCK_SND request
314 Status
= Sock
->ProtoHandler (Sock
, SOCK_SND
, NULL
);
316 if (EFI_ERROR (Status
)) {
325 Flush the tokens in the specific token list.
327 @param Sock Pointer to the socket.
328 @param PendingTokenList Pointer to the token list to be flushed.
332 SockFlushPendingToken (
334 IN LIST_ENTRY
*PendingTokenList
337 SOCK_TOKEN
*SockToken
;
338 SOCK_COMPLETION_TOKEN
*Token
;
340 ASSERT ((Sock
!= NULL
) && (PendingTokenList
!= NULL
));
342 while (!IsListEmpty (PendingTokenList
)) {
343 SockToken
= NET_LIST_HEAD (
349 Token
= SockToken
->Token
;
350 SIGNAL_TOKEN (Token
, Sock
->SockError
);
352 RemoveEntryList (&(SockToken
->TokenList
));
353 gBS
->FreePool (SockToken
);
359 Wake up the connection token while the connection is successfully established,
360 then try to process any pending send token.
362 @param Sock Pointer to the socket.
370 ASSERT (Sock
->ConnectionToken
!= NULL
);
372 SIGNAL_TOKEN (Sock
->ConnectionToken
, EFI_SUCCESS
);
373 Sock
->ConnectionToken
= NULL
;
376 // check to see if some pending send token existed?
378 SockProcessSndToken (Sock
);
384 Wake up the listen token while the connection is established successfully.
386 @param Sock Pointer to the socket.
390 SockWakeListenToken (
395 SOCK_TOKEN
*SockToken
;
396 EFI_TCP4_LISTEN_TOKEN
*ListenToken
;
398 Parent
= Sock
->Parent
;
400 ASSERT ((Parent
!= NULL
) && SOCK_IS_LISTENING (Parent
) && SOCK_IS_CONNECTED (Sock
));
402 if (!IsListEmpty (&Parent
->ListenTokenList
)) {
403 SockToken
= NET_LIST_HEAD (
404 &Parent
->ListenTokenList
,
409 ListenToken
= (EFI_TCP4_LISTEN_TOKEN
*) SockToken
->Token
;
410 ListenToken
->NewChildHandle
= Sock
->SockHandle
;
412 SIGNAL_TOKEN (&(ListenToken
->CompletionToken
), EFI_SUCCESS
);
414 RemoveEntryList (&SockToken
->TokenList
);
415 gBS
->FreePool (SockToken
);
417 RemoveEntryList (&Sock
->ConnectionList
);
420 DEBUG ((EFI_D_WARN
, "SockWakeListenToken: accept a socket, now conncnt is %d", Parent
->ConnCnt
));
428 Wake up the receive token while some data is received.
430 @param Sock Pointer to the socket.
439 UINT32 TokenRcvdBytes
;
440 SOCK_TOKEN
*SockToken
;
441 SOCK_IO_TOKEN
*RcvToken
;
443 ASSERT (Sock
->RcvBuffer
.DataQueue
!= NULL
);
445 RcvdBytes
= (Sock
->RcvBuffer
.DataQueue
)->BufSize
;
447 ASSERT (RcvdBytes
> 0);
449 while (RcvdBytes
> 0 && !IsListEmpty (&Sock
->RcvTokenList
)) {
451 SockToken
= NET_LIST_HEAD (
457 RcvToken
= (SOCK_IO_TOKEN
*) SockToken
->Token
;
458 TokenRcvdBytes
= SockProcessRcvToken (Sock
, RcvToken
);
460 if (0 == TokenRcvdBytes
) {
464 RemoveEntryList (&(SockToken
->TokenList
));
465 gBS
->FreePool (SockToken
);
466 RcvdBytes
-= TokenRcvdBytes
;
472 Process the send token.
474 @param Sock Pointer to the socket.
478 SockProcessSndToken (
483 SOCK_TOKEN
*SockToken
;
485 SOCK_IO_TOKEN
*SndToken
;
486 EFI_TCP4_TRANSMIT_DATA
*TxData
;
489 ASSERT ((Sock
!= NULL
) && (SOCK_STREAM
== Sock
->Type
));
491 FreeSpace
= SockGetFreeSpace (Sock
, SOCK_SND_BUF
);
494 // to determine if process a send token using
495 // socket layer flow control policy
497 while ((FreeSpace
>= Sock
->SndBuffer
.LowWater
) &&
498 !IsListEmpty (&Sock
->SndTokenList
)) {
500 SockToken
= NET_LIST_HEAD (
501 &(Sock
->SndTokenList
),
507 // process this token
509 RemoveEntryList (&(SockToken
->TokenList
));
511 &(Sock
->ProcessingSndTokenList
),
512 &(SockToken
->TokenList
)
516 // Proceess it in the light of SockType
518 SndToken
= (SOCK_IO_TOKEN
*) SockToken
->Token
;
519 TxData
= SndToken
->Packet
.TxData
;
521 DataLen
= (UINT32
) TxData
->DataLength
;
522 Status
= SockProcessTcpSndData (Sock
, TxData
);
524 if (EFI_ERROR (Status
)) {
528 if (DataLen
>= FreeSpace
) {
532 FreeSpace
-= DataLen
;
541 RemoveEntryList (&SockToken
->TokenList
);
542 SIGNAL_TOKEN (SockToken
->Token
, Status
);
543 gBS
->FreePool (SockToken
);
548 Create a socket with initial data SockInitData.
550 @param SockInitData Pointer to the initial data of the socket.
552 @return Pointer to the newly created socket.
557 IN SOCK_INIT_DATA
*SockInitData
564 ASSERT ((SockInitData
!= NULL
) && (SockInitData
->ProtoHandler
!= NULL
));
565 ASSERT (SockInitData
->Type
== SOCK_STREAM
);
566 ASSERT ((SockInitData
->ProtoData
!= NULL
) && (SockInitData
->DataSize
<= PROTO_RESERVED_LEN
));
568 Parent
= SockInitData
->Parent
;
570 if ((Parent
!= NULL
) && (Parent
->ConnCnt
== Parent
->BackLog
)) {
573 "SockCreate: Socket parent has "
574 "reached its connection limit with %d ConnCnt and %d BackLog\n",
582 Sock
= AllocateZeroPool (sizeof (SOCKET
));
585 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to create a new socket\n"));
589 InitializeListHead (&Sock
->Link
);
590 InitializeListHead (&Sock
->ConnectionList
);
591 InitializeListHead (&Sock
->ListenTokenList
);
592 InitializeListHead (&Sock
->RcvTokenList
);
593 InitializeListHead (&Sock
->SndTokenList
);
594 InitializeListHead (&Sock
->ProcessingSndTokenList
);
596 EfiInitializeLock (&(Sock
->Lock
), TPL_CALLBACK
);
598 Sock
->SndBuffer
.DataQueue
= NetbufQueAlloc ();
599 if (NULL
== Sock
->SndBuffer
.DataQueue
) {
600 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to allocate"
601 " SndBuffer for new socket\n"));
606 Sock
->RcvBuffer
.DataQueue
= NetbufQueAlloc ();
607 if (NULL
== Sock
->RcvBuffer
.DataQueue
) {
608 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to allocate "
609 "RcvBuffer for new socket\n"));
614 Sock
->Signature
= SOCK_SIGNATURE
;
616 Sock
->Parent
= Parent
;
617 Sock
->BackLog
= SockInitData
->BackLog
;
618 Sock
->ProtoHandler
= SockInitData
->ProtoHandler
;
619 Sock
->SndBuffer
.HighWater
= SockInitData
->SndBufferSize
;
620 Sock
->RcvBuffer
.HighWater
= SockInitData
->RcvBufferSize
;
621 Sock
->Type
= SockInitData
->Type
;
622 Sock
->DriverBinding
= SockInitData
->DriverBinding
;
623 Sock
->State
= SockInitData
->State
;
624 Sock
->CreateCallback
= SockInitData
->CreateCallback
;
625 Sock
->DestroyCallback
= SockInitData
->DestroyCallback
;
626 Sock
->Context
= SockInitData
->Context
;
628 Sock
->SockError
= EFI_ABORTED
;
629 Sock
->SndBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
630 Sock
->RcvBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
633 // Install protocol on Sock->SockHandle
636 &(Sock
->NetProtocol
.TcpProtocol
),
637 SockInitData
->Protocol
,
638 sizeof (EFI_TCP4_PROTOCOL
)
642 // copy the protodata into socket
644 CopyMem (Sock
->ProtoReserved
, SockInitData
->ProtoData
, SockInitData
->DataSize
);
646 Status
= gBS
->InstallMultipleProtocolInterfaces (
648 &gEfiTcp4ProtocolGuid
,
649 &(Sock
->NetProtocol
.TcpProtocol
),
653 if (EFI_ERROR (Status
)) {
654 DEBUG ((EFI_D_ERROR
, "SockCreate: Install TCP protocol in "
655 "socket failed with %r\n", Status
));
660 if (Parent
!= NULL
) {
661 ASSERT (Parent
->BackLog
> 0);
662 ASSERT (SOCK_IS_LISTENING (Parent
));
665 // need to add it into Parent->ConnectionList
666 // if the Parent->ConnCnt < Parent->BackLog
672 "SockCreate: Create a new socket and add to parent, now conncnt is %d\n",
676 InsertTailList (&Parent
->ConnectionList
, &Sock
->ConnectionList
);
679 if (Sock
->CreateCallback
!= NULL
) {
680 Status
= Sock
->CreateCallback (Sock
, Sock
->Context
);
681 if (EFI_ERROR (Status
)) {
690 if (Sock
->SockHandle
!= NULL
) {
691 gBS
->UninstallMultipleProtocolInterfaces (
693 &gEfiTcp4ProtocolGuid
,
694 &(Sock
->NetProtocol
.TcpProtocol
),
699 if (NULL
!= Sock
->SndBuffer
.DataQueue
) {
700 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
703 if (NULL
!= Sock
->RcvBuffer
.DataQueue
) {
704 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
707 gBS
->FreePool (Sock
);
716 @param Sock Pointer to the socket.
725 EFI_GUID
*ProtocolGuid
;
728 ASSERT (SOCK_STREAM
== Sock
->Type
);
730 if (Sock
->DestroyCallback
!= NULL
) {
731 Sock
->DestroyCallback (Sock
, Sock
->Context
);
735 // Flush the completion token buffered
736 // by sock and rcv, snd buffer
738 if (!SOCK_IS_UNCONFIGURED (Sock
)) {
740 SockConnFlush (Sock
);
741 SockSetState (Sock
, SO_CLOSED
);
742 Sock
->ConfigureState
= SO_UNCONFIGURED
;
746 // Destory the RcvBuffer Queue and SendBuffer Queue
748 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
749 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
752 // Remove it from parent connection list if needed
754 if (Sock
->Parent
!= NULL
) {
756 RemoveEntryList (&(Sock
->ConnectionList
));
757 (Sock
->Parent
->ConnCnt
)--;
761 "SockDestory: Delete a unaccepted socket from parent"
762 "now conncnt is %d\n",
763 Sock
->Parent
->ConnCnt
)
770 // Set the protocol guid and driver binding handle
771 // in the light of Sock->SockType
773 ProtocolGuid
= &gEfiTcp4ProtocolGuid
;
776 // Retrieve the protocol installed on this sock
778 Status
= gBS
->OpenProtocol (
784 EFI_OPEN_PROTOCOL_GET_PROTOCOL
787 if (EFI_ERROR (Status
)) {
789 DEBUG ((EFI_D_ERROR
, "SockDestroy: Open protocol installed "
790 "on socket failed with %r\n", Status
));
796 // Uninstall the protocol installed on this sock
797 // in the light of Sock->SockType
799 gBS
->UninstallMultipleProtocolInterfaces (
807 gBS
->FreePool (Sock
);
815 @param Sock Pointer to the socket.
825 ASSERT (Sock
!= NULL
);
828 // Clear the flag in this socket
833 // Flush the SndBuffer and RcvBuffer of Sock
835 NetbufQueFlush (Sock
->SndBuffer
.DataQueue
);
836 NetbufQueFlush (Sock
->RcvBuffer
.DataQueue
);
839 // Signal the pending token
841 if (Sock
->ConnectionToken
!= NULL
) {
842 SIGNAL_TOKEN (Sock
->ConnectionToken
, Sock
->SockError
);
843 Sock
->ConnectionToken
= NULL
;
846 if (Sock
->CloseToken
!= NULL
) {
847 SIGNAL_TOKEN (Sock
->CloseToken
, Sock
->SockError
);
848 Sock
->CloseToken
= NULL
;
851 SockFlushPendingToken (Sock
, &(Sock
->ListenTokenList
));
852 SockFlushPendingToken (Sock
, &(Sock
->RcvTokenList
));
853 SockFlushPendingToken (Sock
, &(Sock
->SndTokenList
));
854 SockFlushPendingToken (Sock
, &(Sock
->ProcessingSndTokenList
));
857 // Destroy the pending connection, if it is a listening socket
859 if (SOCK_IS_LISTENING (Sock
)) {
860 while (!IsListEmpty (&Sock
->ConnectionList
)) {
861 Child
= NET_LIST_HEAD (
862 &Sock
->ConnectionList
,
867 SockDestroyChild (Child
);
878 Set the state of the socket.
880 @param Sock Pointer to the socket.
881 @param State The new state to be set.
895 Clone a new socket including its associated protocol control block.
897 @param Sock Pointer to the socket to be cloned.
899 @return Pointer to the newly cloned socket. If NULL, error condition occurred.
908 SOCK_INIT_DATA InitData
;
910 InitData
.BackLog
= Sock
->BackLog
;
911 InitData
.Parent
= Sock
;
912 InitData
.State
= Sock
->State
;
913 InitData
.ProtoHandler
= Sock
->ProtoHandler
;
914 InitData
.Type
= Sock
->Type
;
915 InitData
.RcvBufferSize
= Sock
->RcvBuffer
.HighWater
;
916 InitData
.SndBufferSize
= Sock
->SndBuffer
.HighWater
;
917 InitData
.DriverBinding
= Sock
->DriverBinding
;
918 InitData
.Protocol
= &(Sock
->NetProtocol
);
919 InitData
.CreateCallback
= Sock
->CreateCallback
;
920 InitData
.DestroyCallback
= Sock
->DestroyCallback
;
921 InitData
.Context
= Sock
->Context
;
922 InitData
.ProtoData
= Sock
->ProtoReserved
;
923 InitData
.DataSize
= sizeof (Sock
->ProtoReserved
);
925 ClonedSock
= SockCreate (&InitData
);
927 if (NULL
== ClonedSock
) {
928 DEBUG ((EFI_D_ERROR
, "SockClone: no resource to create a cloned sock\n"));
932 SockSetState (ClonedSock
, SO_CONNECTING
);
933 ClonedSock
->ConfigureState
= Sock
->ConfigureState
;
940 Called by the low layer protocol to indicate the socket a connection is
941 established. This function just changes the socket's state to SO_CONNECTED
942 and signals the token used for connection establishment.
944 @param Sock Pointer to the socket associated with the
945 established connection.
948 SockConnEstablished (
953 ASSERT (SO_CONNECTING
== Sock
->State
);
955 SockSetState (Sock
, SO_CONNECTED
);
957 if (NULL
== Sock
->Parent
) {
958 SockWakeConnToken (Sock
);
960 SockWakeListenToken (Sock
);
968 Called by the low layer protocol to indicate the connection is closed; This
969 function flushes the socket, sets the state to SO_CLOSED and signals the close
972 @param Sock Pointer to the socket associated with the closed
980 if (Sock
->CloseToken
!= NULL
) {
981 SIGNAL_TOKEN (Sock
->CloseToken
, EFI_SUCCESS
);
982 Sock
->CloseToken
= NULL
;
985 SockConnFlush (Sock
);
986 SockSetState (Sock
, SO_CLOSED
);
988 if (Sock
->Parent
!= NULL
) {
989 SockDestroyChild (Sock
);
996 Called by low layer protocol to indicate that some data is sent or processed;
997 This function trims the sent data in the socket send buffer, signals the data
1000 @param Sock Pointer to the socket.
1001 @param Count The length of the data processed or sent, in bytes.
1010 SOCK_TOKEN
*SockToken
;
1011 SOCK_COMPLETION_TOKEN
*SndToken
;
1013 ASSERT (!IsListEmpty (&Sock
->ProcessingSndTokenList
));
1014 ASSERT (Count
<= (Sock
->SndBuffer
.DataQueue
)->BufSize
);
1016 NetbufQueTrim (Sock
->SndBuffer
.DataQueue
, Count
);
1019 // To check if we can signal some snd token in this socket
1022 SockToken
= NET_LIST_HEAD (
1023 &(Sock
->ProcessingSndTokenList
),
1028 SndToken
= SockToken
->Token
;
1030 if (SockToken
->RemainDataLen
<= Count
) {
1032 RemoveEntryList (&(SockToken
->TokenList
));
1033 SIGNAL_TOKEN (SndToken
, EFI_SUCCESS
);
1034 Count
-= SockToken
->RemainDataLen
;
1035 gBS
->FreePool (SockToken
);
1038 SockToken
->RemainDataLen
-= Count
;
1044 // to judge if we can process some send token in
1045 // Sock->SndTokenList, if so process those send token
1047 SockProcessSndToken (Sock
);
1053 Called by the low layer protocol to copy some data in socket send
1054 buffer starting from the specific offset to a buffer provided by
1057 @param Sock Pointer to the socket.
1058 @param Offset The start point of the data to be copied.
1059 @param Len The length of the data to be copied.
1060 @param Dest Pointer to the destination to copy the data.
1062 @return The data size copied.
1073 ASSERT ((Sock
!= NULL
) && SOCK_STREAM
== Sock
->Type
);
1075 return NetbufQueCopy (
1076 Sock
->SndBuffer
.DataQueue
,
1085 Called by the low layer protocol to deliver received data to socket layer;
1086 This function will append the data to the socket receive buffer, set ther
1087 urgent data length and then check if any receive token can be signaled.
1089 @param Sock Pointer to the socket.
1090 @param NetBuffer Pointer to the buffer that contains the received
1092 @param UrgLen The length of the urgent data in the received data.
1098 IN NET_BUF
*NetBuffer
,
1102 ASSERT ((Sock
!= NULL
) && (Sock
->RcvBuffer
.DataQueue
!= NULL
) &&
1103 UrgLen
<= NetBuffer
->TotalSize
);
1105 NET_GET_REF (NetBuffer
);
1107 ((TCP_RSV_DATA
*) (NetBuffer
->ProtoData
))->UrgLen
= UrgLen
;
1109 NetbufQueAppend (Sock
->RcvBuffer
.DataQueue
, NetBuffer
);
1111 SockWakeRcvToken (Sock
);
1117 Get the length of the free space of the specific socket buffer.
1119 @param Sock Pointer to the socket.
1120 @param Which Flag to indicate which socket buffer to check,
1121 either send buffer or receive buffer.
1123 @return The length of the free space, in bytes.
1133 SOCK_BUFFER
*SockBuffer
;
1135 ASSERT ((Sock
!= NULL
) && ((SOCK_SND_BUF
== Which
) || (SOCK_RCV_BUF
== Which
)));
1137 if (SOCK_SND_BUF
== Which
) {
1138 SockBuffer
= &(Sock
->SndBuffer
);
1140 SockBuffer
= &(Sock
->RcvBuffer
);
1143 BufferCC
= (SockBuffer
->DataQueue
)->BufSize
;
1145 if (BufferCC
>= SockBuffer
->HighWater
) {
1150 return SockBuffer
->HighWater
- BufferCC
;
1155 Signal the receive token with the specific error or
1156 set socket error code after error is received.
1158 @param Sock Pointer to the socket.
1159 @param Error The error code received.
1168 SOCK_TOKEN
*SockToken
;
1170 if (!IsListEmpty (&Sock
->RcvTokenList
)) {
1172 SockToken
= NET_LIST_HEAD (
1173 &Sock
->RcvTokenList
,
1178 RemoveEntryList (&SockToken
->TokenList
);
1180 SIGNAL_TOKEN (SockToken
->Token
, Error
);
1182 gBS
->FreePool (SockToken
);
1185 SOCK_ERROR (Sock
, Error
);
1191 Called by the low layer protocol to indicate that there
1192 will be no more data from the communication peer; This
1193 function set the socket's state to SO_NO_MORE_DATA and
1194 signal all queued IO tokens with the error status
1197 @param Sock Pointer to the socket.
1207 SOCK_NO_MORE_DATA (Sock
);
1209 if (!IsListEmpty (&Sock
->RcvTokenList
)) {
1211 ASSERT (0 == GET_RCV_DATASIZE (Sock
));
1213 Err
= Sock
->SockError
;
1215 SOCK_ERROR (Sock
, EFI_CONNECTION_FIN
);
1217 SockFlushPendingToken (Sock
, &Sock
->RcvTokenList
);
1219 SOCK_ERROR (Sock
, Err
);
1227 Get the first buffer block in the specific socket buffer.
1229 @param Sockbuf Pointer to the socket buffer.
1231 @return Pointer to the first buffer in the queue. NULL if the queue is empty.
1236 IN SOCK_BUFFER
*Sockbuf
1239 LIST_ENTRY
*NetbufList
;
1241 NetbufList
= &(Sockbuf
->DataQueue
->BufList
);
1243 if (IsListEmpty (NetbufList
)) {
1247 return NET_LIST_HEAD (NetbufList
, NET_BUF
, List
);
1252 Get the next buffer block in the specific socket buffer.
1254 @param Sockbuf Pointer to the socket buffer.
1255 @param SockEntry Pointer to the buffer block prior to the required
1258 @return Pointer to the buffer block next to SockEntry. NULL if SockEntry is
1259 the tail or head entry.
1264 IN SOCK_BUFFER
*Sockbuf
,
1265 IN NET_BUF
*SockEntry
1268 LIST_ENTRY
*NetbufList
;
1270 NetbufList
= &(Sockbuf
->DataQueue
->BufList
);
1272 if ((SockEntry
->List
.ForwardLink
== NetbufList
) ||
1273 (SockEntry
->List
.BackLink
== &SockEntry
->List
) ||
1274 (SockEntry
->List
.ForwardLink
== &SockEntry
->List
)) {
1279 return NET_LIST_USER_STRUCT (SockEntry
->List
.ForwardLink
, NET_BUF
, List
);