3 Copyright (c) 2005 - 2006, Intel Corporation<BR>
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<BR>
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.
17 Get the length of the data that can be retrieved from the socket
20 @param SockBuffer Pointer to the socket receive buffer.
21 @param IsUrg Pointer to a BOOLEAN variable. If TRUE the data is
23 @param BufLen The maximum length of the data buffer to store the
24 received data in socket layer.
26 @return The length of the data can be retreived.
31 IN SOCK_BUFFER
*SockBuffer
,
37 Process the send token.
39 @param Sock Pointer to the socket.
48 Supporting function for both SockImpl and SockInterface.
50 @param Event The Event this notify function registered to, ignored.
63 Get the length of the data that can be retrieved from the socket
66 @param SockBuffer Pointer to the socket receive buffer.
67 @param IsUrg Pointer to a BOOLEAN variable. If TRUE the data is
69 @param BufLen The maximum length of the data buffer to store the
70 received data in socket layer.
72 @return The length of the data can be retreived.
77 IN SOCK_BUFFER
*SockBuffer
,
84 TCP_RSV_DATA
*TcpRsvData
;
87 ASSERT ((SockBuffer
!= NULL
) && (IsUrg
!= NULL
) && (BufLen
> 0));
89 RcvBufEntry
= SockBufFirst (SockBuffer
);
90 ASSERT (RcvBufEntry
!= NULL
);
92 TcpRsvData
= (TCP_RSV_DATA
*) RcvBufEntry
->ProtoData
;
94 *IsUrg
= (BOOLEAN
) ((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
96 if (*IsUrg
&& TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
) {
98 DataLen
= MIN (TcpRsvData
->UrgLen
, BufLen
);
100 if (DataLen
< TcpRsvData
->UrgLen
) {
101 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- DataLen
;
103 TcpRsvData
->UrgLen
= 0;
110 DataLen
= RcvBufEntry
->TotalSize
;
112 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
114 while ((BufLen
> DataLen
) && (RcvBufEntry
!= NULL
)) {
116 TcpRsvData
= (TCP_RSV_DATA
*) RcvBufEntry
->ProtoData
;
118 Urg
= (BOOLEAN
) ((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
124 if (*IsUrg
&& TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
) {
126 if (TcpRsvData
->UrgLen
+ DataLen
< BufLen
) {
127 TcpRsvData
->UrgLen
= 0;
129 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- (BufLen
- DataLen
);
132 return MIN (TcpRsvData
->UrgLen
+ DataLen
, BufLen
);
136 DataLen
+= RcvBufEntry
->TotalSize
;
138 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
141 DataLen
= MIN (BufLen
, DataLen
);
147 Copy data from socket buffer to application provided receive buffer.
149 @param Sock Pointer to the socket.
150 @param TcpRxData Pointer to the application provided receive buffer.
151 @param RcvdBytes The maximum length of the data can be copied.
152 @param IsOOB If TURE the data is OOB, else the data is normal.
166 EFI_TCP4_RECEIVE_DATA
*RxData
;
167 EFI_TCP4_FRAGMENT_DATA
*Fragment
;
169 RxData
= (EFI_TCP4_RECEIVE_DATA
*) TcpRxData
;
173 ASSERT (RxData
->DataLength
>= RcvdBytes
);
175 RxData
->DataLength
= RcvdBytes
;
176 RxData
->UrgentFlag
= IsOOB
;
178 for (Index
= 0; (Index
< RxData
->FragmentCount
) && (RcvdBytes
> 0); Index
++) {
180 Fragment
= &RxData
->FragmentTable
[Index
];
181 CopyBytes
= MIN ((UINT32
) (Fragment
->FragmentLength
), RcvdBytes
);
184 Sock
->RcvBuffer
.DataQueue
,
187 Fragment
->FragmentBuffer
190 Fragment
->FragmentLength
= CopyBytes
;
191 RcvdBytes
-= CopyBytes
;
198 Get received data from the socket layer to the receive token.
200 @param Sock Pointer to the socket.
201 @param RcvToken Pointer to the application provided receive token.
203 @return The length of data received in this token.
207 SockProcessRcvToken (
209 IN SOCK_IO_TOKEN
*RcvToken
212 UINT32 TokenRcvdBytes
;
213 EFI_TCP4_RECEIVE_DATA
*RxData
;
216 ASSERT (Sock
!= NULL
);
218 ASSERT (SOCK_STREAM
== Sock
->Type
);
220 RxData
= RcvToken
->Packet
.RxData
;
222 TokenRcvdBytes
= SockTcpDataToRcv (
225 (UINT32
) RxData
->DataLength
229 // Copy data from RcvBuffer of socket to user
230 // provided RxData and set the fields in TCP RxData
232 SockSetTcpRxData (Sock
, RxData
, TokenRcvdBytes
, IsUrg
);
234 NetbufQueTrim (Sock
->RcvBuffer
.DataQueue
, TokenRcvdBytes
);
235 // SOCK_TRIM_RCV_BUFF (Sock, TokenRcvdBytes);
236 SIGNAL_TOKEN (&(RcvToken
->Token
), EFI_SUCCESS
);
238 return TokenRcvdBytes
;
243 Process the TCP send data, buffer the tcp txdata and append
244 the buffer to socket send buffer,then try to send it.
246 @param Sock Pointer to the socket.
247 @param TcpTxData Pointer to the tcp txdata.
249 @retval EFI_SUCCESS The operation is completed successfully.
250 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
254 SockProcessTcpSndData (
261 EFI_TCP4_TRANSMIT_DATA
*TxData
;
263 TxData
= (EFI_TCP4_TRANSMIT_DATA
*) TcpTxData
;
266 // transform this TxData into a NET_BUFFER
267 // and insert it into Sock->SndBuffer
269 SndData
= NetbufFromExt (
270 (NET_FRAGMENT
*) TxData
->FragmentTable
,
271 (UINT32
) TxData
->FragmentCount
,
278 if (NULL
== SndData
) {
279 DEBUG ((EFI_D_ERROR
, "SockKProcessSndData: Failed to"
280 " call NetBufferFromExt\n"));
282 return EFI_OUT_OF_RESOURCES
;
285 NetbufQueAppend (Sock
->SndBuffer
.DataQueue
, SndData
);
288 // notify the low layer protocol to handle this send token
290 if (TxData
->Urgent
) {
291 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDURG
, NULL
);
293 if (EFI_ERROR (Status
)) {
299 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDPUSH
, NULL
);
301 if (EFI_ERROR (Status
)) {
307 // low layer protocol should really handle the sending
308 // process when catching SOCK_SND request
310 Status
= Sock
->ProtoHandler (Sock
, SOCK_SND
, NULL
);
312 if (EFI_ERROR (Status
)) {
321 Flush the tokens in the specific token list.
323 @param Sock Pointer to the socket.
324 @param PendingTokenList Pointer to the token list to be flushed.
328 SockFlushPendingToken (
330 IN LIST_ENTRY
*PendingTokenList
333 SOCK_TOKEN
*SockToken
;
334 SOCK_COMPLETION_TOKEN
*Token
;
336 ASSERT ((Sock
!= NULL
) && (PendingTokenList
!= NULL
));
338 while (!IsListEmpty (PendingTokenList
)) {
339 SockToken
= NET_LIST_HEAD (
345 Token
= SockToken
->Token
;
346 SIGNAL_TOKEN (Token
, Sock
->SockError
);
348 RemoveEntryList (&(SockToken
->TokenList
));
349 gBS
->FreePool (SockToken
);
355 Wake up the connection token while the connection is successfully established,
356 then try to process any pending send token.
358 @param Sock Pointer to the socket.
366 ASSERT (Sock
->ConnectionToken
!= NULL
);
368 SIGNAL_TOKEN (Sock
->ConnectionToken
, EFI_SUCCESS
);
369 Sock
->ConnectionToken
= NULL
;
372 // check to see if some pending send token existed?
374 SockProcessSndToken (Sock
);
380 Wake up the listen token while the connection is established successfully.
382 @param Sock Pointer to the socket.
386 SockWakeListenToken (
391 SOCK_TOKEN
*SockToken
;
392 EFI_TCP4_LISTEN_TOKEN
*ListenToken
;
394 Parent
= Sock
->Parent
;
396 ASSERT ((Parent
!= NULL
) && SOCK_IS_LISTENING (Parent
) && SOCK_IS_CONNECTED (Sock
));
398 if (!IsListEmpty (&Parent
->ListenTokenList
)) {
399 SockToken
= NET_LIST_HEAD (
400 &Parent
->ListenTokenList
,
405 ListenToken
= (EFI_TCP4_LISTEN_TOKEN
*) SockToken
->Token
;
406 ListenToken
->NewChildHandle
= Sock
->SockHandle
;
408 SIGNAL_TOKEN (&(ListenToken
->CompletionToken
), EFI_SUCCESS
);
410 RemoveEntryList (&SockToken
->TokenList
);
411 gBS
->FreePool (SockToken
);
413 RemoveEntryList (&Sock
->ConnectionList
);
416 DEBUG ((EFI_D_INFO
, "SockWakeListenToken: accept a socket, now conncnt is %d", Parent
->ConnCnt
));
424 Wake up the receive token while some data is received.
426 @param Sock Pointer to the socket.
435 UINT32 TokenRcvdBytes
;
436 SOCK_TOKEN
*SockToken
;
437 SOCK_IO_TOKEN
*RcvToken
;
439 ASSERT (Sock
->RcvBuffer
.DataQueue
!= NULL
);
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.
474 SockProcessSndToken (
479 SOCK_TOKEN
*SockToken
;
481 SOCK_IO_TOKEN
*SndToken
;
482 EFI_TCP4_TRANSMIT_DATA
*TxData
;
485 ASSERT ((Sock
!= NULL
) && (SOCK_STREAM
== Sock
->Type
));
487 FreeSpace
= SockGetFreeSpace (Sock
, SOCK_SND_BUF
);
490 // to determine if process a send token using
491 // socket layer flow control policy
493 while ((FreeSpace
>= Sock
->SndBuffer
.LowWater
) &&
494 !IsListEmpty (&Sock
->SndTokenList
)) {
496 SockToken
= NET_LIST_HEAD (
497 &(Sock
->SndTokenList
),
503 // process this token
505 RemoveEntryList (&(SockToken
->TokenList
));
507 &(Sock
->ProcessingSndTokenList
),
508 &(SockToken
->TokenList
)
512 // Proceess it in the light of SockType
514 SndToken
= (SOCK_IO_TOKEN
*) SockToken
->Token
;
515 TxData
= SndToken
->Packet
.TxData
;
517 DataLen
= (UINT32
) TxData
->DataLength
;
518 Status
= SockProcessTcpSndData (Sock
, TxData
);
520 if (EFI_ERROR (Status
)) {
524 if (DataLen
>= FreeSpace
) {
528 FreeSpace
-= DataLen
;
537 RemoveEntryList (&SockToken
->TokenList
);
538 SIGNAL_TOKEN (SockToken
->Token
, Status
);
539 gBS
->FreePool (SockToken
);
544 Create a socket with initial data SockInitData.
546 @param SockInitData Pointer to the initial data of the socket.
548 @return Pointer to the newly created socket.
553 IN SOCK_INIT_DATA
*SockInitData
560 ASSERT ((SockInitData
!= NULL
) && (SockInitData
->ProtoHandler
!= NULL
));
561 ASSERT (SockInitData
->Type
== SOCK_STREAM
);
562 ASSERT ((SockInitData
->ProtoData
!= NULL
) && (SockInitData
->DataSize
<= PROTO_RESERVED_LEN
));
564 Parent
= SockInitData
->Parent
;
566 if ((Parent
!= NULL
) && (Parent
->ConnCnt
== Parent
->BackLog
)) {
569 "SockCreate: Socket parent has "
570 "reached its connection limit with %d ConnCnt and %d BackLog\n",
578 Sock
= AllocateZeroPool (sizeof (SOCKET
));
581 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to create a new socket\n"));
585 InitializeListHead (&Sock
->Link
);
586 InitializeListHead (&Sock
->ConnectionList
);
587 InitializeListHead (&Sock
->ListenTokenList
);
588 InitializeListHead (&Sock
->RcvTokenList
);
589 InitializeListHead (&Sock
->SndTokenList
);
590 InitializeListHead (&Sock
->ProcessingSndTokenList
);
592 EfiInitializeLock (&(Sock
->Lock
), TPL_CALLBACK
);
594 Sock
->SndBuffer
.DataQueue
= NetbufQueAlloc ();
595 if (NULL
== Sock
->SndBuffer
.DataQueue
) {
596 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to allocate"
597 " SndBuffer for new socket\n"));
602 Sock
->RcvBuffer
.DataQueue
= NetbufQueAlloc ();
603 if (NULL
== Sock
->RcvBuffer
.DataQueue
) {
604 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to allocate "
605 "RcvBuffer for new socket\n"));
610 Sock
->Signature
= SOCK_SIGNATURE
;
612 Sock
->Parent
= Parent
;
613 Sock
->BackLog
= SockInitData
->BackLog
;
614 Sock
->ProtoHandler
= SockInitData
->ProtoHandler
;
615 Sock
->SndBuffer
.HighWater
= SockInitData
->SndBufferSize
;
616 Sock
->RcvBuffer
.HighWater
= SockInitData
->RcvBufferSize
;
617 Sock
->Type
= SockInitData
->Type
;
618 Sock
->DriverBinding
= SockInitData
->DriverBinding
;
619 Sock
->State
= SockInitData
->State
;
620 Sock
->CreateCallback
= SockInitData
->CreateCallback
;
621 Sock
->DestroyCallback
= SockInitData
->DestroyCallback
;
622 Sock
->Context
= SockInitData
->Context
;
624 Sock
->SockError
= EFI_ABORTED
;
625 Sock
->SndBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
626 Sock
->RcvBuffer
.LowWater
= SOCK_BUFF_LOW_WATER
;
629 // Install protocol on Sock->SockHandle
632 &(Sock
->NetProtocol
.TcpProtocol
),
633 SockInitData
->Protocol
,
634 sizeof (EFI_TCP4_PROTOCOL
)
638 // copy the protodata into socket
640 CopyMem (Sock
->ProtoReserved
, SockInitData
->ProtoData
, SockInitData
->DataSize
);
642 Status
= gBS
->InstallMultipleProtocolInterfaces (
644 &gEfiTcp4ProtocolGuid
,
645 &(Sock
->NetProtocol
.TcpProtocol
),
649 if (EFI_ERROR (Status
)) {
650 DEBUG ((EFI_D_ERROR
, "SockCreate: Install TCP protocol in "
651 "socket failed with %r\n", Status
));
656 if (Parent
!= NULL
) {
657 ASSERT (Parent
->BackLog
> 0);
658 ASSERT (SOCK_IS_LISTENING (Parent
));
661 // need to add it into Parent->ConnectionList
662 // if the Parent->ConnCnt < Parent->BackLog
668 "SockCreate: Create a new socket and add to parent, now conncnt is %d\n",
672 InsertTailList (&Parent
->ConnectionList
, &Sock
->ConnectionList
);
675 if (Sock
->CreateCallback
!= NULL
) {
676 Status
= Sock
->CreateCallback (Sock
, Sock
->Context
);
677 if (EFI_ERROR (Status
)) {
686 if (Sock
->SockHandle
!= NULL
) {
687 gBS
->UninstallMultipleProtocolInterfaces (
689 &gEfiTcp4ProtocolGuid
,
690 &(Sock
->NetProtocol
.TcpProtocol
),
695 if (NULL
!= Sock
->SndBuffer
.DataQueue
) {
696 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
699 if (NULL
!= Sock
->RcvBuffer
.DataQueue
) {
700 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
703 gBS
->FreePool (Sock
);
712 @param Sock Pointer to the socket.
721 EFI_GUID
*ProtocolGuid
;
724 ASSERT (SOCK_STREAM
== Sock
->Type
);
726 if (Sock
->DestroyCallback
!= NULL
) {
727 Sock
->DestroyCallback (Sock
, Sock
->Context
);
731 // Flush the completion token buffered
732 // by sock and rcv, snd buffer
734 if (!SOCK_IS_UNCONFIGURED (Sock
)) {
736 SockConnFlush (Sock
);
737 SockSetState (Sock
, SO_CLOSED
);
738 Sock
->ConfigureState
= SO_UNCONFIGURED
;
742 // Destory the RcvBuffer Queue and SendBuffer Queue
744 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
745 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
748 // Remove it from parent connection list if needed
750 if (Sock
->Parent
!= NULL
) {
752 RemoveEntryList (&(Sock
->ConnectionList
));
753 (Sock
->Parent
->ConnCnt
)--;
757 "SockDestory: Delete a unaccepted socket from parent"
758 "now conncnt is %d\n",
759 Sock
->Parent
->ConnCnt
)
766 // Set the protocol guid and driver binding handle
767 // in the light of Sock->SockType
769 ProtocolGuid
= &gEfiTcp4ProtocolGuid
;
772 // Retrieve the protocol installed on this sock
774 Status
= gBS
->OpenProtocol (
780 EFI_OPEN_PROTOCOL_GET_PROTOCOL
783 if (EFI_ERROR (Status
)) {
785 DEBUG ((EFI_D_ERROR
, "SockDestroy: Open protocol installed "
786 "on socket failed with %r\n", Status
));
792 // Uninstall the protocol installed on this sock
793 // in the light of Sock->SockType
795 gBS
->UninstallMultipleProtocolInterfaces (
803 gBS
->FreePool (Sock
);
811 @param Sock Pointer to the socket.
821 ASSERT (Sock
!= NULL
);
824 // Clear the flag in this socket
829 // Flush the SndBuffer and RcvBuffer of Sock
831 NetbufQueFlush (Sock
->SndBuffer
.DataQueue
);
832 NetbufQueFlush (Sock
->RcvBuffer
.DataQueue
);
835 // Signal the pending token
837 if (Sock
->ConnectionToken
!= NULL
) {
838 SIGNAL_TOKEN (Sock
->ConnectionToken
, Sock
->SockError
);
839 Sock
->ConnectionToken
= NULL
;
842 if (Sock
->CloseToken
!= NULL
) {
843 SIGNAL_TOKEN (Sock
->CloseToken
, Sock
->SockError
);
844 Sock
->CloseToken
= NULL
;
847 SockFlushPendingToken (Sock
, &(Sock
->ListenTokenList
));
848 SockFlushPendingToken (Sock
, &(Sock
->RcvTokenList
));
849 SockFlushPendingToken (Sock
, &(Sock
->SndTokenList
));
850 SockFlushPendingToken (Sock
, &(Sock
->ProcessingSndTokenList
));
853 // Destroy the pending connection, if it is a listening socket
855 if (SOCK_IS_LISTENING (Sock
)) {
856 while (!IsListEmpty (&Sock
->ConnectionList
)) {
857 Child
= NET_LIST_HEAD (
858 &Sock
->ConnectionList
,
863 SockDestroyChild (Child
);
874 Set the state of the socket.
876 @param Sock Pointer to the socket.
877 @param State The new state to be set.
891 Clone a new socket including its associated protocol control block.
893 @param Sock Pointer to the socket to be cloned.
895 @return Pointer to the newly cloned socket. If NULL, error condition occurred.
904 SOCK_INIT_DATA InitData
;
906 InitData
.BackLog
= Sock
->BackLog
;
907 InitData
.Parent
= Sock
;
908 InitData
.State
= Sock
->State
;
909 InitData
.ProtoHandler
= Sock
->ProtoHandler
;
910 InitData
.Type
= Sock
->Type
;
911 InitData
.RcvBufferSize
= Sock
->RcvBuffer
.HighWater
;
912 InitData
.SndBufferSize
= Sock
->SndBuffer
.HighWater
;
913 InitData
.DriverBinding
= Sock
->DriverBinding
;
914 InitData
.Protocol
= &(Sock
->NetProtocol
);
915 InitData
.CreateCallback
= Sock
->CreateCallback
;
916 InitData
.DestroyCallback
= Sock
->DestroyCallback
;
917 InitData
.Context
= Sock
->Context
;
918 InitData
.ProtoData
= Sock
->ProtoReserved
;
919 InitData
.DataSize
= sizeof (Sock
->ProtoReserved
);
921 ClonedSock
= SockCreate (&InitData
);
923 if (NULL
== ClonedSock
) {
924 DEBUG ((EFI_D_ERROR
, "SockClone: no resource to create a cloned sock\n"));
928 SockSetState (ClonedSock
, SO_CONNECTING
);
929 ClonedSock
->ConfigureState
= Sock
->ConfigureState
;
936 Called by the low layer protocol to indicate the socket a connection is
937 established. This function just changes the socket's state to SO_CONNECTED
938 and signals the token used for connection establishment.
940 @param Sock Pointer to the socket associated with the
941 established connection.
944 SockConnEstablished (
949 ASSERT (SO_CONNECTING
== Sock
->State
);
951 SockSetState (Sock
, SO_CONNECTED
);
953 if (NULL
== Sock
->Parent
) {
954 SockWakeConnToken (Sock
);
956 SockWakeListenToken (Sock
);
964 Called by the low layer protocol to indicate the connection is closed; This
965 function flushes the socket, sets the state to SO_CLOSED and signals the close
968 @param Sock Pointer to the socket associated with the closed
976 if (Sock
->CloseToken
!= NULL
) {
977 SIGNAL_TOKEN (Sock
->CloseToken
, EFI_SUCCESS
);
978 Sock
->CloseToken
= NULL
;
981 SockConnFlush (Sock
);
982 SockSetState (Sock
, SO_CLOSED
);
984 if (Sock
->Parent
!= NULL
) {
985 SockDestroyChild (Sock
);
992 Called by low layer protocol to indicate that some data is sent or processed;
993 This function trims the sent data in the socket send buffer, signals the data
996 @param Sock Pointer to the socket.
997 @param Count The length of the data processed or sent, in bytes.
1006 SOCK_TOKEN
*SockToken
;
1007 SOCK_COMPLETION_TOKEN
*SndToken
;
1009 ASSERT (!IsListEmpty (&Sock
->ProcessingSndTokenList
));
1010 ASSERT (Count
<= (Sock
->SndBuffer
.DataQueue
)->BufSize
);
1012 NetbufQueTrim (Sock
->SndBuffer
.DataQueue
, Count
);
1015 // To check if we can signal some snd token in this socket
1018 SockToken
= NET_LIST_HEAD (
1019 &(Sock
->ProcessingSndTokenList
),
1024 SndToken
= SockToken
->Token
;
1026 if (SockToken
->RemainDataLen
<= Count
) {
1028 RemoveEntryList (&(SockToken
->TokenList
));
1029 SIGNAL_TOKEN (SndToken
, EFI_SUCCESS
);
1030 Count
-= SockToken
->RemainDataLen
;
1031 gBS
->FreePool (SockToken
);
1034 SockToken
->RemainDataLen
-= Count
;
1040 // to judge if we can process some send token in
1041 // Sock->SndTokenList, if so process those send token
1043 SockProcessSndToken (Sock
);
1049 Called by the low layer protocol to copy some data in socket send
1050 buffer starting from the specific offset to a buffer provided by
1053 @param Sock Pointer to the socket.
1054 @param Offset The start point of the data to be copied.
1055 @param Len The length of the data to be copied.
1056 @param Dest Pointer to the destination to copy the data.
1058 @return The data size copied.
1069 ASSERT ((Sock
!= NULL
) && SOCK_STREAM
== Sock
->Type
);
1071 return NetbufQueCopy (
1072 Sock
->SndBuffer
.DataQueue
,
1081 Called by the low layer protocol to deliver received data to socket layer;
1082 This function will append the data to the socket receive buffer, set ther
1083 urgent data length and then check if any receive token can be signaled.
1085 @param Sock Pointer to the socket.
1086 @param NetBuffer Pointer to the buffer that contains the received
1088 @param UrgLen The length of the urgent data in the received data.
1094 IN NET_BUF
*NetBuffer
,
1098 ASSERT ((Sock
!= NULL
) && (Sock
->RcvBuffer
.DataQueue
!= NULL
) &&
1099 UrgLen
<= NetBuffer
->TotalSize
);
1101 NET_GET_REF (NetBuffer
);
1103 ((TCP_RSV_DATA
*) (NetBuffer
->ProtoData
))->UrgLen
= UrgLen
;
1105 NetbufQueAppend (Sock
->RcvBuffer
.DataQueue
, NetBuffer
);
1107 SockWakeRcvToken (Sock
);
1113 Get the length of the free space of the specific socket buffer.
1115 @param Sock Pointer to the socket.
1116 @param Which Flag to indicate which socket buffer to check,
1117 either send buffer or receive buffer.
1119 @return The length of the free space, in bytes.
1129 SOCK_BUFFER
*SockBuffer
;
1131 ASSERT ((Sock
!= NULL
) && ((SOCK_SND_BUF
== Which
) || (SOCK_RCV_BUF
== Which
)));
1133 if (SOCK_SND_BUF
== Which
) {
1134 SockBuffer
= &(Sock
->SndBuffer
);
1136 SockBuffer
= &(Sock
->RcvBuffer
);
1139 BufferCC
= (SockBuffer
->DataQueue
)->BufSize
;
1141 if (BufferCC
>= SockBuffer
->HighWater
) {
1146 return SockBuffer
->HighWater
- BufferCC
;
1151 Signal the receive token with the specific error or
1152 set socket error code after error is received.
1154 @param Sock Pointer to the socket.
1155 @param Error The error code received.
1164 SOCK_TOKEN
*SockToken
;
1166 if (!IsListEmpty (&Sock
->RcvTokenList
)) {
1168 SockToken
= NET_LIST_HEAD (
1169 &Sock
->RcvTokenList
,
1174 RemoveEntryList (&SockToken
->TokenList
);
1176 SIGNAL_TOKEN (SockToken
->Token
, Error
);
1178 gBS
->FreePool (SockToken
);
1181 SOCK_ERROR (Sock
, Error
);
1187 Called by the low layer protocol to indicate that there
1188 will be no more data from the communication peer; This
1189 function set the socket's state to SO_NO_MORE_DATA and
1190 signal all queued IO tokens with the error status
1193 @param Sock Pointer to the socket.
1203 SOCK_NO_MORE_DATA (Sock
);
1205 if (!IsListEmpty (&Sock
->RcvTokenList
)) {
1207 ASSERT (0 == GET_RCV_DATASIZE (Sock
));
1209 Err
= Sock
->SockError
;
1211 SOCK_ERROR (Sock
, EFI_CONNECTION_FIN
);
1213 SockFlushPendingToken (Sock
, &Sock
->RcvTokenList
);
1215 SOCK_ERROR (Sock
, Err
);
1223 Get the first buffer block in the specific socket buffer.
1225 @param Sockbuf Pointer to the socket buffer.
1227 @return Pointer to the first buffer in the queue. NULL if the queue is empty.
1232 IN SOCK_BUFFER
*Sockbuf
1235 LIST_ENTRY
*NetbufList
;
1237 NetbufList
= &(Sockbuf
->DataQueue
->BufList
);
1239 if (IsListEmpty (NetbufList
)) {
1243 return NET_LIST_HEAD (NetbufList
, NET_BUF
, List
);
1248 Get the next buffer block in the specific socket buffer.
1250 @param Sockbuf Pointer to the socket buffer.
1251 @param SockEntry Pointer to the buffer block prior to the required
1254 @return Pointer to the buffer block next to SockEntry. NULL if SockEntry is
1255 the tail or head entry.
1260 IN SOCK_BUFFER
*Sockbuf
,
1261 IN NET_BUF
*SockEntry
1264 LIST_ENTRY
*NetbufList
;
1266 NetbufList
= &(Sockbuf
->DataQueue
->BufList
);
1268 if ((SockEntry
->List
.ForwardLink
== NetbufList
) ||
1269 (SockEntry
->List
.BackLink
== &SockEntry
->List
) ||
1270 (SockEntry
->List
.ForwardLink
== &SockEntry
->List
)) {
1275 return NET_LIST_USER_STRUCT (SockEntry
->List
.ForwardLink
, NET_BUF
, List
);