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
;
86 ASSERT ((SockBuffer
!= NULL
) && (IsUrg
!= NULL
) && (BufLen
> 0));
88 RcvBufEntry
= SockBufFirst (SockBuffer
);
89 ASSERT (RcvBufEntry
!= NULL
);
91 TcpRsvData
= (TCP_RSV_DATA
*) RcvBufEntry
->ProtoData
;
93 *IsUrg
= (BOOLEAN
) ((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
95 if (*IsUrg
&& TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
) {
97 DataLen
= MIN (TcpRsvData
->UrgLen
, BufLen
);
99 if (DataLen
< TcpRsvData
->UrgLen
) {
100 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- DataLen
;
102 TcpRsvData
->UrgLen
= 0;
109 DataLen
= RcvBufEntry
->TotalSize
;
111 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
113 while ((BufLen
> DataLen
) && (RcvBufEntry
!= NULL
)) {
115 TcpRsvData
= (TCP_RSV_DATA
*) RcvBufEntry
->ProtoData
;
117 Urg
= (BOOLEAN
) ((TcpRsvData
->UrgLen
> 0) ? TRUE
: FALSE
);
123 if (*IsUrg
&& TcpRsvData
->UrgLen
< RcvBufEntry
->TotalSize
) {
125 if (TcpRsvData
->UrgLen
+ DataLen
< BufLen
) {
126 TcpRsvData
->UrgLen
= 0;
128 TcpRsvData
->UrgLen
= TcpRsvData
->UrgLen
- (BufLen
- DataLen
);
131 return MIN (TcpRsvData
->UrgLen
+ DataLen
, BufLen
);
135 DataLen
+= RcvBufEntry
->TotalSize
;
137 RcvBufEntry
= SockBufNext (SockBuffer
, RcvBufEntry
);
140 DataLen
= MIN (BufLen
, DataLen
);
146 Copy data from socket buffer to application provided receive buffer.
148 @param Sock Pointer to the socket.
149 @param TcpRxData Pointer to the application provided receive buffer.
150 @param RcvdBytes The maximum length of the data can be copied.
151 @param IsOOB If TURE the data is OOB, FALSE the data is normal.
165 EFI_TCP4_RECEIVE_DATA
*RxData
;
166 EFI_TCP4_FRAGMENT_DATA
*Fragment
;
168 RxData
= (EFI_TCP4_RECEIVE_DATA
*) TcpRxData
;
172 ASSERT (RxData
->DataLength
>= RcvdBytes
);
174 RxData
->DataLength
= RcvdBytes
;
175 RxData
->UrgentFlag
= IsOOB
;
177 for (Index
= 0; (Index
< RxData
->FragmentCount
) && (RcvdBytes
> 0); Index
++) {
179 Fragment
= &RxData
->FragmentTable
[Index
];
180 CopyBytes
= MIN ((UINT32
) (Fragment
->FragmentLength
), RcvdBytes
);
183 Sock
->RcvBuffer
.DataQueue
,
186 Fragment
->FragmentBuffer
189 Fragment
->FragmentLength
= CopyBytes
;
190 RcvdBytes
-= CopyBytes
;
197 Get received data from the socket layer to the receive token.
199 @param Sock Pointer to the socket.
200 @param RcvToken Pointer to the application provided receive token.
202 @return The length of data received in this token.
206 SockProcessRcvToken (
208 IN OUT SOCK_IO_TOKEN
*RcvToken
211 UINT32 TokenRcvdBytes
;
212 EFI_TCP4_RECEIVE_DATA
*RxData
;
215 ASSERT (Sock
!= NULL
);
217 ASSERT (SOCK_STREAM
== Sock
->Type
);
219 RxData
= RcvToken
->Packet
.RxData
;
221 TokenRcvdBytes
= SockTcpDataToRcv (
224 (UINT32
) RxData
->DataLength
228 // Copy data from RcvBuffer of socket to user
229 // provided RxData and set the fields in TCP RxData
231 SockSetTcpRxData (Sock
, RxData
, TokenRcvdBytes
, IsUrg
);
233 NetbufQueTrim (Sock
->RcvBuffer
.DataQueue
, TokenRcvdBytes
);
234 SIGNAL_TOKEN (&(RcvToken
->Token
), EFI_SUCCESS
);
236 return TokenRcvdBytes
;
241 Process the TCP send data, buffer the tcp txdata and append
242 the buffer to socket send buffer,then try to send it.
244 @param Sock Pointer to the socket.
245 @param TcpTxData Pointer to the application provided send buffer.
247 @retval EFI_SUCCESS The operation is completed successfully.
248 @retval EFI_OUT_OF_RESOURCES Failed due to resource limit.
252 SockProcessTcpSndData (
259 EFI_TCP4_TRANSMIT_DATA
*TxData
;
261 TxData
= (EFI_TCP4_TRANSMIT_DATA
*) TcpTxData
;
264 // transform this TxData into a NET_BUFFER
265 // and insert it into Sock->SndBuffer
267 SndData
= NetbufFromExt (
268 (NET_FRAGMENT
*) TxData
->FragmentTable
,
269 (UINT32
) TxData
->FragmentCount
,
276 if (NULL
== SndData
) {
277 DEBUG ((EFI_D_ERROR
, "SockKProcessSndData: Failed to"
278 " call NetBufferFromExt\n"));
280 return EFI_OUT_OF_RESOURCES
;
283 NetbufQueAppend (Sock
->SndBuffer
.DataQueue
, SndData
);
286 // notify the low layer protocol to handle this send token
288 if (TxData
->Urgent
) {
289 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDURG
, NULL
);
291 if (EFI_ERROR (Status
)) {
297 Status
= Sock
->ProtoHandler (Sock
, SOCK_SNDPUSH
, NULL
);
299 if (EFI_ERROR (Status
)) {
305 // low layer protocol should really handle the sending
306 // process when catching SOCK_SND request
308 Status
= Sock
->ProtoHandler (Sock
, SOCK_SND
, NULL
);
310 if (EFI_ERROR (Status
)) {
319 Flush the tokens in the specific token list.
321 @param Sock Pointer to the socket.
322 @param PendingTokenList Pointer to the token list to be flushed.
326 SockFlushPendingToken (
328 IN LIST_ENTRY
*PendingTokenList
331 SOCK_TOKEN
*SockToken
;
332 SOCK_COMPLETION_TOKEN
*Token
;
334 ASSERT ((Sock
!= NULL
) && (PendingTokenList
!= NULL
));
336 while (!IsListEmpty (PendingTokenList
)) {
337 SockToken
= NET_LIST_HEAD (
343 Token
= SockToken
->Token
;
344 SIGNAL_TOKEN (Token
, Sock
->SockError
);
346 RemoveEntryList (&(SockToken
->TokenList
));
347 gBS
->FreePool (SockToken
);
353 Wake up the connection token while the connection is successfully established,
354 then try to process any pending send token.
356 @param Sock Pointer to the socket.
364 ASSERT (Sock
->ConnectionToken
!= NULL
);
366 SIGNAL_TOKEN (Sock
->ConnectionToken
, EFI_SUCCESS
);
367 Sock
->ConnectionToken
= NULL
;
370 // check to see if some pending send token existed?
372 SockProcessSndToken (Sock
);
378 Wake up the listen token while the connection is established successfully.
380 @param Sock Pointer to the socket.
384 SockWakeListenToken (
389 SOCK_TOKEN
*SockToken
;
390 EFI_TCP4_LISTEN_TOKEN
*ListenToken
;
392 Parent
= Sock
->Parent
;
394 ASSERT ((Parent
!= NULL
) && SOCK_IS_LISTENING (Parent
) && SOCK_IS_CONNECTED (Sock
));
396 if (!IsListEmpty (&Parent
->ListenTokenList
)) {
397 SockToken
= NET_LIST_HEAD (
398 &Parent
->ListenTokenList
,
403 ListenToken
= (EFI_TCP4_LISTEN_TOKEN
*) SockToken
->Token
;
404 ListenToken
->NewChildHandle
= Sock
->SockHandle
;
406 SIGNAL_TOKEN (&(ListenToken
->CompletionToken
), EFI_SUCCESS
);
408 RemoveEntryList (&SockToken
->TokenList
);
409 gBS
->FreePool (SockToken
);
411 RemoveEntryList (&Sock
->ConnectionList
);
414 DEBUG ((EFI_D_INFO
, "SockWakeListenToken: accept a socket, now conncnt is %d", Parent
->ConnCnt
));
422 Wake up the receive token while some data is received.
424 @param Sock Pointer to the socket.
433 UINT32 TokenRcvdBytes
;
434 SOCK_TOKEN
*SockToken
;
435 SOCK_IO_TOKEN
*RcvToken
;
437 ASSERT (Sock
->RcvBuffer
.DataQueue
!= NULL
);
439 RcvdBytes
= (Sock
->RcvBuffer
.DataQueue
)->BufSize
;
441 ASSERT (RcvdBytes
> 0);
443 while (RcvdBytes
> 0 && !IsListEmpty (&Sock
->RcvTokenList
)) {
445 SockToken
= NET_LIST_HEAD (
451 RcvToken
= (SOCK_IO_TOKEN
*) SockToken
->Token
;
452 TokenRcvdBytes
= SockProcessRcvToken (Sock
, RcvToken
);
454 if (0 == TokenRcvdBytes
) {
458 RemoveEntryList (&(SockToken
->TokenList
));
459 gBS
->FreePool (SockToken
);
460 RcvdBytes
-= TokenRcvdBytes
;
466 Process the send token.
468 @param Sock Pointer to the socket.
472 SockProcessSndToken (
477 SOCK_TOKEN
*SockToken
;
479 SOCK_IO_TOKEN
*SndToken
;
480 EFI_TCP4_TRANSMIT_DATA
*TxData
;
483 ASSERT ((Sock
!= NULL
) && (SOCK_STREAM
== Sock
->Type
));
485 FreeSpace
= SockGetFreeSpace (Sock
, SOCK_SND_BUF
);
488 // to determine if process a send token using
489 // socket layer flow control policy
491 while ((FreeSpace
>= Sock
->SndBuffer
.LowWater
) &&
492 !IsListEmpty (&Sock
->SndTokenList
)) {
494 SockToken
= NET_LIST_HEAD (
495 &(Sock
->SndTokenList
),
501 // process this token
503 RemoveEntryList (&(SockToken
->TokenList
));
505 &(Sock
->ProcessingSndTokenList
),
506 &(SockToken
->TokenList
)
510 // Proceess it in the light of SockType
512 SndToken
= (SOCK_IO_TOKEN
*) SockToken
->Token
;
513 TxData
= SndToken
->Packet
.TxData
;
515 DataLen
= (UINT32
) TxData
->DataLength
;
516 Status
= SockProcessTcpSndData (Sock
, TxData
);
518 if (EFI_ERROR (Status
)) {
522 if (DataLen
>= FreeSpace
) {
526 FreeSpace
-= DataLen
;
535 RemoveEntryList (&SockToken
->TokenList
);
536 SIGNAL_TOKEN (SockToken
->Token
, Status
);
537 gBS
->FreePool (SockToken
);
542 Create a socket with initial data SockInitData.
544 @param SockInitData Pointer to the initial data of the socket.
546 @return Pointer to the newly created socket, return NULL when exception occured.
551 IN SOCK_INIT_DATA
*SockInitData
558 ASSERT ((SockInitData
!= NULL
) && (SockInitData
->ProtoHandler
!= NULL
));
559 ASSERT (SockInitData
->Type
== SOCK_STREAM
);
560 ASSERT ((SockInitData
->ProtoData
!= NULL
) && (SockInitData
->DataSize
<= PROTO_RESERVED_LEN
));
562 Parent
= SockInitData
->Parent
;
564 if ((Parent
!= NULL
) && (Parent
->ConnCnt
== Parent
->BackLog
)) {
567 "SockCreate: Socket parent has "
568 "reached its connection limit with %d ConnCnt and %d BackLog\n",
576 Sock
= AllocateZeroPool (sizeof (SOCKET
));
579 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to create a new socket\n"));
583 InitializeListHead (&Sock
->Link
);
584 InitializeListHead (&Sock
->ConnectionList
);
585 InitializeListHead (&Sock
->ListenTokenList
);
586 InitializeListHead (&Sock
->RcvTokenList
);
587 InitializeListHead (&Sock
->SndTokenList
);
588 InitializeListHead (&Sock
->ProcessingSndTokenList
);
590 EfiInitializeLock (&(Sock
->Lock
), TPL_CALLBACK
);
592 Sock
->SndBuffer
.DataQueue
= NetbufQueAlloc ();
593 if (NULL
== Sock
->SndBuffer
.DataQueue
) {
594 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to allocate"
595 " SndBuffer for new socket\n"));
600 Sock
->RcvBuffer
.DataQueue
= NetbufQueAlloc ();
601 if (NULL
== Sock
->RcvBuffer
.DataQueue
) {
602 DEBUG ((EFI_D_ERROR
, "SockCreate: No resource to allocate "
603 "RcvBuffer for new socket\n"));
608 Sock
->Signature
= SOCK_SIGNATURE
;
610 Sock
->Parent
= Parent
;
611 Sock
->BackLog
= SockInitData
->BackLog
;
612 Sock
->ProtoHandler
= SockInitData
->ProtoHandler
;
613 Sock
->SndBuffer
.HighWater
= SockInitData
->SndBufferSize
;
614 Sock
->RcvBuffer
.HighWater
= SockInitData
->RcvBufferSize
;
615 Sock
->Type
= SockInitData
->Type
;
616 Sock
->DriverBinding
= SockInitData
->DriverBinding
;
617 Sock
->State
= SockInitData
->State
;
618 Sock
->CreateCallback
= SockInitData
->CreateCallback
;
619 Sock
->DestroyCallback
= SockInitData
->DestroyCallback
;
620 Sock
->Context
= SockInitData
->Context
;
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
)
636 // copy the protodata into socket
638 CopyMem (Sock
->ProtoReserved
, SockInitData
->ProtoData
, SockInitData
->DataSize
);
640 Status
= gBS
->InstallMultipleProtocolInterfaces (
642 &gEfiTcp4ProtocolGuid
,
643 &(Sock
->NetProtocol
.TcpProtocol
),
647 if (EFI_ERROR (Status
)) {
648 DEBUG ((EFI_D_ERROR
, "SockCreate: Install TCP protocol in "
649 "socket failed with %r\n", Status
));
654 if (Parent
!= NULL
) {
655 ASSERT (Parent
->BackLog
> 0);
656 ASSERT (SOCK_IS_LISTENING (Parent
));
659 // need to add it into Parent->ConnectionList
660 // if the Parent->ConnCnt < Parent->BackLog
666 "SockCreate: Create a new socket and add to parent, now conncnt is %d\n",
670 InsertTailList (&Parent
->ConnectionList
, &Sock
->ConnectionList
);
673 if (Sock
->CreateCallback
!= NULL
) {
674 Status
= Sock
->CreateCallback (Sock
, Sock
->Context
);
675 if (EFI_ERROR (Status
)) {
684 if (Sock
->SockHandle
!= NULL
) {
685 gBS
->UninstallMultipleProtocolInterfaces (
687 &gEfiTcp4ProtocolGuid
,
688 &(Sock
->NetProtocol
.TcpProtocol
),
693 if (NULL
!= Sock
->SndBuffer
.DataQueue
) {
694 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
697 if (NULL
!= Sock
->RcvBuffer
.DataQueue
) {
698 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
701 gBS
->FreePool (Sock
);
710 @param Sock Pointer to the socket.
719 EFI_GUID
*ProtocolGuid
;
722 ASSERT (SOCK_STREAM
== Sock
->Type
);
724 if (Sock
->DestroyCallback
!= NULL
) {
725 Sock
->DestroyCallback (Sock
, Sock
->Context
);
729 // Flush the completion token buffered
730 // by sock and rcv, snd buffer
732 if (!SOCK_IS_UNCONFIGURED (Sock
)) {
734 SockConnFlush (Sock
);
735 SockSetState (Sock
, SO_CLOSED
);
736 Sock
->ConfigureState
= SO_UNCONFIGURED
;
740 // Destory the RcvBuffer Queue and SendBuffer Queue
742 NetbufQueFree (Sock
->RcvBuffer
.DataQueue
);
743 NetbufQueFree (Sock
->SndBuffer
.DataQueue
);
746 // Remove it from parent connection list if needed
748 if (Sock
->Parent
!= NULL
) {
750 RemoveEntryList (&(Sock
->ConnectionList
));
751 (Sock
->Parent
->ConnCnt
)--;
755 "SockDestory: Delete a unaccepted socket from parent"
756 "now conncnt is %d\n",
757 Sock
->Parent
->ConnCnt
)
764 // Set the protocol guid and driver binding handle
765 // in the light of Sock->SockType
767 ProtocolGuid
= &gEfiTcp4ProtocolGuid
;
770 // Retrieve the protocol installed on this sock
772 Status
= gBS
->OpenProtocol (
778 EFI_OPEN_PROTOCOL_GET_PROTOCOL
781 if (EFI_ERROR (Status
)) {
783 DEBUG ((EFI_D_ERROR
, "SockDestroy: Open protocol installed "
784 "on socket failed with %r\n", Status
));
790 // Uninstall the protocol installed on this sock
791 // in the light of Sock->SockType
793 gBS
->UninstallMultipleProtocolInterfaces (
801 gBS
->FreePool (Sock
);
807 Flush the sndBuffer and rcvBuffer of socket.
809 @param Sock Pointer to the socket.
819 ASSERT (Sock
!= NULL
);
822 // Clear the flag in this socket
827 // Flush the SndBuffer and RcvBuffer of Sock
829 NetbufQueFlush (Sock
->SndBuffer
.DataQueue
);
830 NetbufQueFlush (Sock
->RcvBuffer
.DataQueue
);
833 // Signal the pending token
835 if (Sock
->ConnectionToken
!= NULL
) {
836 SIGNAL_TOKEN (Sock
->ConnectionToken
, Sock
->SockError
);
837 Sock
->ConnectionToken
= NULL
;
840 if (Sock
->CloseToken
!= NULL
) {
841 SIGNAL_TOKEN (Sock
->CloseToken
, Sock
->SockError
);
842 Sock
->CloseToken
= NULL
;
845 SockFlushPendingToken (Sock
, &(Sock
->ListenTokenList
));
846 SockFlushPendingToken (Sock
, &(Sock
->RcvTokenList
));
847 SockFlushPendingToken (Sock
, &(Sock
->SndTokenList
));
848 SockFlushPendingToken (Sock
, &(Sock
->ProcessingSndTokenList
));
851 // Destroy the pending connection, if it is a listening socket
853 if (SOCK_IS_LISTENING (Sock
)) {
854 while (!IsListEmpty (&Sock
->ConnectionList
)) {
855 Child
= NET_LIST_HEAD (
856 &Sock
->ConnectionList
,
861 SockDestroyChild (Child
);
872 Set the state of the socket.
874 @param Sock Pointer to the socket.
875 @param State The new state to be set.
889 Clone a new socket including its associated protocol control block.
891 @param Sock Pointer to the socket to be cloned.
893 @return Pointer to the newly cloned socket. If NULL, error condition occurred.
902 SOCK_INIT_DATA InitData
;
904 InitData
.BackLog
= Sock
->BackLog
;
905 InitData
.Parent
= Sock
;
906 InitData
.State
= Sock
->State
;
907 InitData
.ProtoHandler
= Sock
->ProtoHandler
;
908 InitData
.Type
= Sock
->Type
;
909 InitData
.RcvBufferSize
= Sock
->RcvBuffer
.HighWater
;
910 InitData
.SndBufferSize
= Sock
->SndBuffer
.HighWater
;
911 InitData
.DriverBinding
= Sock
->DriverBinding
;
912 InitData
.Protocol
= &(Sock
->NetProtocol
);
913 InitData
.CreateCallback
= Sock
->CreateCallback
;
914 InitData
.DestroyCallback
= Sock
->DestroyCallback
;
915 InitData
.Context
= Sock
->Context
;
916 InitData
.ProtoData
= Sock
->ProtoReserved
;
917 InitData
.DataSize
= sizeof (Sock
->ProtoReserved
);
919 ClonedSock
= SockCreate (&InitData
);
921 if (NULL
== ClonedSock
) {
922 DEBUG ((EFI_D_ERROR
, "SockClone: no resource to create a cloned sock\n"));
926 SockSetState (ClonedSock
, SO_CONNECTING
);
927 ClonedSock
->ConfigureState
= Sock
->ConfigureState
;
934 Called by the low layer protocol to indicate the socket a connection is
937 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.
966 This function flushes the socket, sets the state to SO_CLOSED and signals
969 @param Sock Pointer to the socket associated with the closed
978 if (Sock
->CloseToken
!= NULL
) {
979 SIGNAL_TOKEN (Sock
->CloseToken
, EFI_SUCCESS
);
980 Sock
->CloseToken
= NULL
;
983 SockConnFlush (Sock
);
984 SockSetState (Sock
, SO_CLOSED
);
986 if (Sock
->Parent
!= NULL
) {
987 SockDestroyChild (Sock
);
994 Called by low layer protocol to indicate that some data is sent or processed.
996 This function trims the sent data in the socket send buffer, signals the data
999 @param Sock Pointer to the socket.
1000 @param Count The length of the data processed or sent, in bytes.
1009 SOCK_TOKEN
*SockToken
;
1010 SOCK_COMPLETION_TOKEN
*SndToken
;
1012 ASSERT (!IsListEmpty (&Sock
->ProcessingSndTokenList
));
1013 ASSERT (Count
<= (Sock
->SndBuffer
.DataQueue
)->BufSize
);
1015 NetbufQueTrim (Sock
->SndBuffer
.DataQueue
, Count
);
1018 // To check if we can signal some snd token in this socket
1021 SockToken
= NET_LIST_HEAD (
1022 &(Sock
->ProcessingSndTokenList
),
1027 SndToken
= SockToken
->Token
;
1029 if (SockToken
->RemainDataLen
<= Count
) {
1031 RemoveEntryList (&(SockToken
->TokenList
));
1032 SIGNAL_TOKEN (SndToken
, EFI_SUCCESS
);
1033 Count
-= SockToken
->RemainDataLen
;
1034 gBS
->FreePool (SockToken
);
1037 SockToken
->RemainDataLen
-= Count
;
1043 // to judge if we can process some send token in
1044 // Sock->SndTokenList, if so process those send token
1046 SockProcessSndToken (Sock
);
1052 Called by the low layer protocol to copy some data in socket send
1053 buffer starting from the specific offset to a buffer provided by
1056 @param Sock Pointer to the socket.
1057 @param Offset The start point of the data to be copied.
1058 @param Len The length of the data to be copied.
1059 @param Dest Pointer to the destination to copy the data.
1061 @return The data size copied.
1072 ASSERT ((Sock
!= NULL
) && SOCK_STREAM
== Sock
->Type
);
1074 return NetbufQueCopy (
1075 Sock
->SndBuffer
.DataQueue
,
1084 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 OUT 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.
1164 IN OUT SOCKET
*Sock
,
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 will be no more data
1192 from the communication peer.
1194 This function set the socket's state to SO_NO_MORE_DATA and signal all queued
1195 IO tokens with the error status EFI_CONNECTION_FIN.
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
);