/** @file
  Implementation of I/O interfaces between TCP and IpIoLib.

  Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "TcpMain.h"

/**
  Packet receive callback function provided to IP_IO, used to call
  the proper function to handle the packet received by IP.

  @param[in] Status        Result of the receive request.
  @param[in] IcmpErr       Valid when Status is EFI_ICMP_ERROR.
  @param[in] NetSession    The IP session for the received packet.
  @param[in] Pkt           Packet received.
  @param[in] Context       The data provided by the user for the received packet when
                           the callback is registered in IP_IO_OPEN_DATA::RcvdContext.
                           This is an optional parameter that may be NULL.

**/
VOID
EFIAPI
TcpRxCallback (
  IN EFI_STATUS                       Status,
  IN UINT8                            IcmpErr,
  IN EFI_NET_SESSION_DATA             *NetSession,
  IN NET_BUF                          *Pkt,
  IN VOID                             *Context    OPTIONAL
  )
{
  if (EFI_SUCCESS == Status) {
    TcpInput (Pkt, &NetSession->Source, &NetSession->Dest, NetSession->IpVersion);
  } else {
    TcpIcmpInput (
      Pkt,
      IcmpErr,
      &NetSession->Source,
      &NetSession->Dest,
      NetSession->IpVersion
      );
  }
}

/**
  Send the segment to IP via IpIo function.

  @param[in]  Tcb                Pointer to the TCP_CB of this TCP instance.
  @param[in]  Nbuf               Pointer to the TCP segment to be sent.
  @param[in]  Src                Source address of the TCP segment.
  @param[in]  Dest               Destination address of the TCP segment.
  @param[in]  Version            IP_VERSION_4 or IP_VERSION_6

  @retval 0                      The segment was sent out successfully.
  @retval -1                     The segment failed to send.

**/
INTN
TcpSendIpPacket (
  IN TCP_CB          *Tcb,
  IN NET_BUF         *Nbuf,
  IN EFI_IP_ADDRESS  *Src,
  IN EFI_IP_ADDRESS  *Dest,
  IN UINT8           Version
  )
{
  EFI_STATUS       Status;
  IP_IO            *IpIo;
  IP_IO_OVERRIDE   Override;
  SOCKET           *Sock;
  VOID             *IpSender;
  TCP_PROTO_DATA  *TcpProto;

  if (NULL == Tcb) {

    IpIo     = NULL;
    IpSender = IpIoFindSender (&IpIo, Version, Src);

    if (IpSender == NULL) {
      DEBUG ((EFI_D_WARN, "TcpSendIpPacket: No appropriate IpSender.\n"));
      return -1;
    }

    if (Version == IP_VERSION_6) {
      //
      // It's tricky here. EFI IPv6 Spec don't allow an instance overriding the
      // destination address if the dest is already specified through the
      // configuration data. Here we get the IpIo we need and use the default IP
      // instance in this IpIo to send the packet. The dest address is configured
      // to be the unspecified address for the default IP instance.
      //
      IpSender = NULL;
    }
  } else {

    Sock     = Tcb->Sk;
    TcpProto = (TCP_PROTO_DATA *) Sock->ProtoReserved;
    IpIo     = TcpProto->TcpService->IpIo;
    IpSender = Tcb->IpInfo;

    if (Version == IP_VERSION_6) {
      //
      // It's IPv6 and this TCP segment belongs to a solid TCB, in such case
      // the destination address can't be overridden, so reset the Dest to NULL.
      //
      if (!Tcb->RemoteIpZero) {
        Dest = NULL;
      }
    }
  }

  ASSERT (Version == IpIo->IpVersion);

  if (Version == IP_VERSION_4) {
    Override.Ip4OverrideData.TypeOfService = 0;
    Override.Ip4OverrideData.TimeToLive    = 255;
    Override.Ip4OverrideData.DoNotFragment = FALSE;
    Override.Ip4OverrideData.Protocol      = EFI_IP_PROTO_TCP;
    ZeroMem (&Override.Ip4OverrideData.GatewayAddress, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Override.Ip4OverrideData.SourceAddress, Src, sizeof (EFI_IPv4_ADDRESS));
  } else {
    Override.Ip6OverrideData.Protocol  = EFI_IP_PROTO_TCP;
    Override.Ip6OverrideData.HopLimit  = 255;
    Override.Ip6OverrideData.FlowLabel = 0;
  }

  Status = IpIoSend (IpIo, Nbuf, IpSender, NULL, NULL, Dest, &Override);

  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_ERROR, "TcpSendIpPacket: return %r error\n", Status));
    return -1;
  }

  return 0;
}

/**
  Refresh the remote peer's Neighbor Cache State if already exists.

  @param[in]  Tcb                Pointer to the TCP_CB of this TCP instance.
  @param[in]  Neighbor           Source address of the TCP segment.
  @param[in]  Timeout            Time in 100-ns units that this entry will remain
                                 in the neighbor cache. A value of zero means that
                                 the entry  is permanent. A value of non-zero means
                                 that the entry is dynamic and will be deleted
                                 after Timeout.

  @retval EFI_SUCCESS            Successfully updated the neighbor relationship.
  @retval EFI_NOT_STARTED        The IpIo is not configured.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.
  @retval EFI_OUT_OF_RESOURCES   Failed to allocate some resources.
  @retval EFI_NOT_FOUND          This entry is not in the neighbor table.

**/
EFI_STATUS
Tcp6RefreshNeighbor (
  IN TCP_CB          *Tcb,
  IN EFI_IP_ADDRESS  *Neighbor,
  IN UINT32          Timeout
  )
{
  IP_IO            *IpIo;
  SOCKET           *Sock;
  TCP_PROTO_DATA  *TcpProto;

  if (NULL == Tcb) {
    IpIo = NULL;
    IpIoFindSender (&IpIo, IP_VERSION_6, Neighbor);

    if (IpIo == NULL) {
      DEBUG ((EFI_D_WARN, "Tcp6AddNeighbor: No appropriate IpIo.\n"));
      return EFI_NOT_STARTED;
    }

  } else {
    Sock     = Tcb->Sk;
    TcpProto = (TCP_PROTO_DATA *) Sock->ProtoReserved;
    IpIo     = TcpProto->TcpService->IpIo;
  }

  return IpIoRefreshNeighbor (IpIo, Neighbor, Timeout);
}

