/****************************************************************************
 * apps/netutils/tftpc/tftpc_put.c
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.  The
 * ASF licenses this file to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance with the
 * License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 * License for the specific language governing permissions and limitations
 * under the License.
 *
 ****************************************************************************/

/****************************************************************************
 * Included Files
 ****************************************************************************/

#include <nuttx/config.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <debug.h>

#include <nuttx/net/netconfig.h>
#include "netutils/tftp.h"

#include "tftpc_internal.h"

#if defined(CONFIG_NET) && defined(CONFIG_NET_UDP)

/****************************************************************************
 * Pre-processor Definitions
 ****************************************************************************/

#define TFTP_RETRIES 3

/****************************************************************************
 * Private Function Prototypes
 ****************************************************************************/

/****************************************************************************
 * Private Functions
 ****************************************************************************/

/****************************************************************************
 * Name: tftp_mkdatapacket
 *
 * Description:
 *   DATA message format:
 *
 *     2 bytes: Opcode (network order == big-endian)
 *     2 bytes: Block number (network order == big-endian)
 *     N bytes: Data (where N <= 512)
 *
 * Input Parameters:
 *   fd      - File descriptor used to read from the file
 *   offset  - File offset to read from
 *   packet  - Buffer to write the data packet into
 *   blockno - The block number of the packet
 *
 * Return Value:
 *   Number of bytes read into the packet. <TFTP_PACKETSIZE means end of
 *   file; <1 if an error occurs.
 *
 ****************************************************************************/

int tftp_mkdatapacket(off_t offset, FAR uint8_t *packet, uint16_t blockno,
                      tftp_callback_t tftp_cb, FAR void *ctx)
{
  int nbytesread;

  /* Format the DATA message header */

  packet[0] = TFTP_DATA >> 8;
  packet[1] = TFTP_DATA & 0xff;
  packet[2] = blockno >> 8;
  packet[3] = blockno & 0xff;

  nbytesread = tftp_cb(ctx, offset, &packet[TFTP_DATAHEADERSIZE],
                       TFTP_DATASIZE);
  if (nbytesread < 0)
    {
      return ERROR;
    }

  return nbytesread + TFTP_DATAHEADERSIZE;
}

/****************************************************************************
 * Name: tftp_rcvack
 *
 * Description:
 *   ACK message format:
 *
 *     2 bytes: Opcode (network order == big-endian)
 *     2 bytes: Block number (network order == big-endian)
 *
 * Input Parameters:
 *   sd      - Socket descriptor to use in in the transfer
 *   packet   - buffer to use for the transfers
 *   server  - The address of the server
 *   port    - The port number of the server (0 if not yet known)
 *   blockno - Location to return block number in the received ACK
 *
 * Returned Value:
 *   OK:success and blockno valid, ERROR:failure.
 *
 ****************************************************************************/

static int tftp_rcvack(int sd, FAR uint8_t *packet,
                       FAR struct sockaddr_in *server, FAR uint16_t *port,
                       FAR uint16_t *blockno)
{
  struct sockaddr_in from;     /* The address the last UDP msg recv'd from */
  ssize_t nbytes;              /* The number of bytes received. */
  uint16_t opcode;             /* The received opcode */
  uint16_t rblockno;           /* The received block number */
  int packetlen;               /* Packet length */
  int retry;                   /* Retry counter */

  /* Try up to TFTP_RETRIES times */

  for (retry = 0; retry < TFTP_RETRIES; retry++)
    {
      /* Try for until a valid ACK is received or some error occurs */

      for (; ; )
        {
          /* Receive the next UDP packet from the server */

          nbytes = tftp_recvfrom(sd, packet, TFTP_IOBUFSIZE, &from);
          if (nbytes < TFTP_ACKHEADERSIZE)
            {
              /* Failed to receive a good packet */

              if (nbytes == 0)
                {
                  nerr("ERROR: Connection lost: %zd bytes\n", nbytes);
                }
              else if (nbytes > 0)
                {
                  nerr("ERROR: Short packet: %zd bytes\n", nbytes);
                }
              else
                {
                  nerr("ERROR: Recvfrom failure\n");
                }

              /* Break out to bump up the retry count */

              break;
            }
          else
            {
              /* Get the port being used by the server if that has not yet
               * been established.
               */

              if (!*port)
                {
                  *port            = from.sin_port;
                  server->sin_port = from.sin_port;
                }

              /* Verify that the packet was received from the correct host
               * and port.
               */

              if (server->sin_addr.s_addr != from.sin_addr.s_addr)
                {
                  ninfo("Invalid address in DATA\n");
                  continue;
                }

              if (*port != server->sin_port)
                {
                  ninfo("Invalid port in DATA\n");
                  packetlen = tftp_mkerrpacket(packet, TFTP_ERR_UNKID,
                                               TFTP_ERRST_UNKID);
                  tftp_sendto(sd, packet, packetlen, server);
                  continue;
                }

              /* Parse the error message */

              opcode   = (uint16_t)packet[0] << 8 | (uint16_t)packet[1];
              rblockno = (uint16_t)packet[2] << 8 | (uint16_t)packet[3];

              /* Verify that the message that we received is an ACK for the
               * expected block number.
               */

              if (opcode != TFTP_ACK)
                {
                  nwarn("WARNING: Bad opcode\n");

#ifdef CONFIG_DEBUG_NET_WARN
                  if (opcode == TFTP_ERR)
                    {
                      tftp_parseerrpacket(packet);
                    }
                  else
#endif
                  if (opcode > TFTP_MAXRFC1350)
                    {
                      packetlen = tftp_mkerrpacket(packet,
                                                   TFTP_ERR_ILLEGALOP,
                                                   TFTP_ERRST_ILLEGALOP);
                      tftp_sendto(sd, packet, packetlen, server);
                    }

                  /* Break out an bump up the retry count */

                  break;
                }

              /* Success! */

              ninfo("Received ACK for block %d\n", rblockno);
              *blockno = rblockno;
              return OK;
            }
        }
    }

  /* We have tried TFTP_RETRIES times */

  nerr("ERROR: Timeout, Waiting for ACK\n");
  return ERROR; /* Will never get here */
}

/****************************************************************************
 * Public Functions
 ****************************************************************************/

/****************************************************************************
 * Name: tftpput_cb
 *
 * Input Parameters:
 *   remote - The name of the file on the TFTP server.
 *   addr   - The IP address of the server in network order
 *   binary - TRUE:  Perform binary ('octect') transfer
 *            FALSE: Perform text ('netascii') transfer
 *   cb     - callback that will be called with data packets
 *   ctx    - pointer passed to the previous callback
 *
 ****************************************************************************/

int tftpput_cb(FAR const char *remote, in_addr_t addr, bool binary,
               tftp_callback_t cb, FAR void *ctx)
{
  struct sockaddr_in server;         /* The address of the TFTP server */
  FAR uint8_t *packet;               /* Allocated memory to hold one packet */
  off_t offset;                      /* Offset into source file */
  uint16_t blockno;                  /* The current transfer block number */
  uint16_t rblockno;                 /* The ACK'ed block number */
  uint16_t port = 0;                 /* This is the port nbr for the transfer */
  int packetlen;                     /* The length of the data packet */
  int sd;                            /* Socket descriptor for socket I/O */
  int retry;                         /* Retry counter */
  int result = ERROR;                /* Assume failure */
  int ret;                           /* Generic return status */

  /* Allocate the buffer to used for socket/disk I/O */

  packet = (FAR uint8_t *)zalloc(TFTP_IOBUFSIZE);
  if (!packet)
    {
      nerr("ERROR: packet memory allocation failure\n");
      errno = ENOMEM;
      goto errout;
    }

  /* Initialize a UDP socket and setup the server address */

  sd = tftp_sockinit(&server, addr);
  if (sd < 0)
    {
      goto errout_with_packet;
    }

  /* Send the write request using the well known port.  This may need
   * to be done several times because (1) UDP is inherenly unreliable
   * and packets may be lost normally, and (2) uIP has a nasty habit
   * of droppying packets if there is nothing hit in the ARP table.
   */

  blockno = 1;
  retry   = 0;
  for (; ; )
    {
      packetlen = tftp_mkreqpacket(packet, TFTP_IOBUFSIZE,
                                   TFTP_WRQ, remote, binary);
      ret = tftp_sendto(sd, packet, packetlen, &server);
      if (ret != packetlen)
        {
          goto errout_with_sd;
        }

      /* Receive the ACK for the write request */

      if (tftp_rcvack(sd, packet, &server, &port, NULL) == 0)
        {
          break;
        }

      nwarn("WARNING: Re-sending request\n");

      /* We are going to loop and re-send the request packet. Check the
       * retry count so that we do not loop forever.
       */

      if (++retry > TFTP_RETRIES)
        {
          nerr("ERROR: Retry count exceeded\n");
          errno = ETIMEDOUT;
          goto errout_with_sd;
        }
    }

  /* Then loop sending the entire file to the server in chunks */

  offset     = 0;
  retry      = 0;

  for (; ; )
    {
      /* Construct the next data packet */

      packetlen = tftp_mkdatapacket(offset, packet, blockno, cb, ctx);
      if (packetlen < 0)
        {
          goto errout_with_sd;
        }

      /* Send the next data chunk */

      ret = tftp_sendto(sd, packet, packetlen, &server);
      if (ret != packetlen)
        {
          goto errout_with_sd;
        }

      /* Check for an ACK for the data chunk */

      if (tftp_rcvack(sd, packet, &server, &port, &rblockno) == OK)
        {
          /* Check if the packet that we just sent was ACK'ed.  If not,
           * we just loop to resend the same packet (same blockno, same
           * file offset).
           */

          if (rblockno == blockno)
            {
              /* Yes.. If we are at the end of the file and if all of the
               * packets have been ACKed, then we are done.
               */

              if (packetlen < TFTP_PACKETSIZE)
                {
                  break;
                }

              /* Not the last block.. set up for the next block */

              blockno += 1;
              offset  += TFTP_DATASIZE;
              retry    = 0;

              /* Skip the retry test */

              continue;
            }
        }

      /* We are going to loop and re-send the data packet. Check the retry
       * count so that we do not loop forever.
       */

      if (++retry > TFTP_RETRIES)
        {
          nerr("ERROR: Retry count exceeded\n");
          errno = ETIMEDOUT;
          goto errout_with_sd;
        }
    }

  /* Return success */

  result = OK;

errout_with_sd:
  close(sd);
errout_with_packet:
  free(packet);
errout:
  return result;
}

/****************************************************************************
 * Name: tftp_read
 ****************************************************************************/

static ssize_t tftp_read(FAR void *ctx, uint32_t offset, FAR uint8_t *buf,
                         size_t buflen)
{
  int fd = (intptr_t)ctx;
  off_t tmp;
  ssize_t nbytesread;
  ssize_t totalread = 0;

  /* Seek to the correct offset in the file */

  tmp = lseek(fd, offset, SEEK_SET);
  if (tmp == (off_t)-1)
    {
      nerr("ERROR: lseek failed: %d\n", errno);
      return ERROR;
    }

  /* Read the file data into the packet buffer */

  while (totalread < buflen)
    {
      /* Read the data... repeating the read in the event that it was
       * interrupted by a signal.
       */

      do
        {
          nbytesread = read(fd, buf, buflen - totalread);
        }
      while (nbytesread < 0 && errno == EINTR);

      /* Check for non-EINTR errors */

      if (nbytesread < 0)
        {
          nerr("ERROR: read failed: %d\n", errno);
          return ERROR;
        }

      /* Check for end of file */

      else if (nbytesread == 0)
        {
          break;
        }

      /* Handle partial reads.  Partial reads can happen normally
       * when the source is some device driver that returns data
       * in bits and pieces as received (such as a pipe)
       */

      totalread += nbytesread;
      buf       += nbytesread;
    }

  return totalread;
}

/****************************************************************************
 * Name: tftpput
 *
 * Input Parameters:
 *   local  - Path to the file system object to be sent.
 *   remote - The name of the file on the TFTP server.
 *   addr   - The IP address of the server in network order
 *   binary - TRUE:  Perform binary ('octect') transfer
 *            FALSE: Perform text ('netascii') transfer
 *
 ****************************************************************************/

int tftpput(FAR const char *local, FAR const char *remote, in_addr_t addr,
            bool binary)
{
  int fd;                            /* File descriptor for file I/O */
  int result = ERROR;                /* Assume failure */

  /* Open the file for reading */

  fd = open(local, O_RDONLY);
  if (fd < 0)
    {
      nerr("ERROR: open failed: %d\n", errno);
      goto errout;
    }

  result = tftpput_cb(remote, addr, binary, tftp_read,
                      (FAR void *)(intptr_t)fd);

  close(fd);

errout:
  return result;
}

#endif /* CONFIG_NET && CONFIG_NET_UDP */
