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
= (BOOLEAN
) ((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
81 if (*IsUrg
&& TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
) {
83 DataLen
= 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
= (BOOLEAN
) ((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 MIN (TcpRsvData
->UrgLen
+ DataLen
, BufLen
);
121 DataLen
+= RcvBufEntry
->TotalSize
;
123 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
126 DataLen
= 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
= MIN ((UINT32
) (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 (
212 (UINT32
) RxData
->DataLength
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 (UINT32
) TxData
->FragmentCount
,
264 if (NULL
== SndData
) {
265 DEBUG ((EFI_D_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 LIST_ENTRY
*PendingTokenList
322 SOCK_TOKEN
*SockToken
;
323 SOCK_COMPLETION_TOKEN
*Token
;
325 ASSERT (Sock
&& PendingTokenList
);
327 while (!IsListEmpty (PendingTokenList
)) {
328 SockToken
= NET_LIST_HEAD (
334 Token
= SockToken
->Token
;
335 SIGNAL_TOKEN (Token
, Sock
->SockError
);
337 RemoveEntryList (&(SockToken
->TokenList
));
338 gBS
->FreePool (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 (!IsListEmpty (&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 RemoveEntryList (&SockToken
->TokenList
);
408 gBS
->FreePool (SockToken
);
410 RemoveEntryList (&Sock
->ConnectionList
);
413 DEBUG ((EFI_D_WARN
, "SockWakeListenToken: accept a socket, now conncnt is %d", Parent
->ConnCnt
));
421 Wake up the receive token while some data is received.
423 @param Sock Pointer to the socket.
435 UINT32 TokenRcvdBytes
;
436 SOCK_TOKEN
*SockToken
;
437 SOCK_IO_TOKEN
*RcvToken
;
439 ASSERT (Sock
->RcvBuffer
.DataQueue
);
441 RcvdBytes
= (Sock
->RcvBuffer
.DataQueue
)->BufSize
;
443 ASSERT (RcvdBytes
> 0);
445 while (RcvdBytes
> 0 && !IsListEmpty (&Sock
->RcvTokenList
)) {
447 SockToken
= NET_LIST_HEAD (
453 RcvToken
= (SOCK_IO_TOKEN
*) SockToken
->Token
;
454 TokenRcvdBytes
= SockProcessRcvToken (Sock
, RcvToken
);
456 if (0 == TokenRcvdBytes
) {
460 RemoveEntryList (&(SockToken
->TokenList
));
461 gBS
->FreePool (SockToken
);
462 RcvdBytes
-= TokenRcvdBytes
;
468 Process the send token.
470 @param Sock Pointer to the socket.
477 SockProcessSndToken (
482 SOCK_TOKEN
*SockToken
;
484 SOCK_IO_TOKEN
*SndToken
;
485 EFI_TCP4_TRANSMIT_DATA
*TxData
;
488 ASSERT (Sock
&& (SOCK_STREAM
== Sock
->Type
));
490 FreeSpace
= SockGetFreeSpace (Sock
, SOCK_SND_BUF
);
493 // to determine if process a send token using
494 // socket layer flow control policy
496 while ((FreeSpace
>= Sock
->SndBuffer
.LowWater
) &&
497 !IsListEmpty (&Sock
->SndTokenList
)) {
499 SockToken
= NET_LIST_HEAD (
500 &(Sock
->SndTokenList
),
506 // process this token
508 RemoveEntryList (&(SockToken
->TokenList
));
510 &(Sock
->ProcessingSndTokenList
),
511 &(SockToken
->TokenList
)
515 // Proceess it in the light of SockType
517 SndToken
= (SOCK_IO_TOKEN
*) SockToken
->Token
;
518 TxData
= SndToken
->Packet
.TxData
;
520 DataLen
= (UINT32
) TxData
->DataLength
;
521 Status
= SockProcessTcpSndData (Sock
, TxData
);
523 if (EFI_ERROR (Status
)) {
527 if (DataLen
>= FreeSpace
) {
531 FreeSpace
-= DataLen
;
540 RemoveEntryList (&SockToken
->TokenList
);
541 SIGNAL_TOKEN (SockToken
->Token
, Status
);
542 gBS
->FreePool (SockToken
);
547 Create a socket with initial data SockInitData.
549 @param SockInitData Pointer to the initial data of the socket.
551 @return Pointer to the newly created socket.
556 IN SOCK_INIT_DATA
*SockInitData
563 ASSERT (SockInitData
&& SockInitData
->ProtoHandler
);
564 ASSERT (SockInitData
->Type
== SOCK_STREAM
);
565 ASSERT (SockInitData
->ProtoData
&& (SockInitData
->DataSize
<= PROTO_RESERVED_LEN
));
567 Parent
= SockInitData
->Parent
;
569 if (Parent
&& (Parent
->ConnCnt
== Parent
->BackLog
)) {
572 "SockCreate: Socket parent has "
573 "reached its connection limit with %d ConnCnt and %d BackLog\n",
581 Sock
= AllocateZeroPool (sizeof (SOCKET
));
584 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to create a new socket\n"));
588 InitializeListHead (&Sock
->Link
);
589 InitializeListHead (&Sock
->ConnectionList
);
590 InitializeListHead (&Sock
->ListenTokenList
);
591 InitializeListHead (&Sock
->RcvTokenList
);
592 InitializeListHead (&Sock
->SndTokenList
);
593 InitializeListHead (&Sock
->ProcessingSndTokenList
);
595 EfiInitializeLock (&(Sock
->Lock
), TPL_CALLBACK
);
597 Sock
->SndBuffer
.DataQueue
= NetbufQueAlloc ();
598 if (NULL
== Sock
->SndBuffer
.DataQueue
) {
599 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to allocate"
600 " SndBuffer for new socket\n"));
605 Sock
->RcvBuffer
.DataQueue
= NetbufQueAlloc ();
606 if (NULL
== Sock
->RcvBuffer
.DataQueue
) {
607 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to allocate "
608 "RcvBuffer for new socket\n"));
613 Sock
->Signature
= SOCK_SIGNATURE
;
615 Sock
->Parent
= Parent
;
616 Sock
->BackLog
= SockInitData
->BackLog
;
617 Sock
->ProtoHandler
= SockInitData
->ProtoHandler
;
618 Sock
->SndBuffer
.HighWater
= SockInitData
->SndBufferSize
;
619 Sock
->RcvBuffer
.HighWater
= SockInitData
->RcvBufferSize
;
620 Sock
->Type
= SockInitData
->Type
;
621 Sock
->DriverBinding
= SockInitData
->DriverBinding
;
622 Sock
->State
= SockInitData
->State
;
623 Sock
->CreateCallback
= SockInitData
->CreateCallback
;
624 Sock
->DestroyCallback
= SockInitData
->DestroyCallback
;
625 Sock
->Context
= SockInitData
->Context
;
627 Sock
->SockError
= EFI_ABORTED
;
628 Sock
->SndBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
629 Sock
->RcvBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
632 // Install protocol on Sock->SockHandle
635 &(Sock
->NetProtocol
.TcpProtocol
),
636 SockInitData
->Protocol
,
637 sizeof (EFI_TCP4_PROTOCOL
)
641 // copy the protodata into socket
643 CopyMem (Sock
->ProtoReserved
, SockInitData
->ProtoData
, SockInitData
->DataSize
);
645 Status
= gBS
->InstallMultipleProtocolInterfaces (
647 &gEfiTcp4ProtocolGuid
,
648 &(Sock
->NetProtocol
.TcpProtocol
),
652 if (EFI_ERROR (Status
)) {
653 DEBUG ((EFI_D_ERROR
, "SockCreate: Install TCP protocol in "
654 "socket failed with %r\n", Status
));
659 if (Parent
!= NULL
) {
660 ASSERT (Parent
->BackLog
> 0);
661 ASSERT (SOCK_IS_LISTENING (Parent
));
664 // need to add it into Parent->ConnectionList
665 // if the Parent->ConnCnt < Parent->BackLog
671 "SockCreate: Create a new socket and add to parent, now conncnt is %d\n",
675 InsertTailList (&Parent
->ConnectionList
, &Sock
->ConnectionList
);
678 if (Sock
->CreateCallback
!= NULL
) {
679 Status
= Sock
->CreateCallback (Sock
, Sock
->Context
);
680 if (EFI_ERROR (Status
)) {
689 if (Sock
->SockHandle
!= NULL
) {
690 gBS
->UninstallMultipleProtocolInterfaces (
692 &gEfiTcp4ProtocolGuid
,
693 &(Sock
->NetProtocol
.TcpProtocol
),
698 if (NULL
!= Sock
->SndBuffer
.DataQueue
) {
699 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
702 if (NULL
!= Sock
->RcvBuffer
.DataQueue
) {
703 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
706 gBS
->FreePool (Sock
);
715 @param Sock Pointer to the socket.
726 EFI_GUID
*ProtocolGuid
;
729 ASSERT (SOCK_STREAM
== Sock
->Type
);
731 if (Sock
->DestroyCallback
!= NULL
) {
732 Sock
->DestroyCallback (Sock
, Sock
->Context
);
736 // Flush the completion token buffered
737 // by sock and rcv, snd buffer
739 if (!SOCK_IS_UNCONFIGURED (Sock
)) {
741 SockConnFlush (Sock
);
742 SockSetState (Sock
, SO_CLOSED
);
743 Sock
->ConfigureState
= SO_UNCONFIGURED
;
747 // Destory the RcvBuffer Queue and SendBuffer Queue
749 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
750 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
753 // Remove it from parent connection list if needed
757 RemoveEntryList (&(Sock
->ConnectionList
));
758 (Sock
->Parent
->ConnCnt
)--;
762 "SockDestory: Delete a unaccepted socket from parent"
763 "now conncnt is %d\n",
764 Sock
->Parent
->ConnCnt
)
771 // Set the protocol guid and driver binding handle
772 // in the light of Sock->SockType
774 ProtocolGuid
= &gEfiTcp4ProtocolGuid
;
777 // Retrieve the protocol installed on this sock
779 Status
= gBS
->OpenProtocol (
785 EFI_OPEN_PROTOCOL_GET_PROTOCOL
788 if (EFI_ERROR (Status
)) {
790 DEBUG ((EFI_D_ERROR
, "SockDestroy: Open protocol installed "
791 "on socket failed with %r\n", Status
));
797 // Uninstall the protocol installed on this sock
798 // in the light of Sock->SockType
800 gBS
->UninstallMultipleProtocolInterfaces (
808 gBS
->FreePool (Sock
);
816 @param Sock Pointer to the socket.
831 // Clear the flag in this socket
836 // Flush the SndBuffer and RcvBuffer of Sock
838 NetbufQueFlush (Sock
->SndBuffer
.DataQueue
);
839 NetbufQueFlush (Sock
->RcvBuffer
.DataQueue
);
842 // Signal the pending token
844 if (Sock
->ConnectionToken
!= NULL
) {
845 SIGNAL_TOKEN (Sock
->ConnectionToken
, Sock
->SockError
);
846 Sock
->ConnectionToken
= NULL
;
849 if (Sock
->CloseToken
!= NULL
) {
850 SIGNAL_TOKEN (Sock
->CloseToken
, Sock
->SockError
);
851 Sock
->CloseToken
= NULL
;
854 SockFlushPendingToken (Sock
, &(Sock
->ListenTokenList
));
855 SockFlushPendingToken (Sock
, &(Sock
->RcvTokenList
));
856 SockFlushPendingToken (Sock
, &(Sock
->SndTokenList
));
857 SockFlushPendingToken (Sock
, &(Sock
->ProcessingSndTokenList
));
860 // Destroy the pending connection, if it is a listening socket
862 if (SOCK_IS_LISTENING (Sock
)) {
863 while (!IsListEmpty (&Sock
->ConnectionList
)) {
864 Child
= NET_LIST_HEAD (
865 &Sock
->ConnectionList
,
870 SockDestroyChild (Child
);
881 Set the state of the socket.
883 @param Sock Pointer to the socket.
884 @param State The new state to be set.
900 Clone a new socket including its associated protocol control block.
902 @param Sock Pointer to the socket to be cloned.
904 @retval * Pointer to the newly cloned socket. If NULL, error
914 SOCK_INIT_DATA InitData
;
916 InitData
.BackLog
= Sock
->BackLog
;
917 InitData
.Parent
= Sock
;
918 InitData
.State
= Sock
->State
;
919 InitData
.ProtoHandler
= Sock
->ProtoHandler
;
920 InitData
.Type
= Sock
->Type
;
921 InitData
.RcvBufferSize
= Sock
->RcvBuffer
.HighWater
;
922 InitData
.SndBufferSize
= Sock
->SndBuffer
.HighWater
;
923 InitData
.DriverBinding
= Sock
->DriverBinding
;
924 InitData
.Protocol
= &(Sock
->NetProtocol
);
925 InitData
.CreateCallback
= Sock
->CreateCallback
;
926 InitData
.DestroyCallback
= Sock
->DestroyCallback
;
927 InitData
.Context
= Sock
->Context
;
928 InitData
.ProtoData
= Sock
->ProtoReserved
;
929 InitData
.DataSize
= sizeof (Sock
->ProtoReserved
);
931 ClonedSock
= SockCreate (&InitData
);
933 if (NULL
== ClonedSock
) {
934 DEBUG ((EFI_D_ERROR
, "SockClone: no resource to create a cloned sock\n"));
938 SockSetState (ClonedSock
, SO_CONNECTING
);
939 ClonedSock
->ConfigureState
= Sock
->ConfigureState
;
946 Called by the low layer protocol to indicate the socket
947 a connection is established. This function just changes
948 the socket's state to SO_CONNECTED and signals the token
949 used for connection establishment.
951 @param Sock Pointer to the socket associated with the
952 established connection.
958 SockConnEstablished (
963 ASSERT (SO_CONNECTING
== Sock
->State
);
965 SockSetState (Sock
, SO_CONNECTED
);
967 if (NULL
== Sock
->Parent
) {
968 SockWakeConnToken (Sock
);
970 SockWakeListenToken (Sock
);
978 Called by the low layer protocol to indicate the connection
979 is closed. This function flushes the socket, sets the state
980 to SO_CLOSED and signals the close token.
982 @param Sock Pointer to the socket associated with the closed
993 if (Sock
->CloseToken
) {
994 SIGNAL_TOKEN (Sock
->CloseToken
, EFI_SUCCESS
);
995 Sock
->CloseToken
= NULL
;
998 SockConnFlush (Sock
);
999 SockSetState (Sock
, SO_CLOSED
);
1001 if (Sock
->Parent
!= NULL
) {
1002 SockDestroyChild (Sock
);
1009 Called by low layer protocol to indicate that some
1010 data is sent or processed. This function trims the
1011 sent data in the socket send buffer, signals the
1012 data token if proper
1014 @param Sock Pointer to the socket.
1015 @param Count The length of the data processed or sent, in bytes.
1026 SOCK_TOKEN
*SockToken
;
1027 SOCK_COMPLETION_TOKEN
*SndToken
;
1029 ASSERT (!IsListEmpty (&Sock
->ProcessingSndTokenList
));
1030 ASSERT (Count
<= (Sock
->SndBuffer
.DataQueue
)->BufSize
);
1032 NetbufQueTrim (Sock
->SndBuffer
.DataQueue
, Count
);
1035 // To check if we can signal some snd token in this socket
1038 SockToken
= NET_LIST_HEAD (
1039 &(Sock
->ProcessingSndTokenList
),
1044 SndToken
= SockToken
->Token
;
1046 if (SockToken
->RemainDataLen
<= Count
) {
1048 RemoveEntryList (&(SockToken
->TokenList
));
1049 SIGNAL_TOKEN (SndToken
, EFI_SUCCESS
);
1050 Count
-= SockToken
->RemainDataLen
;
1051 gBS
->FreePool (SockToken
);
1054 SockToken
->RemainDataLen
-= Count
;
1060 // to judge if we can process some send token in
1061 // Sock->SndTokenList, if so process those send token
1063 SockProcessSndToken (Sock
);
1069 Called by the low layer protocol to copy some data in socket send
1070 buffer starting from the specific offset to a buffer provided by
1073 @param Sock Pointer to the socket.
1074 @param Offset The start point of the data to be copied.
1075 @param Len The length of the data to be copied.
1076 @param Dest Pointer to the destination to copy the data.
1078 @return The data size copied.
1089 ASSERT (Sock
&& SOCK_STREAM
== Sock
->Type
);
1091 return NetbufQueCopy (
1092 Sock
->SndBuffer
.DataQueue
,
1101 Called by the low layer protocol to deliver received data
1102 to socket layer. This function will append the data to the
1103 socket receive buffer, set ther urgent data length and then
1104 check if any receive token can be signaled.
1106 @param Sock Pointer to the socket.
1107 @param NetBuffer Pointer to the buffer that contains the received
1109 @param UrgLen The length of the urgent data in the received data.
1117 IN NET_BUF
*NetBuffer
,
1121 ASSERT (Sock
&& Sock
->RcvBuffer
.DataQueue
&&
1122 UrgLen
<= NetBuffer
->TotalSize
);
1124 NET_GET_REF (NetBuffer
);
1126 ((TCP_RSV_DATA
*) (NetBuffer
->ProtoData
))->UrgLen
= UrgLen
;
1128 NetbufQueAppend (Sock
->RcvBuffer
.DataQueue
, NetBuffer
);
1130 SockWakeRcvToken (Sock
);
1136 Get the length of the free space of the specific socket buffer.
1138 @param Sock Pointer to the socket.
1139 @param Which Flag to indicate which socket buffer to check,
1140 either send buffer or receive buffer.
1142 @return The length of the free space, in bytes.
1152 SOCK_BUFFER
*SockBuffer
;
1154 ASSERT (Sock
&& ((SOCK_SND_BUF
== Which
) || (SOCK_RCV_BUF
== Which
)));
1156 if (SOCK_SND_BUF
== Which
) {
1157 SockBuffer
= &(Sock
->SndBuffer
);
1159 SockBuffer
= &(Sock
->RcvBuffer
);
1162 BufferCC
= (SockBuffer
->DataQueue
)->BufSize
;
1164 if (BufferCC
>= SockBuffer
->HighWater
) {
1169 return SockBuffer
->HighWater
- BufferCC
;
1174 Signal the receive token with the specific error or
1175 set socket error code after error is received.
1177 @param Sock Pointer to the socket.
1178 @param Error The error code received.
1189 SOCK_TOKEN
*SockToken
;
1191 if (!IsListEmpty (&Sock
->RcvTokenList
)) {
1193 SockToken
= NET_LIST_HEAD (
1194 &Sock
->RcvTokenList
,
1199 RemoveEntryList (&SockToken
->TokenList
);
1201 SIGNAL_TOKEN (SockToken
->Token
, Error
);
1203 gBS
->FreePool (SockToken
);
1206 SOCK_ERROR (Sock
, Error
);
1212 Called by the low layer protocol to indicate that there
1213 will be no more data from the communication peer. This
1214 function set the socket's state to SO_NO_MORE_DATA and
1215 signal all queued IO tokens with the error status
1218 @param Sock Pointer to the socket.
1230 SOCK_NO_MORE_DATA (Sock
);
1232 if (!IsListEmpty (&Sock
->RcvTokenList
)) {
1234 ASSERT (0 == GET_RCV_DATASIZE (Sock
));
1236 Err
= Sock
->SockError
;
1238 SOCK_ERROR (Sock
, EFI_CONNECTION_FIN
);
1240 SockFlushPendingToken (Sock
, &Sock
->RcvTokenList
);
1242 SOCK_ERROR (Sock
, Err
);
1250 Get the first buffer block in the specific socket buffer.
1252 @param Sockbuf Pointer to the socket buffer.
1254 @return Pointer to the first buffer in the queue. NULL if the queue is empty.
1259 IN SOCK_BUFFER
*Sockbuf
1262 LIST_ENTRY
*NetbufList
;
1264 NetbufList
= &(Sockbuf
->DataQueue
->BufList
);
1266 if (IsListEmpty (NetbufList
)) {
1270 return NET_LIST_HEAD (NetbufList
, NET_BUF
, List
);
1275 Get the next buffer block in the specific socket buffer.
1277 @param Sockbuf Pointer to the socket buffer.
1278 @param SockEntry Pointer to the buffer block prior to the required
1281 @return Pointer to the buffer block next to SockEntry. NULL if SockEntry is the tail or head entry.
1286 IN SOCK_BUFFER
*Sockbuf
,
1287 IN NET_BUF
*SockEntry
1290 LIST_ENTRY
*NetbufList
;
1292 NetbufList
= &(Sockbuf
->DataQueue
->BufList
);
1294 if ((SockEntry
->List
.ForwardLink
== NetbufList
) ||
1295 (SockEntry
->List
.BackLink
== &SockEntry
->List
) ||
1296 (SockEntry
->List
.ForwardLink
== &SockEntry
->List
)
1302 return NET_LIST_USER_STRUCT (SockEntry
->List
.ForwardLink
, NET_BUF
, List
);