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.
26 IN SOCK_BUFFER
*SockBuffer
,
47 Get the length of the data that can be retrieved from the socket
50 @param SockBuffer Pointer to the socket receive buffer.
51 @param IsUrg Pointer to a BOOLEAN variable. If TRUE the data is
53 @param BufLen The maximum length of the data buffer to store the
54 received data in socket layer.
56 @return The length of the data can be retreived.
62 IN SOCK_BUFFER
*SockBuffer
,
69 TCP_RSV_DATA
*TcpRsvData
;
72 ASSERT (SockBuffer
&& IsUrg
&& (BufLen
> 0));
74 RcvBufEntry
= SockBufFirst (SockBuffer
);
77 TcpRsvData
= (TCP_RSV_DATA
*) RcvBufEntry
->ProtoData
;
79 *IsUrg
= ((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
81 if (*IsUrg
&& TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
) {
83 DataLen
= NET_MIN (TcpRsvData
->UrgLen
, BufLen
);
85 if (DataLen
< TcpRsvData
->UrgLen
) {
86 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- DataLen
;
88 TcpRsvData
->UrgLen
= 0;
95 DataLen
= RcvBufEntry
->TotalSize
;
97 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
99 while ((BufLen
> DataLen
) && (RcvBufEntry
!= NULL
)) {
101 TcpRsvData
= (TCP_RSV_DATA
*) RcvBufEntry
->ProtoData
;
103 Urg
= ((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
109 if (*IsUrg
&& TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
) {
111 if (TcpRsvData
->UrgLen
+ DataLen
< BufLen
) {
112 TcpRsvData
->UrgLen
= 0;
114 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- (BufLen
- DataLen
);
117 return NET_MIN (TcpRsvData
->UrgLen
+ DataLen
, BufLen
);
121 DataLen
+= RcvBufEntry
->TotalSize
;
123 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
126 DataLen
= NET_MIN (BufLen
, DataLen
);
132 Copy data from socket buffer to application provided receive buffer.
134 @param Sock Pointer to the socket.
135 @param TcpRxData Pointer to the application provided receive buffer.
136 @param RcvdBytes The maximum length of the data can be copied.
137 @param IsOOB If TURE the data is OOB, else the data is normal.
153 EFI_TCP4_RECEIVE_DATA
*RxData
;
154 EFI_TCP4_FRAGMENT_DATA
*Fragment
;
156 RxData
= (EFI_TCP4_RECEIVE_DATA
*) TcpRxData
;
160 ASSERT (RxData
->DataLength
>= RcvdBytes
);
162 RxData
->DataLength
= RcvdBytes
;
163 RxData
->UrgentFlag
= IsOOB
;
165 for (Index
= 0; (Index
< RxData
->FragmentCount
) && (RcvdBytes
> 0); Index
++) {
167 Fragment
= &RxData
->FragmentTable
[Index
];
168 CopyBytes
= NET_MIN (Fragment
->FragmentLength
, RcvdBytes
);
171 Sock
->RcvBuffer
.DataQueue
,
174 Fragment
->FragmentBuffer
177 Fragment
->FragmentLength
= CopyBytes
;
178 RcvdBytes
-= CopyBytes
;
185 Get received data from the socket layer to the receive token.
187 @param Sock Pointer to the socket.
188 @param RcvToken Pointer to the application provided receive token.
190 @return The length of data received in this token.
194 SockProcessRcvToken (
196 IN SOCK_IO_TOKEN
*RcvToken
199 UINT32 TokenRcvdBytes
;
200 EFI_TCP4_RECEIVE_DATA
*RxData
;
205 ASSERT (SOCK_STREAM
== Sock
->Type
);
207 RxData
= RcvToken
->Packet
.RxData
;
209 TokenRcvdBytes
= SockTcpDataToRcv (
216 // Copy data from RcvBuffer of socket to user
217 // provided RxData and set the fields in TCP RxData
219 SockSetTcpRxData (Sock
, RxData
, TokenRcvdBytes
, IsUrg
);
221 SOCK_TRIM_RCV_BUFF (Sock
, TokenRcvdBytes
);
222 SIGNAL_TOKEN (&(RcvToken
->Token
), EFI_SUCCESS
);
224 return TokenRcvdBytes
;
229 Process the TCP send data, buffer the tcp txdata and append
230 the buffer to socket send buffer,then try to send it.
232 @param Sock Pointer to the socket.
233 @param TcpTxData Pointer to the tcp txdata.
235 @retval EFI_SUCCESS The operation is completed successfully.
236 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
240 SockProcessTcpSndData (
247 EFI_TCP4_TRANSMIT_DATA
*TxData
;
249 TxData
= (EFI_TCP4_TRANSMIT_DATA
*) TcpTxData
;
252 // transform this TxData into a NET_BUFFER
253 // and insert it into Sock->SndBuffer
255 SndData
= NetbufFromExt (
256 (NET_FRAGMENT
*) TxData
->FragmentTable
,
257 TxData
->FragmentCount
,
264 if (NULL
== SndData
) {
265 SOCK_DEBUG_ERROR (("SockKProcessSndData: Failed to"
266 " call NetBufferFromExt\n"));
268 return EFI_OUT_OF_RESOURCES
;
271 NetbufQueAppend (Sock
->SndBuffer
.DataQueue
, SndData
);
274 // notify the low layer protocol to handle this send token
276 if (TxData
->Urgent
) {
277 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDURG
, NULL
);
279 if (EFI_ERROR (Status
)) {
285 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDPUSH
, NULL
);
287 if (EFI_ERROR (Status
)) {
293 // low layer protocol should really handle the sending
294 // process when catching SOCK_SND request
296 Status
= Sock
->ProtoHandler (Sock
, SOCK_SND
, NULL
);
298 if (EFI_ERROR (Status
)) {
307 Flush the tokens in the specific token list.
309 @param Sock Pointer to the socket.
310 @param PendingTokenList Pointer to the token list to be flushed.
317 SockFlushPendingToken (
319 IN NET_LIST_ENTRY
*PendingTokenList
322 SOCK_TOKEN
*SockToken
;
323 SOCK_COMPLETION_TOKEN
*Token
;
325 ASSERT (Sock
&& PendingTokenList
);
327 while (!NetListIsEmpty (PendingTokenList
)) {
328 SockToken
= NET_LIST_HEAD (
334 Token
= SockToken
->Token
;
335 SIGNAL_TOKEN (Token
, Sock
->SockError
);
337 NetListRemoveEntry (&(SockToken
->TokenList
));
338 NetFreePool (SockToken
);
344 Wake up the connection token while the connection is
345 successfully established, then try to process any
348 @param Sock Pointer to the socket.
359 ASSERT (Sock
->ConnectionToken
!= NULL
);
361 SIGNAL_TOKEN (Sock
->ConnectionToken
, EFI_SUCCESS
);
362 Sock
->ConnectionToken
= NULL
;
365 // check to see if some pending send token existed?
367 SockProcessSndToken (Sock
);
373 Wake up the listen token while the connection is
374 established successfully.
376 @param Sock Pointer to the socket.
383 SockWakeListenToken (
388 SOCK_TOKEN
*SockToken
;
389 EFI_TCP4_LISTEN_TOKEN
*ListenToken
;
391 Parent
= Sock
->Parent
;
393 ASSERT (Parent
&& SOCK_IS_LISTENING (Parent
) && SOCK_IS_CONNECTED (Sock
));
395 if (!NetListIsEmpty (&Parent
->ListenTokenList
)) {
396 SockToken
= NET_LIST_HEAD (
397 &Parent
->ListenTokenList
,
402 ListenToken
= (EFI_TCP4_LISTEN_TOKEN
*) SockToken
->Token
;
403 ListenToken
->NewChildHandle
= Sock
->SockHandle
;
405 SIGNAL_TOKEN (&(ListenToken
->CompletionToken
), EFI_SUCCESS
);
407 NetListRemoveEntry (&SockToken
->TokenList
);
408 NetFreePool (SockToken
);
410 NetListRemoveEntry (&Sock
->ConnectionList
);
413 SOCK_DEBUG_WARN (("SockWakeListenToken: accept a socket,"
414 "now conncnt is %d", Parent
->ConnCnt
));
422 Wake up the receive token while some data is received.
424 @param Sock Pointer to the socket.
436 UINT32 TokenRcvdBytes
;
437 SOCK_TOKEN
*SockToken
;
438 SOCK_IO_TOKEN
*RcvToken
;
440 ASSERT (Sock
->RcvBuffer
.DataQueue
);
442 RcvdBytes
= (Sock
->RcvBuffer
.DataQueue
)->BufSize
;
444 ASSERT (RcvdBytes
> 0);
446 while (RcvdBytes
> 0 && !NetListIsEmpty (&Sock
->RcvTokenList
)) {
448 SockToken
= NET_LIST_HEAD (
454 RcvToken
= (SOCK_IO_TOKEN
*) SockToken
->Token
;
455 TokenRcvdBytes
= SockProcessRcvToken (Sock
, RcvToken
);
457 if (0 == TokenRcvdBytes
) {
461 NetListRemoveEntry (&(SockToken
->TokenList
));
462 NetFreePool (SockToken
);
463 RcvdBytes
-= TokenRcvdBytes
;
469 Process the send token.
471 @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
&& (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 !NetListIsEmpty (&Sock
->SndTokenList
)) {
500 SockToken
= NET_LIST_HEAD (
501 &(Sock
->SndTokenList
),
507 // process this token
509 NetListRemoveEntry (&(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
= TxData
->DataLength
;
522 Status
= SockProcessTcpSndData (Sock
, TxData
);
524 if (EFI_ERROR (Status
)) {
528 if (DataLen
>= FreeSpace
) {
532 FreeSpace
-= DataLen
;
541 NetListRemoveEntry (&SockToken
->TokenList
);
542 SIGNAL_TOKEN (SockToken
->Token
, Status
);
543 NetFreePool (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
&& SockInitData
->ProtoHandler
);
565 ASSERT (SockInitData
->Type
== SOCK_STREAM
);
567 Parent
= SockInitData
->Parent
;
569 if (Parent
&& (Parent
->ConnCnt
== Parent
->BackLog
)) {
571 ("SockCreate: Socket parent has "
572 "reached its connection limit with %d ConnCnt and %d BackLog\n",
580 Sock
= NetAllocateZeroPool (sizeof (SOCKET
));
583 SOCK_DEBUG_ERROR (("SockCreate: No resource to create a new socket\n"));
587 NetListInit (&Sock
->ConnectionList
);
588 NetListInit (&Sock
->ListenTokenList
);
589 NetListInit (&Sock
->RcvTokenList
);
590 NetListInit (&Sock
->SndTokenList
);
591 NetListInit (&Sock
->ProcessingSndTokenList
);
593 NET_LOCK_INIT (&(Sock
->Lock
));
595 Sock
->SndBuffer
.DataQueue
= NetbufQueAlloc ();
596 if (NULL
== Sock
->SndBuffer
.DataQueue
) {
597 SOCK_DEBUG_ERROR (("SockCreate: No resource to allocate"
598 " SndBuffer for new socket\n"));
603 Sock
->RcvBuffer
.DataQueue
= NetbufQueAlloc ();
604 if (NULL
== Sock
->RcvBuffer
.DataQueue
) {
605 SOCK_DEBUG_ERROR (("SockCreate: No resource to allocate "
606 "RcvBuffer for new socket\n"));
611 Sock
->Signature
= SOCK_SIGNATURE
;
613 Sock
->Parent
= Parent
;
614 Sock
->BackLog
= SockInitData
->BackLog
;
615 Sock
->ProtoHandler
= SockInitData
->ProtoHandler
;
616 Sock
->SndBuffer
.HighWater
= SockInitData
->SndBufferSize
;
617 Sock
->RcvBuffer
.HighWater
= SockInitData
->RcvBufferSize
;
618 Sock
->Type
= SockInitData
->Type
;
619 Sock
->DriverBinding
= SockInitData
->DriverBinding
;
620 Sock
->State
= SockInitData
->State
;
622 Sock
->SockError
= EFI_ABORTED
;
623 Sock
->SndBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
624 Sock
->RcvBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
627 // Install protocol on Sock->SockHandle
630 &(Sock
->NetProtocol
.TcpProtocol
),
631 SockInitData
->Protocol
,
632 sizeof (EFI_TCP4_PROTOCOL
)
635 Status
= gBS
->InstallMultipleProtocolInterfaces (
637 &gEfiTcp4ProtocolGuid
,
638 &(Sock
->NetProtocol
.TcpProtocol
),
642 if (EFI_ERROR (Status
)) {
643 SOCK_DEBUG_ERROR (("SockCreate: Install TCP protocol in "
644 "socket failed with %r\n", Status
));
649 if (Parent
!= NULL
) {
650 ASSERT (Parent
->BackLog
> 0);
651 ASSERT (SOCK_IS_LISTENING (Parent
));
654 // need to add it into Parent->ConnectionList
655 // if the Parent->ConnCnt < Parent->BackLog
659 SOCK_DEBUG_WARN (("SockCreate: Create a new socket and"
660 "add to parent, now conncnt is %d\n", Parent
->ConnCnt
));
662 NetListInsertTail (&Parent
->ConnectionList
, &Sock
->ConnectionList
);
670 if (NULL
!= Sock
->SndBuffer
.DataQueue
) {
671 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
674 if (NULL
!= Sock
->RcvBuffer
.DataQueue
) {
675 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
688 @param Sock Pointer to the socket.
699 EFI_GUID
*ProtocolGuid
;
702 ASSERT (SOCK_STREAM
== Sock
->Type
);
705 // Flush the completion token buffered
706 // by sock and rcv, snd buffer
708 if (!SOCK_IS_UNCONFIGURED (Sock
)) {
710 SockConnFlush (Sock
);
711 SockSetState (Sock
, SO_CLOSED
);
712 Sock
->ConfigureState
= SO_UNCONFIGURED
;
716 // Destory the RcvBuffer Queue and SendBuffer Queue
718 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
719 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
722 // Remove it from parent connection list if needed
726 NetListRemoveEntry (&(Sock
->ConnectionList
));
727 (Sock
->Parent
->ConnCnt
)--;
729 SOCK_DEBUG_WARN (("SockDestory: Delete a unaccepted socket from parent"
730 "now conncnt is %d\n", Sock
->Parent
->ConnCnt
));
736 // Set the protocol guid and driver binding handle
737 // in the light of Sock->SockType
739 ProtocolGuid
= &gEfiTcp4ProtocolGuid
;
742 // Retrieve the protocol installed on this sock
744 Status
= gBS
->OpenProtocol (
750 EFI_OPEN_PROTOCOL_GET_PROTOCOL
753 if (EFI_ERROR (Status
)) {
755 SOCK_DEBUG_ERROR (("SockDestroy: Open protocol installed "
756 "on socket failed with %r\n", Status
));
762 // Uninstall the protocol installed on this sock
763 // in the light of Sock->SockType
765 gBS
->UninstallMultipleProtocolInterfaces (
781 @param Sock Pointer to the socket.
796 // Clear the flag in this socket
801 // Flush the SndBuffer and RcvBuffer of Sock
803 NetbufQueFlush (Sock
->SndBuffer
.DataQueue
);
804 NetbufQueFlush (Sock
->RcvBuffer
.DataQueue
);
807 // Signal the pending token
809 if (Sock
->ConnectionToken
!= NULL
) {
810 SIGNAL_TOKEN (Sock
->ConnectionToken
, Sock
->SockError
);
811 Sock
->ConnectionToken
= NULL
;
814 if (Sock
->CloseToken
!= NULL
) {
815 SIGNAL_TOKEN (Sock
->CloseToken
, Sock
->SockError
);
816 Sock
->CloseToken
= NULL
;
819 SockFlushPendingToken (Sock
, &(Sock
->ListenTokenList
));
820 SockFlushPendingToken (Sock
, &(Sock
->RcvTokenList
));
821 SockFlushPendingToken (Sock
, &(Sock
->SndTokenList
));
822 SockFlushPendingToken (Sock
, &(Sock
->ProcessingSndTokenList
));
825 // Destroy the pending connection, if it is a listening socket
827 if (SOCK_IS_LISTENING (Sock
)) {
828 while (!NetListIsEmpty (&Sock
->ConnectionList
)) {
829 Child
= NET_LIST_HEAD (
830 &Sock
->ConnectionList
,
835 SockDestroyChild (Child
);
846 Set the state of the socket.
848 @param Sock Pointer to the socket.
849 @param State The new state to be set.
865 Clone a new socket including its associated protocol control block.
867 @param Sock Pointer to the socket to be cloned.
869 @retval * Pointer to the newly cloned socket. If NULL, error
879 SOCK_INIT_DATA InitData
;
881 InitData
.BackLog
= Sock
->BackLog
;
882 InitData
.Parent
= Sock
;
883 InitData
.State
= Sock
->State
;
884 InitData
.ProtoHandler
= Sock
->ProtoHandler
;
885 InitData
.Type
= Sock
->Type
;
886 InitData
.RcvBufferSize
= Sock
->RcvBuffer
.HighWater
;
887 InitData
.SndBufferSize
= Sock
->SndBuffer
.HighWater
;
888 InitData
.DriverBinding
= Sock
->DriverBinding
;
889 InitData
.Protocol
= &(Sock
->NetProtocol
);
891 ClonedSock
= SockCreate (&InitData
);
893 if (NULL
== ClonedSock
) {
894 SOCK_DEBUG_ERROR (("SockClone: no resource to create a cloned sock\n"));
899 ClonedSock
->ProtoReserved
,
904 SockSetState (ClonedSock
, SO_CONNECTING
);
905 ClonedSock
->ConfigureState
= Sock
->ConfigureState
;
912 Called by the low layer protocol to indicate the socket
913 a connection is established. This function just changes
914 the socket's state to SO_CONNECTED and signals the token
915 used for connection establishment.
917 @param Sock Pointer to the socket associated with the
918 established connection.
924 SockConnEstablished (
929 ASSERT (SO_CONNECTING
== Sock
->State
);
931 SockSetState (Sock
, SO_CONNECTED
);
933 if (NULL
== Sock
->Parent
) {
934 SockWakeConnToken (Sock
);
936 SockWakeListenToken (Sock
);
944 Called by the low layer protocol to indicate the connection
945 is closed. This function flushes the socket, sets the state
946 to SO_CLOSED and signals the close token.
948 @param Sock Pointer to the socket associated with the closed
959 if (Sock
->CloseToken
) {
960 SIGNAL_TOKEN (Sock
->CloseToken
, EFI_SUCCESS
);
961 Sock
->CloseToken
= NULL
;
964 SockConnFlush (Sock
);
965 SockSetState (Sock
, SO_CLOSED
);
967 if (Sock
->Parent
!= NULL
) {
968 SockDestroyChild (Sock
);
975 Called by low layer protocol to indicate that some
976 data is sent or processed. This function trims the
977 sent data in the socket send buffer, signals the
980 @param Sock Pointer to the socket.
981 @param Count The length of the data processed or sent, in bytes.
992 SOCK_TOKEN
*SockToken
;
993 SOCK_COMPLETION_TOKEN
*SndToken
;
995 ASSERT (!NetListIsEmpty (&Sock
->ProcessingSndTokenList
));
996 ASSERT (Count
<= (Sock
->SndBuffer
.DataQueue
)->BufSize
);
998 NetbufQueTrim (Sock
->SndBuffer
.DataQueue
, Count
);
1001 // To check if we can signal some snd token in this socket
1004 SockToken
= NET_LIST_HEAD (
1005 &(Sock
->ProcessingSndTokenList
),
1010 SndToken
= SockToken
->Token
;
1012 if (SockToken
->RemainDataLen
<= Count
) {
1014 NetListRemoveEntry (&(SockToken
->TokenList
));
1015 SIGNAL_TOKEN (SndToken
, EFI_SUCCESS
);
1016 Count
-= SockToken
->RemainDataLen
;
1017 NetFreePool (SockToken
);
1020 SockToken
->RemainDataLen
-= Count
;
1026 // to judge if we can process some send token in
1027 // Sock->SndTokenList, if so process those send token
1029 SockProcessSndToken (Sock
);
1035 Called by the low layer protocol to copy some data in socket send
1036 buffer starting from the specific offset to a buffer provided by
1039 @param Sock Pointer to the socket.
1040 @param Offset The start point of the data to be copied.
1041 @param Len The length of the data to be copied.
1042 @param Dest Pointer to the destination to copy the data.
1044 @return The data size copied.
1055 ASSERT (Sock
&& SOCK_STREAM
== Sock
->Type
);
1057 return NetbufQueCopy (
1058 Sock
->SndBuffer
.DataQueue
,
1067 Called by the low layer protocol to deliver received data
1068 to socket layer. This function will append the data to the
1069 socket receive buffer, set ther urgent data length and then
1070 check if any receive token can be signaled.
1072 @param Sock Pointer to the socket.
1073 @param NetBuffer Pointer to the buffer that contains the received
1075 @param UrgLen The length of the urgent data in the received data.
1083 IN NET_BUF
*NetBuffer
,
1087 ASSERT (Sock
&& Sock
->RcvBuffer
.DataQueue
&&
1088 UrgLen
<= NetBuffer
->TotalSize
);
1090 NET_GET_REF (NetBuffer
);
1092 ((TCP_RSV_DATA
*) (NetBuffer
->ProtoData
))->UrgLen
= UrgLen
;
1094 NetbufQueAppend (Sock
->RcvBuffer
.DataQueue
, NetBuffer
);
1096 SockWakeRcvToken (Sock
);
1102 Get the length of the free space of the specific socket buffer.
1104 @param Sock Pointer to the socket.
1105 @param Which Flag to indicate which socket buffer to check,
1106 either send buffer or receive buffer.
1108 @return The length of the free space, in bytes.
1118 SOCK_BUFFER
*SockBuffer
;
1120 ASSERT (Sock
&& ((SOCK_SND_BUF
== Which
) || (SOCK_RCV_BUF
== Which
)));
1122 if (SOCK_SND_BUF
== Which
) {
1123 SockBuffer
= &(Sock
->SndBuffer
);
1125 SockBuffer
= &(Sock
->RcvBuffer
);
1128 BufferCC
= (SockBuffer
->DataQueue
)->BufSize
;
1130 if (BufferCC
>= SockBuffer
->HighWater
) {
1135 return SockBuffer
->HighWater
- BufferCC
;
1140 Signal the receive token with the specific error or
1141 set socket error code after error is received.
1143 @param Sock Pointer to the socket.
1144 @param Error The error code received.
1155 SOCK_TOKEN
*SockToken
;
1157 if (!NetListIsEmpty (&Sock
->RcvTokenList
)) {
1159 SockToken
= NET_LIST_HEAD (
1160 &Sock
->RcvTokenList
,
1165 NetListRemoveEntry (&SockToken
->TokenList
);
1167 SIGNAL_TOKEN (SockToken
->Token
, Error
);
1169 NetFreePool (SockToken
);
1172 SOCK_ERROR (Sock
, Error
);
1178 Called by the low layer protocol to indicate that there
1179 will be no more data from the communication peer. This
1180 function set the socket's state to SO_NO_MORE_DATA and
1181 signal all queued IO tokens with the error status
1184 @param Sock Pointer to the socket.
1196 SOCK_NO_MORE_DATA (Sock
);
1198 if (!NetListIsEmpty (&Sock
->RcvTokenList
)) {
1200 ASSERT (0 == GET_RCV_DATASIZE (Sock
));
1202 Err
= Sock
->SockError
;
1204 SOCK_ERROR (Sock
, EFI_CONNECTION_FIN
);
1206 SockFlushPendingToken (Sock
, &Sock
->RcvTokenList
);
1208 SOCK_ERROR (Sock
, Err
);
1216 Get the first buffer block in the specific socket buffer.
1218 @param Sockbuf Pointer to the socket buffer.
1220 @return Pointer to the first buffer in the queue. NULL if the queue is empty.
1225 IN SOCK_BUFFER
*Sockbuf
1228 NET_LIST_ENTRY
*NetbufList
;
1230 NetbufList
= &(Sockbuf
->DataQueue
->BufList
);
1232 if (NetListIsEmpty (NetbufList
)) {
1236 return NET_LIST_HEAD (NetbufList
, NET_BUF
, List
);
1241 Get the next buffer block in the specific socket buffer.
1243 @param Sockbuf Pointer to the socket buffer.
1244 @param SockEntry Pointer to the buffer block prior to the required
1247 @return Pointer to the buffer block next to SockEntry. NULL if SockEntry is the tail or head entry.
1252 IN SOCK_BUFFER
*Sockbuf
,
1253 IN NET_BUF
*SockEntry
1256 NET_LIST_ENTRY
*NetbufList
;
1258 NetbufList
= &(Sockbuf
->DataQueue
->BufList
);
1260 if ((SockEntry
->List
.ForwardLink
== NetbufList
) ||
1261 (SockEntry
->List
.BackLink
== &SockEntry
->List
) ||
1262 (SockEntry
->List
.ForwardLink
== &SockEntry
->List
)
1268 return NET_LIST_USER_STRUCT (SockEntry
->List
.ForwardLink
, NET_BUF
, List
);