//*****************************************************************************
//
// tftp.h - Public function prototypes and globals related to the lwIP TFTP
//          server.
//
// Copyright (c) 2009-2014 Texas Instruments Incorporated.  All rights reserved.
// Software License Agreement
// 
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
// 
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
// 
// This is part of revision 2.1.0.12573 of the Tiva Utility Library.
//
//*****************************************************************************

#ifndef __TFTP_H__
#define __TFTP_H__

//*****************************************************************************
//
// If building with a C++ compiler, make all of the definitions in this header
// have a C binding.
//
//*****************************************************************************
#ifdef __cplusplus
extern "C"
{
#endif

//*****************************************************************************
//
//! \addtogroup tftp_api
//! @{
//
//*****************************************************************************

//*****************************************************************************
//
//! TFTP error codes.  Note that this enum is mapped so that all positive
//! values match the TFTP protocol-defined error codes.
//
//*****************************************************************************
typedef enum
{
    TFTP_OK = -1,
    TFTP_ERR_NOT_DEFINED = 0,
    TFTP_FILE_NOT_FOUND = 1,
    TFTP_ACCESS_VIOLATION = 2,
    TFTP_DISK_FULL = 3,
    TFTP_ILLEGAL_OP = 4,
    TFTP_UNKNOWN_TID = 5,
    TFTP_FILE_EXISTS = 6,
    TFTP_NO_SUCH_USER = 7
}
tTFTPError;

//*****************************************************************************
//
//! TFTP file transfer modes.  This enum contains members defining ASCII
//! text transfer mode (TFTP_MODE_NETASCII), binary transfer mode
//! (TFTP_MODE_OCTET) and a marker for an invalid mode (TFTP_MODE_INVALID).
//
//*****************************************************************************
typedef enum
{
    TFTP_MODE_NETASCII,
    TFTP_MODE_OCTET,
    TFTP_MODE_INVALID
}
tTFTPMode;

//*****************************************************************************
//
//! Data transfer under TFTP is performed using fixed-size blocks.  This label
//! defines the size of a block of TFTP data.
//
//*****************************************************************************
#define TFTP_BLOCK_SIZE         512

//*****************************************************************************
//
// Callback function prototypes passed to TFTPInit.  These functions receive
// notification of incoming GET and PUT requests, allowing the client to decide
// whether to accept the request or not.
//
//*****************************************************************************
struct _tTFTPConnection;

typedef tTFTPError (*tTFTPRequest)(struct _tTFTPConnection *psTFTP, bool bGet,
                                   int8_t *pui8FileName, tTFTPMode eMode);
typedef tTFTPError (*tTFTPTransfer)(struct _tTFTPConnection *psTFTP);
typedef void (*tTFTPClose)(struct _tTFTPConnection *psTFTP);

//*****************************************************************************
//
//! The TFTP connection control structure.  This is passed to a client on all
//! callbacks relating to a given TFTP connection.  Depending upon the
//! callback, the client may need to fill in values to various fields or use
//! field values to determine where to transfer data from or to.
//
//*****************************************************************************
typedef struct _tTFTPConnection
{
    //
    //! Pointer to the start of the buffer into which GET data should be copied
    //! or from which PUT data should be read.
    //
    uint8_t *pui8Data;

    //
    //! The length of the data requested in response to a single pfnGetData
    //! callback or the size of the received data for a pfnPutData callback.
    //
    uint32_t ui32DataLength;

    //
    //! Count of remaining bytes to send during a GET request or the byte
    //! offset within a block during a PUT request.  The application must set
    //! this field to the size of the requested file during the tTFTPRequest
    // callback if a GET request is to be accepted.
    //
    uint32_t ui32DataRemaining;

    //
    //! Application function which is called whenever more data is required to
    //! satisfy a GET request.  The function must copy ui32DataLength bytes
    //! into the buffer pointed to by pui8Data.
    //
    tTFTPTransfer pfnGetData;

    //
    //! Application function which is called whenever a packet of file data is
    //! received during a PUT request.  The function must save the data to the
    //! target file using ui32BlockNum and ui32DataRemaining to indicate the
    //! position of the data in the file, and return an appropriate error code.
    //! Note that several calls to this function may be made for a given
    //! received TFTP block since the underlying networking stack may have
    //! split the TFTP packet between several packets and a callback is made
    //! for each of these.  This avoids the need for a 512 byte buffer.  The
    //! ui32DataRemaining is used in these cases to indicate the offset of the
    //! data within the current block.
    //
    tTFTPTransfer pfnPutData;

    //
    //! Application function which is called when the TFTP connection is to
    //! be closed.  The function should tidy up and free any resources
    //! associated with the connection prior to returning.
    //
    tTFTPClose pfnClose;

    //
    //! This field may be used by the client to store an application-specific
    //! pointer that will be accessible on all callbacks from the TFTP module
    //! relating to this connection.
    //
    uint8_t *pui8User;

    //
    //! Pointer to an error string which the client must fill in if reporting
    //! an error.  This string will be sent to the TFTP client in any case
    //! where pfnPutData or pfnGetData return a value other than TFTP_OK.
    //
    char *pcErrorString;

    //
    //! A pointer to the underlying UDP connection.  Applications must not
    //! modify this field.
    //
    struct udp_pcb *psPCB;

    //
    //! The current block number for an ongoing TFTP transfer.  Applications
    //! may read this value to determine which data to return on a pfnGetData
    //! callback or where to write incoming data on a pfnPutData callback but
    //! must not modify it.
    //
    uint32_t ui32BlockNum;
}
tTFTPConnection;

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

//*****************************************************************************
//
// Public function prototypes.
//
//*****************************************************************************
extern void TFTPInit(tTFTPRequest pfnRequest);

//*****************************************************************************
//
// Mark the end of the C bindings section for C++ compilers.
//
//*****************************************************************************
#ifdef __cplusplus
}
#endif

#endif // __TFTP_H__