natftpclnt Sample Application using the TFTP client API
21 May 2008 - RSD


Overview
--------
    This application demonstrates the TFTP client API.  It is provided as a guide
    to enable the customer to quickly write their own TFTP client applications


Supported Platforms and Processors
----------------------------------
    This application is a network application requiring an Ethernet or WiFi 
    interface, thus can be run on any Digi International processor or platform.


Features and APIs being demonstrated
------------------------------------

    TFTP Client
    -----------
    - naTFTPstart(char *server_ip, int port)
    - naTFTPsend (char *serverfilename, char *filename, int xfermode, int drive)
    - naTFTPrecv (char *serverfilename, char *filename, int xfermode, int drive)
    - naTFTPstop (void)
    
    The features are tested by getting, via naTFTPrecv, files from a TFTP server and 
    then returning these files back, via naTFTPsend, to the server with different 
    filenames.  After the files have been transferred, the user can verify the files 
    are the same and verify that the files have been placed on the board successfully.


Required external equipment and setup
-------------------------------------
    This application requires an TFTP Server.


BSP Requirements
----------------
    This application requires (and the tftp library itself) requires the CLIB 
    Filesystem to be defined in platform bsp_fs.h file:

        #define BSP_INCLUDE_FILESYSTEM_FOR_CLIBRARY          TRUE


Customizable Application Parameters
-----------------------------------

    tftp server IP address and port
    -------------------------------
    The TFTP server and service port MUST first be configured.  These values are 
    currently hardcoded towards the top of root.c.

        #define  APP_SERVER_ADDRESS        "10.52.35.61"
        #define  APP_SERVER_PORT           69

    The TFTP server address must be entered as an IPv4 dotted notation address 
    (i.e., "XXX.XXX.XXX.XXX") and the server port is an integer.  The standard 
    service port for tftp is 69.  

    Replace these hardcoded values with those values required for your tftp 
    server.

    tftp server file requirements
    -----------------------------
    The application defines APP_FILE1 and APP_FILE2, as "readme.txt" and "rom.bin".
    The tftp server must have these two files residing in it's root directory:

    Note that rom.bin can be a binary file, but the readme.txt MUST be an ASCII file.

Running the Application
-----------------------

    The application starts in the function applicationStart() in the file root.c.
    This function does not create a thread.  It simply calls TFTP functions from 
    the tftp library.  

    After completion of the application, the tftp server file system should have 
    rom.bin copied to files FFrom.bin and RFrom.bin.  The file readme.txt should be written 
    to FF1.txt and RF2.txt.  The F and the R designator reflect that this file 
    traveled through the FLASH or RAM file system, respectively, on the embedded 
    platform.


Detailed Application Description
--------------------------------
This sample tests the TFTP Library by calling functions in the library.  The 
functions and what they do are listed below.

:: naTFTPstart

naTFTPstart will attempt to connect to a TFTP server.  Of course TFTP is based on
UDP so there is actually NO connection made.  This function will set all of the
necessary parameter, IP addresses and ports.  The function will return back an error
if it could not create the socket or bind the port to the socket.  This function
will return success as long as a socket is opened and a port is binded.  This means
that it could return success even if there is no TFTP Server at the specified address.
That error will be found in the send/recv functions when they attempt to send/recv data.

NOTE:: This is a blocking function.  This means that whatever thread calls it will be
suspended until naTFTPstart returns a value back to the calling thread.

:: naTFTPsend

naTFTPsend will attempt to send a file that is stored on the board to the TFTP server.
This function requires that naTFTPstart has been called and a connection has been 
set-up.  It will first check to make sure a connection is set-up.  After that it will
attempt to access the file and send it to the server.  If at any point there is an
error, and error code will be returned in the form of an int (refer to the tftp.h file
for specifics).  Will return TFTP_SUCCESS if successful.

server_filename should be the path on the server where the file is to be saved.  This could
be in the format filename.txt or fldr/filename.txt (as long as the folder "fldr" exists on
the server.  Otherwise an error packet will be received stating "File not found on server").
The local_filename is the file that is on the local device and will be sent to the server.
This string can be in the format filename.txt and fldr/filename.txt (again if the folder fldr
already exists on the board). The parameter mode is used to tell if the mode is NetAscii
or Binary.  This should be passed in as strings in all caps. If not in all caps will return
NA_INVALID_MODE.  The last parameter is store.  This will tell the function if local_filename
is stored on RAM0 or FLASH0.  These are the only accepted inputs and should be passed in as
all caps.  If not a NA_INVALID_STORE error will be returned.

NOTE:: This is a blocking function.  This means that whatever thread calls it will be
suspended until naTFTPsend returns a value back to the calling thread.

:: naTFTPrecv

naTFTPrecv will attempt to receive a file that is on the TFTP server and save to the 
boards RAM.  This function requires that naTFTPstart has been called and a connection 
has been set-up.  It will first check to make sure a connection is set-up.  After that
it will accept packets from the server and save the data to the boards RAM.  If at any
point there is an error, and error code will be returned in the form of an int (refer 
to the tftp.h file for specifics).  Will return TFTP_SUCCESS if successful.

server_filename should be the path on the server where the file is to be received from.
This could be in the format filename.txt or fldr/filename.txt (as long as the folder "fldr"
exists on the server. Otherwise an error packet will be received stating "File not found on server").
The local_filename is the file that is on the local device where the received file will be saved.
This string can be in the format filename.txt and fldr/filename.txt (again if the folder fldr
already exists on the board). The parameter mode is used to tell if the mode is NetAscii
or Binary.  This should be passed in as strings in all caps. If not in all caps will return
NA_INVALID_MODE.  The last parameter is store.  This will tell the function if local_filename
is stored on RAM0 or FLASH0.  These are the only accepted inputs and should be passed in as 
all caps.  If not a NA_INVALID_STORE error will be returned.

NOTE:: This is a blocking function.  This means that whatever thread calls it will be
suspended until naTFTPrecv returns a value back to the calling thread.

:: naTFTPstop

naTFTPstop will set all connection variables to 0.  After this function is called
naTFTPsend and naTFTPrecv will no longer do anything because the connection is no
longer set-up.
NOTE:: This is a blocking function.  This means that whatever thread calls it will be
suspended until naTFTPstop returns a value back to the calling thread.

APPLICATION FLOW
----------------
For the tftp server API to function properly, functions must be called in the proper 
sequnce.  Below are sample sequence calls that are correct, followed by some that 
will produce errors.

    Correct Sequences:
    ------------------
    Example 1:
        naTFTPstart
        naTFTPrecv    *** simply recv a file
        naTFTPstop

    Example 2:
        naTFTPstart
        naTFTPrecv    *** This example shows that you can 
        naTFTPrecv    *** have multiple send/recv between
        naTFTPsend    *** a naTFTPstart and naTFTPstop
        naTFTPstop
    
    Example 3:
        naTFTPstart
        naTFTPrecv    *** This example shows that you can
        naTFTPstop    *** start a connection, recv (or send)
        naTFTPstart   *** a file, stop the connection and then
        naTFTPsend    *** re-open the connection to send/recv again
        naTFTPstop
   
    Invalid Sequences:
    ------------------
    Example 1:
        naTFTPsend    *** need to have a start before send/recv data

    Example 2:
        naTFTPstart
        naTFTPrecv
        naTFTPstop
        naTFTPsend    *** need to have another start before this send
    
    Example 3:
        naTFTPstart
        naTFTPrecv    *** This example will NOT produce an error, but
        naTFTPsend    *** should call naTFTPstop to close the "connection".

    Example 4:
        naTFTPstart   *** This example will return a NATFTP_SESSION_ACTIVE
        naTFTPrecv    *** error on the second naTFTPstart.  But the application
        naTFTPstart   *** will continue and the naTFTPsend will send data according
        naTFTPsend    *** to the first naTFTPstart parameters.
        naTFTPstop
    

NOTE ABOUT STORING TO FLASH
If the user would like to store an file to flash it is allowed.  But the user should
be aware that flash memory is non-volatile memory.  Whatever is stored in flash will
stay in flash even when the board is powered down or restarted.  The user must delete
the files that are no longer needed from flash on there own, this sample does not do
that for them.  


KNOWN ISSUES

If the user tries to recv a file and store it to flash, but the file is larger than
the amount of space free on flash, the naTFTPrecv will return a TFTP_LOCAL_FS_FULL
error.  The file will NOT be deleted though and the flash memory will not be able to
receive any other new file because FLASH will be full.  The user must some how free
flash memory on their own.


The application uses the following files located in the
netos\src\linkerScripts directory.  These files are generated
when the BSP is built.

bootldr.dat     bootloader configuration file used to generate the
                file image.bin.  It controls the information placed
                in the bootloader header of the image.

image.ldr       GNU linker script used to build an image that can
                be debugged and used with the bootloader.
                
customize.ldr   Customizable GNU linker script
