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.
25 IN SOCK_BUFFER
*SockBuffer
,
45 Get the length of the data that can be retrieved from the socket
48 @param SockBuffer Pointer to the socket receive buffer.
49 @param IsUrg Pointer to a BOOLEAN variable. If TRUE the data is
51 @param BufLen The maximum length of the data buffer to store the
52 received data in socket layer.
54 @return The length of the data can be retreived.
59 IN SOCK_BUFFER
*SockBuffer
,
66 TCP_RSV_DATA
*TcpRsvData
;
69 ASSERT (SockBuffer
&& IsUrg
&& (BufLen
> 0));
71 RcvBufEntry
= SockBufFirst (SockBuffer
);
74 TcpRsvData
= (TCP_RSV_DATA
*) RcvBufEntry
->ProtoData
;
76 *IsUrg
= (BOOLEAN
) ((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
78 if (*IsUrg
&& TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
) {
80 DataLen
= MIN (TcpRsvData
->UrgLen
, BufLen
);
82 if (DataLen
< TcpRsvData
->UrgLen
) {
83 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- DataLen
;
85 TcpRsvData
->UrgLen
= 0;
92 DataLen
= RcvBufEntry
->TotalSize
;
94 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
96 while ((BufLen
> DataLen
) && (RcvBufEntry
!= NULL
)) {
98 TcpRsvData
= (TCP_RSV_DATA
*) RcvBufEntry
->ProtoData
;
100 Urg
= (BOOLEAN
) ((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
106 if (*IsUrg
&& TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
) {
108 if (TcpRsvData
->UrgLen
+ DataLen
< BufLen
) {
109 TcpRsvData
->UrgLen
= 0;
111 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- (BufLen
- DataLen
);
114 return MIN (TcpRsvData
->UrgLen
+ DataLen
, BufLen
);
118 DataLen
+= RcvBufEntry
->TotalSize
;
120 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
123 DataLen
= MIN (BufLen
, DataLen
);
129 Copy data from socket buffer to application provided receive buffer.
131 @param Sock Pointer to the socket.
132 @param TcpRxData Pointer to the application provided receive buffer.
133 @param RcvdBytes The maximum length of the data can be copied.
134 @param IsOOB If TURE the data is OOB, else the data is normal.
150 EFI_TCP4_RECEIVE_DATA
*RxData
;
151 EFI_TCP4_FRAGMENT_DATA
*Fragment
;
153 RxData
= (EFI_TCP4_RECEIVE_DATA
*) TcpRxData
;
157 ASSERT (RxData
->DataLength
>= RcvdBytes
);
159 RxData
->DataLength
= RcvdBytes
;
160 RxData
->UrgentFlag
= IsOOB
;
162 for (Index
= 0; (Index
< RxData
->FragmentCount
) && (RcvdBytes
> 0); Index
++) {
164 Fragment
= &RxData
->FragmentTable
[Index
];
165 CopyBytes
= MIN ((UINT32
) (Fragment
->FragmentLength
), RcvdBytes
);
168 Sock
->RcvBuffer
.DataQueue
,
171 Fragment
->FragmentBuffer
174 Fragment
->FragmentLength
= CopyBytes
;
175 RcvdBytes
-= CopyBytes
;
182 Get received data from the socket layer to the receive token.
184 @param Sock Pointer to the socket.
185 @param RcvToken Pointer to the application provided receive token.
187 @return The length of data received in this token.
191 SockProcessRcvToken (
193 IN SOCK_IO_TOKEN
*RcvToken
196 UINT32 TokenRcvdBytes
;
197 EFI_TCP4_RECEIVE_DATA
*RxData
;
202 ASSERT (SOCK_STREAM
== Sock
->Type
);
204 RxData
= RcvToken
->Packet
.RxData
;
206 TokenRcvdBytes
= SockTcpDataToRcv (
209 (UINT32
) RxData
->DataLength
213 // Copy data from RcvBuffer of socket to user
214 // provided RxData and set the fields in TCP RxData
216 SockSetTcpRxData (Sock
, RxData
, TokenRcvdBytes
, IsUrg
);
218 SOCK_TRIM_RCV_BUFF (Sock
, TokenRcvdBytes
);
219 SIGNAL_TOKEN (&(RcvToken
->Token
), EFI_SUCCESS
);
221 return TokenRcvdBytes
;
226 Process the TCP send data, buffer the tcp txdata and append
227 the buffer to socket send buffer,then try to send it.
229 @param Sock Pointer to the socket.
230 @param TcpTxData Pointer to the tcp txdata.
232 @retval EFI_SUCCESS The operation is completed successfully.
233 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
237 SockProcessTcpSndData (
244 EFI_TCP4_TRANSMIT_DATA
*TxData
;
246 TxData
= (EFI_TCP4_TRANSMIT_DATA
*) TcpTxData
;
249 // transform this TxData into a NET_BUFFER
250 // and insert it into Sock->SndBuffer
252 SndData
= NetbufFromExt (
253 (NET_FRAGMENT
*) TxData
->FragmentTable
,
254 (UINT32
) TxData
->FragmentCount
,
261 if (NULL
== SndData
) {
262 DEBUG ((EFI_D_ERROR
, "SockKProcessSndData: Failed to"
263 " call NetBufferFromExt\n"));
265 return EFI_OUT_OF_RESOURCES
;
268 NetbufQueAppend (Sock
->SndBuffer
.DataQueue
, SndData
);
271 // notify the low layer protocol to handle this send token
273 if (TxData
->Urgent
) {
274 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDURG
, NULL
);
276 if (EFI_ERROR (Status
)) {
282 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDPUSH
, NULL
);
284 if (EFI_ERROR (Status
)) {
290 // low layer protocol should really handle the sending
291 // process when catching SOCK_SND request
293 Status
= Sock
->ProtoHandler (Sock
, SOCK_SND
, NULL
);
295 if (EFI_ERROR (Status
)) {
304 Flush the tokens in the specific token list.
306 @param Sock Pointer to the socket.
307 @param PendingTokenList Pointer to the token list to be flushed.
313 SockFlushPendingToken (
315 IN LIST_ENTRY
*PendingTokenList
318 SOCK_TOKEN
*SockToken
;
319 SOCK_COMPLETION_TOKEN
*Token
;
321 ASSERT (Sock
&& PendingTokenList
);
323 while (!IsListEmpty (PendingTokenList
)) {
324 SockToken
= NET_LIST_HEAD (
330 Token
= SockToken
->Token
;
331 SIGNAL_TOKEN (Token
, Sock
->SockError
);
333 RemoveEntryList (&(SockToken
->TokenList
));
334 gBS
->FreePool (SockToken
);
340 Wake up the connection token while the connection is
341 successfully established, then try to process any
344 @param Sock Pointer to the socket.
354 ASSERT (Sock
->ConnectionToken
!= NULL
);
356 SIGNAL_TOKEN (Sock
->ConnectionToken
, EFI_SUCCESS
);
357 Sock
->ConnectionToken
= NULL
;
360 // check to see if some pending send token existed?
362 SockProcessSndToken (Sock
);
368 Wake up the listen token while the connection is
369 established successfully.
371 @param Sock Pointer to the socket.
377 SockWakeListenToken (
382 SOCK_TOKEN
*SockToken
;
383 EFI_TCP4_LISTEN_TOKEN
*ListenToken
;
385 Parent
= Sock
->Parent
;
387 ASSERT (Parent
&& SOCK_IS_LISTENING (Parent
) && SOCK_IS_CONNECTED (Sock
));
389 if (!IsListEmpty (&Parent
->ListenTokenList
)) {
390 SockToken
= NET_LIST_HEAD (
391 &Parent
->ListenTokenList
,
396 ListenToken
= (EFI_TCP4_LISTEN_TOKEN
*) SockToken
->Token
;
397 ListenToken
->NewChildHandle
= Sock
->SockHandle
;
399 SIGNAL_TOKEN (&(ListenToken
->CompletionToken
), EFI_SUCCESS
);
401 RemoveEntryList (&SockToken
->TokenList
);
402 gBS
->FreePool (SockToken
);
404 RemoveEntryList (&Sock
->ConnectionList
);
407 DEBUG ((EFI_D_WARN
, "SockWakeListenToken: accept a socket, now conncnt is %d", Parent
->ConnCnt
));
415 Wake up the receive token while some data is received.
417 @param Sock Pointer to the socket.
428 UINT32 TokenRcvdBytes
;
429 SOCK_TOKEN
*SockToken
;
430 SOCK_IO_TOKEN
*RcvToken
;
432 ASSERT (Sock
->RcvBuffer
.DataQueue
);
434 RcvdBytes
= (Sock
->RcvBuffer
.DataQueue
)->BufSize
;
436 ASSERT (RcvdBytes
> 0);
438 while (RcvdBytes
> 0 && !IsListEmpty (&Sock
->RcvTokenList
)) {
440 SockToken
= NET_LIST_HEAD (
446 RcvToken
= (SOCK_IO_TOKEN
*) SockToken
->Token
;
447 TokenRcvdBytes
= SockProcessRcvToken (Sock
, RcvToken
);
449 if (0 == TokenRcvdBytes
) {
453 RemoveEntryList (&(SockToken
->TokenList
));
454 gBS
->FreePool (SockToken
);
455 RcvdBytes
-= TokenRcvdBytes
;
461 Process the send token.
463 @param Sock Pointer to the socket.
469 SockProcessSndToken (
474 SOCK_TOKEN
*SockToken
;
476 SOCK_IO_TOKEN
*SndToken
;
477 EFI_TCP4_TRANSMIT_DATA
*TxData
;
480 ASSERT (Sock
&& (SOCK_STREAM
== Sock
->Type
));
482 FreeSpace
= SockGetFreeSpace (Sock
, SOCK_SND_BUF
);
485 // to determine if process a send token using
486 // socket layer flow control policy
488 while ((FreeSpace
>= Sock
->SndBuffer
.LowWater
) &&
489 !IsListEmpty (&Sock
->SndTokenList
)) {
491 SockToken
= NET_LIST_HEAD (
492 &(Sock
->SndTokenList
),
498 // process this token
500 RemoveEntryList (&(SockToken
->TokenList
));
502 &(Sock
->ProcessingSndTokenList
),
503 &(SockToken
->TokenList
)
507 // Proceess it in the light of SockType
509 SndToken
= (SOCK_IO_TOKEN
*) SockToken
->Token
;
510 TxData
= SndToken
->Packet
.TxData
;
512 DataLen
= (UINT32
) TxData
->DataLength
;
513 Status
= SockProcessTcpSndData (Sock
, TxData
);
515 if (EFI_ERROR (Status
)) {
519 if (DataLen
>= FreeSpace
) {
523 FreeSpace
-= DataLen
;
532 RemoveEntryList (&SockToken
->TokenList
);
533 SIGNAL_TOKEN (SockToken
->Token
, Status
);
534 gBS
->FreePool (SockToken
);
539 Create a socket with initial data SockInitData.
541 @param SockInitData Pointer to the initial data of the socket.
543 @return Pointer to the newly created socket.
548 IN SOCK_INIT_DATA
*SockInitData
555 ASSERT (SockInitData
&& SockInitData
->ProtoHandler
);
556 ASSERT (SockInitData
->Type
== SOCK_STREAM
);
557 ASSERT (SockInitData
->ProtoData
&& (SockInitData
->DataSize
<= PROTO_RESERVED_LEN
));
559 Parent
= SockInitData
->Parent
;
561 if (Parent
&& (Parent
->ConnCnt
== Parent
->BackLog
)) {
564 "SockCreate: Socket parent has "
565 "reached its connection limit with %d ConnCnt and %d BackLog\n",
573 Sock
= AllocateZeroPool (sizeof (SOCKET
));
576 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to create a new socket\n"));
580 InitializeListHead (&Sock
->Link
);
581 InitializeListHead (&Sock
->ConnectionList
);
582 InitializeListHead (&Sock
->ListenTokenList
);
583 InitializeListHead (&Sock
->RcvTokenList
);
584 InitializeListHead (&Sock
->SndTokenList
);
585 InitializeListHead (&Sock
->ProcessingSndTokenList
);
587 EfiInitializeLock (&(Sock
->Lock
), TPL_CALLBACK
);
589 Sock
->SndBuffer
.DataQueue
= NetbufQueAlloc ();
590 if (NULL
== Sock
->SndBuffer
.DataQueue
) {
591 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to allocate"
592 " SndBuffer for new socket\n"));
597 Sock
->RcvBuffer
.DataQueue
= NetbufQueAlloc ();
598 if (NULL
== Sock
->RcvBuffer
.DataQueue
) {
599 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to allocate "
600 "RcvBuffer for new socket\n"));
605 Sock
->Signature
= SOCK_SIGNATURE
;
607 Sock
->Parent
= Parent
;
608 Sock
->BackLog
= SockInitData
->BackLog
;
609 Sock
->ProtoHandler
= SockInitData
->ProtoHandler
;
610 Sock
->SndBuffer
.HighWater
= SockInitData
->SndBufferSize
;
611 Sock
->RcvBuffer
.HighWater
= SockInitData
->RcvBufferSize
;
612 Sock
->Type
= SockInitData
->Type
;
613 Sock
->DriverBinding
= SockInitData
->DriverBinding
;
614 Sock
->State
= SockInitData
->State
;
615 Sock
->CreateCallback
= SockInitData
->CreateCallback
;
616 Sock
->DestroyCallback
= SockInitData
->DestroyCallback
;
617 Sock
->Context
= SockInitData
->Context
;
619 Sock
->SockError
= EFI_ABORTED
;
620 Sock
->SndBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
621 Sock
->RcvBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
624 // Install protocol on Sock->SockHandle
627 &(Sock
->NetProtocol
.TcpProtocol
),
628 SockInitData
->Protocol
,
629 sizeof (EFI_TCP4_PROTOCOL
)
633 // copy the protodata into socket
635 CopyMem (Sock
->ProtoReserved
, SockInitData
->ProtoData
, SockInitData
->DataSize
);
637 Status
= gBS
->InstallMultipleProtocolInterfaces (
639 &gEfiTcp4ProtocolGuid
,
640 &(Sock
->NetProtocol
.TcpProtocol
),
644 if (EFI_ERROR (Status
)) {
645 DEBUG ((EFI_D_ERROR
, "SockCreate: Install TCP protocol in "
646 "socket failed with %r\n", Status
));
651 if (Parent
!= NULL
) {
652 ASSERT (Parent
->BackLog
> 0);
653 ASSERT (SOCK_IS_LISTENING (Parent
));
656 // need to add it into Parent->ConnectionList
657 // if the Parent->ConnCnt < Parent->BackLog
663 "SockCreate: Create a new socket and add to parent, now conncnt is %d\n",
667 InsertTailList (&Parent
->ConnectionList
, &Sock
->ConnectionList
);
670 if (Sock
->CreateCallback
!= NULL
) {
671 Status
= Sock
->CreateCallback (Sock
, Sock
->Context
);
672 if (EFI_ERROR (Status
)) {
681 if (Sock
->SockHandle
!= NULL
) {
682 gBS
->UninstallMultipleProtocolInterfaces (
684 &gEfiTcp4ProtocolGuid
,
685 &(Sock
->NetProtocol
.TcpProtocol
),
690 if (NULL
!= Sock
->SndBuffer
.DataQueue
) {
691 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
694 if (NULL
!= Sock
->RcvBuffer
.DataQueue
) {
695 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
698 gBS
->FreePool (Sock
);
707 @param Sock Pointer to the socket.
718 EFI_GUID
*ProtocolGuid
;
721 ASSERT (SOCK_STREAM
== Sock
->Type
);
723 if (Sock
->DestroyCallback
!= NULL
) {
724 Sock
->DestroyCallback (Sock
, Sock
->Context
);
728 // Flush the completion token buffered
729 // by sock and rcv, snd buffer
731 if (!SOCK_IS_UNCONFIGURED (Sock
)) {
733 SockConnFlush (Sock
);
734 SockSetState (Sock
, SO_CLOSED
);
735 Sock
->ConfigureState
= SO_UNCONFIGURED
;
739 // Destory the RcvBuffer Queue and SendBuffer Queue
741 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
742 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
745 // Remove it from parent connection list if needed
749 RemoveEntryList (&(Sock
->ConnectionList
));
750 (Sock
->Parent
->ConnCnt
)--;
754 "SockDestory: Delete a unaccepted socket from parent"
755 "now conncnt is %d\n",
756 Sock
->Parent
->ConnCnt
)
763 // Set the protocol guid and driver binding handle
764 // in the light of Sock->SockType
766 ProtocolGuid
= &gEfiTcp4ProtocolGuid
;
769 // Retrieve the protocol installed on this sock
771 Status
= gBS
->OpenProtocol (
777 EFI_OPEN_PROTOCOL_GET_PROTOCOL
780 if (EFI_ERROR (Status
)) {
782 DEBUG ((EFI_D_ERROR
, "SockDestroy: Open protocol installed "
783 "on socket failed with %r\n", Status
));
789 // Uninstall the protocol installed on this sock
790 // in the light of Sock->SockType
792 gBS
->UninstallMultipleProtocolInterfaces (
800 gBS
->FreePool (Sock
);
808 @param Sock Pointer to the socket.
823 // Clear the flag in this socket
828 // Flush the SndBuffer and RcvBuffer of Sock
830 NetbufQueFlush (Sock
->SndBuffer
.DataQueue
);
831 NetbufQueFlush (Sock
->RcvBuffer
.DataQueue
);
834 // Signal the pending token
836 if (Sock
->ConnectionToken
!= NULL
) {
837 SIGNAL_TOKEN (Sock
->ConnectionToken
, Sock
->SockError
);
838 Sock
->ConnectionToken
= NULL
;
841 if (Sock
->CloseToken
!= NULL
) {
842 SIGNAL_TOKEN (Sock
->CloseToken
, Sock
->SockError
);
843 Sock
->CloseToken
= NULL
;
846 SockFlushPendingToken (Sock
, &(Sock
->ListenTokenList
));
847 SockFlushPendingToken (Sock
, &(Sock
->RcvTokenList
));
848 SockFlushPendingToken (Sock
, &(Sock
->SndTokenList
));
849 SockFlushPendingToken (Sock
, &(Sock
->ProcessingSndTokenList
));
852 // Destroy the pending connection, if it is a listening socket
854 if (SOCK_IS_LISTENING (Sock
)) {
855 while (!IsListEmpty (&Sock
->ConnectionList
)) {
856 Child
= NET_LIST_HEAD (
857 &Sock
->ConnectionList
,
862 SockDestroyChild (Child
);
873 Set the state of the socket.
875 @param Sock Pointer to the socket.
876 @param State The new state to be set.
892 Clone a new socket including its associated protocol control block.
894 @param Sock Pointer to the socket to be cloned.
896 @retval * Pointer to the newly cloned socket. If NULL, error
906 SOCK_INIT_DATA InitData
;
908 InitData
.BackLog
= Sock
->BackLog
;
909 InitData
.Parent
= Sock
;
910 InitData
.State
= Sock
->State
;
911 InitData
.ProtoHandler
= Sock
->ProtoHandler
;
912 InitData
.Type
= Sock
->Type
;
913 InitData
.RcvBufferSize
= Sock
->RcvBuffer
.HighWater
;
914 InitData
.SndBufferSize
= Sock
->SndBuffer
.HighWater
;
915 InitData
.DriverBinding
= Sock
->DriverBinding
;
916 InitData
.Protocol
= &(Sock
->NetProtocol
);
917 InitData
.CreateCallback
= Sock
->CreateCallback
;
918 InitData
.DestroyCallback
= Sock
->DestroyCallback
;
919 InitData
.Context
= Sock
->Context
;
920 InitData
.ProtoData
= Sock
->ProtoReserved
;
921 InitData
.DataSize
= sizeof (Sock
->ProtoReserved
);
923 ClonedSock
= SockCreate (&InitData
);
925 if (NULL
== ClonedSock
) {
926 DEBUG ((EFI_D_ERROR
, "SockClone: no resource to create a cloned sock\n"));
930 SockSetState (ClonedSock
, SO_CONNECTING
);
931 ClonedSock
->ConfigureState
= Sock
->ConfigureState
;
938 Called by the low layer protocol to indicate the socket
939 a connection is established. This function just changes
940 the socket's state to SO_CONNECTED and signals the token
941 used for connection establishment.
943 @param Sock Pointer to the socket associated with the
944 established connection.
950 SockConnEstablished (
955 ASSERT (SO_CONNECTING
== Sock
->State
);
957 SockSetState (Sock
, SO_CONNECTED
);
959 if (NULL
== Sock
->Parent
) {
960 SockWakeConnToken (Sock
);
962 SockWakeListenToken (Sock
);
970 Called by the low layer protocol to indicate the connection
971 is closed. This function flushes the socket, sets the state
972 to SO_CLOSED and signals the close token.
974 @param Sock Pointer to the socket associated with the closed
985 if (Sock
->CloseToken
) {
986 SIGNAL_TOKEN (Sock
->CloseToken
, EFI_SUCCESS
);
987 Sock
->CloseToken
= NULL
;
990 SockConnFlush (Sock
);
991 SockSetState (Sock
, SO_CLOSED
);
993 if (Sock
->Parent
!= NULL
) {
994 SockDestroyChild (Sock
);
1001 Called by low layer protocol to indicate that some
1002 data is sent or processed. This function trims the
1003 sent data in the socket send buffer, signals the
1004 data token if proper
1006 @param Sock Pointer to the socket.
1007 @param Count The length of the data processed or sent, in bytes.
1018 SOCK_TOKEN
*SockToken
;
1019 SOCK_COMPLETION_TOKEN
*SndToken
;
1021 ASSERT (!IsListEmpty (&Sock
->ProcessingSndTokenList
));
1022 ASSERT (Count
<= (Sock
->SndBuffer
.DataQueue
)->BufSize
);
1024 NetbufQueTrim (Sock
->SndBuffer
.DataQueue
, Count
);
1027 // To check if we can signal some snd token in this socket
1030 SockToken
= NET_LIST_HEAD (
1031 &(Sock
->ProcessingSndTokenList
),
1036 SndToken
= SockToken
->Token
;
1038 if (SockToken
->RemainDataLen
<= Count
) {
1040 RemoveEntryList (&(SockToken
->TokenList
));
1041 SIGNAL_TOKEN (SndToken
, EFI_SUCCESS
);
1042 Count
-= SockToken
->RemainDataLen
;
1043 gBS
->FreePool (SockToken
);
1046 SockToken
->RemainDataLen
-= Count
;
1052 // to judge if we can process some send token in
1053 // Sock->SndTokenList, if so process those send token
1055 SockProcessSndToken (Sock
);
1061 Called by the low layer protocol to copy some data in socket send
1062 buffer starting from the specific offset to a buffer provided by
1065 @param Sock Pointer to the socket.
1066 @param Offset The start point of the data to be copied.
1067 @param Len The length of the data to be copied.
1068 @param Dest Pointer to the destination to copy the data.
1070 @return The data size copied.
1081 ASSERT (Sock
&& SOCK_STREAM
== Sock
->Type
);
1083 return NetbufQueCopy (
1084 Sock
->SndBuffer
.DataQueue
,
1093 Called by the low layer protocol to deliver received data
1094 to socket layer. This function will append the data to the
1095 socket receive buffer, set ther urgent data length and then
1096 check if any receive token can be signaled.
1098 @param Sock Pointer to the socket.
1099 @param NetBuffer Pointer to the buffer that contains the received
1101 @param UrgLen The length of the urgent data in the received data.
1109 IN NET_BUF
*NetBuffer
,
1113 ASSERT (Sock
&& Sock
->RcvBuffer
.DataQueue
&&
1114 UrgLen
<= NetBuffer
->TotalSize
);
1116 NET_GET_REF (NetBuffer
);
1118 ((TCP_RSV_DATA
*) (NetBuffer
->ProtoData
))->UrgLen
= UrgLen
;
1120 NetbufQueAppend (Sock
->RcvBuffer
.DataQueue
, NetBuffer
);
1122 SockWakeRcvToken (Sock
);
1128 Get the length of the free space of the specific socket buffer.
1130 @param Sock Pointer to the socket.
1131 @param Which Flag to indicate which socket buffer to check,
1132 either send buffer or receive buffer.
1134 @return The length of the free space, in bytes.
1144 SOCK_BUFFER
*SockBuffer
;
1146 ASSERT (Sock
&& ((SOCK_SND_BUF
== Which
) || (SOCK_RCV_BUF
== Which
)));
1148 if (SOCK_SND_BUF
== Which
) {
1149 SockBuffer
= &(Sock
->SndBuffer
);
1151 SockBuffer
= &(Sock
->RcvBuffer
);
1154 BufferCC
= (SockBuffer
->DataQueue
)->BufSize
;
1156 if (BufferCC
>= SockBuffer
->HighWater
) {
1161 return SockBuffer
->HighWater
- BufferCC
;
1166 Signal the receive token with the specific error or
1167 set socket error code after error is received.
1169 @param Sock Pointer to the socket.
1170 @param Error The error code received.
1181 SOCK_TOKEN
*SockToken
;
1183 if (!IsListEmpty (&Sock
->RcvTokenList
)) {
1185 SockToken
= NET_LIST_HEAD (
1186 &Sock
->RcvTokenList
,
1191 RemoveEntryList (&SockToken
->TokenList
);
1193 SIGNAL_TOKEN (SockToken
->Token
, Error
);
1195 gBS
->FreePool (SockToken
);
1198 SOCK_ERROR (Sock
, Error
);
1204 Called by the low layer protocol to indicate that there
1205 will be no more data from the communication peer. This
1206 function set the socket's state to SO_NO_MORE_DATA and
1207 signal all queued IO tokens with the error status
1210 @param Sock Pointer to the socket.
1222 SOCK_NO_MORE_DATA (Sock
);
1224 if (!IsListEmpty (&Sock
->RcvTokenList
)) {
1226 ASSERT (0 == GET_RCV_DATASIZE (Sock
));
1228 Err
= Sock
->SockError
;
1230 SOCK_ERROR (Sock
, EFI_CONNECTION_FIN
);
1232 SockFlushPendingToken (Sock
, &Sock
->RcvTokenList
);
1234 SOCK_ERROR (Sock
, Err
);
1242 Get the first buffer block in the specific socket buffer.
1244 @param Sockbuf Pointer to the socket buffer.
1246 @return Pointer to the first buffer in the queue. NULL if the queue is empty.
1251 IN SOCK_BUFFER
*Sockbuf
1254 LIST_ENTRY
*NetbufList
;
1256 NetbufList
= &(Sockbuf
->DataQueue
->BufList
);
1258 if (IsListEmpty (NetbufList
)) {
1262 return NET_LIST_HEAD (NetbufList
, NET_BUF
, List
);
1267 Get the next buffer block in the specific socket buffer.
1269 @param Sockbuf Pointer to the socket buffer.
1270 @param SockEntry Pointer to the buffer block prior to the required
1273 @return Pointer to the buffer block next to SockEntry. NULL if SockEntry is the tail or head entry.
1278 IN SOCK_BUFFER
*Sockbuf
,
1279 IN NET_BUF
*SockEntry
1282 LIST_ENTRY
*NetbufList
;
1284 NetbufList
= &(Sockbuf
->DataQueue
->BufList
);
1286 if ((SockEntry
->List
.ForwardLink
== NetbufList
) ||
1287 (SockEntry
->List
.BackLink
== &SockEntry
->List
) ||
1288 (SockEntry
->List
.ForwardLink
== &SockEntry
->List
)
1294 return NET_LIST_USER_STRUCT (SockEntry
->List
.ForwardLink
, NET_BUF
, List
);