⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tftpc.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
/*************************************************************************
*                                                                       
*        Copyright (c) 1993 - 2001 Accelerated Technology, Inc.           
*                                                                       
* PROPRIETARY RIGHTS of Accelerated Technology are involved in the      
* subject matter of this material.  All manufacturing, reproduction,    
* use, and sales rights pertaining to this subject matter are governed  
* by the license agreement.  The recipient of this software implicitly  
* accepts the terms of the license.                                     
*                                                                       
*************************************************************************/

/*************************************************************************
*                                                                       
*   FILE NAME                                           VERSION          
*                                                                               
*       tftpc.c                                           4.4        
*                                                                               
*   COMPONENT                                                             
*                                                                       
*       Net  -  TFTP Client                                            
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       This file contains the TFTP routines necessary to get and to put 
*       a file to a  TFTP server.                                        
*                                                                       
*   DATA STRUCTURES
*
*       None
*
*   FUNCTIONS                                                             
*                                                                       
*       TFTPC_Get                 Get a file from a TFTP server.         
*       TFTPC_Put                 Put a file to a TFTP server.           
*       TFTPC_Request             Send a request to a TFTP server.  
*       TFTPC_Recv                Recv a packet.                         
*       TFTPC_Process_Data        Process a data packet.                 
*       TFTPC_Ack                 Send a TFTP ack.                       
*       TFTPC_Process_Ack         Process an ack packet.                 
*       TFTPC_Send_Data           Send a TFTP data packet.               
*       TFTPC_Retransmit          Retransmit the last TFTP packet.       
*       TFTPC_Error               Send a TFTP error packet.              
*       TFTPC_Check_Options       Evaluate server acknowledged options 
*       TFTPC_Set_Options         Set options to be sent to the server.
*                                                                       
*   DEPENDENCIES                                                          
*                                                                       
*       nucleus.h
*       target.h
*       externs.h
*       sockdefs.h
*       tftpextc.h
*       tftpdefs.h
*       ncl.h
*       fal.h
*                                                                       
*************************************************************************/

#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/externs.h"
#include "net/inc/sockdefs.h"
#include "net/inc/socketd.h"
#include "net/inc/tftpdefc.h"
#include "net/inc/tftpextc.h"
#include "net/inc/ncl.h"
#include "fal/inc/fal.h"

extern NU_MEMORY_POOL  System_Memory;

/* TFTP defines 9 error codes, with values 0 through 8.  In the event that one
*  of these errors is received it will be passed back to the application.  Since
*  a value of 0 is defined to be NU_SUCCESS in the Nucleus PLUS OS it is
*  necessary to redefine the first error code, and since the convention at ATI
*  is to return negative numbers for error codes all were redefined below.
*
*  VALUE       ERROR
*  -100        Not defined, see error message (if any)
*  -101        File not found
*  -102        Access violation
*  -103        Disk full or allocation execeeded
*  -104        Illegal TFTP operation
*  -105        Unknown transfer ID
*  -106        File already exists
*  -107        No such user
*  -108        Illegal Option Negotiation
*/

INT16  tftp_errors[] = {-100, -101, -102, -103, -104, -105, -106, -107, -108};

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       TFTPC_Get                                                        
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       This function is called from a user application.  It retrieves a 
*       file from a TFTP server - compatible with RFC 2347 compliant and 
*       non-compliant servers.                                           
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *remote_ip      Pointer to the target ip address.       
*       *rpath          The remote file to get.
*       *lpath          Local name to give the file.
*       *ops            Pointer to options the user requests of the server.
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       The number of bytes received when succesful.  Else various error 
*       codes are returned.                                              
*                                                                       
*************************************************************************/
INT32 TFTPC_Get(UINT8 *remote_ip, CHAR *rpath, CHAR *lpath, TFTP_OPTIONS *ops)
{
    TFTP_CB  *tftp_con;
    STATUS   status;
    INT16    retransmits;
    INT32    total_bytes, bytes_received;
    UINT32   file_size = 0;
    FAL_FILE file_desc;
    
    /* Open the file and get the length for the tsize option */
    if ((file_desc = FAL_Open(lpath, PO_RDWR|PO_CREAT|PO_TRUNC|PO_BINARY, FAL_IWRITE)) < 0)
        return (FAL_Get_Last_Error()); 
   
    /* Check that the requested options are valid */
    TFTPC_Set_Options(file_size, ops);
    
    /* We will need at least BUFFER_SIZE_MIN bytes to transmit a request
     * packet, so if the requested blksize is less than BUFFER_SIZE_MIN,
     * we still need to allocate BUFFER_SIZE_MIN bytes in memory for the
     * transmission buffer
     */
    if (ops->blksize < TFTP_BUFFER_SIZE_MIN)
    {
        /* Allocate memory for the TFTP Control Block & transmission buffer */
        status = NU_Allocate_Memory (&System_Memory, (VOID **)&tftp_con,
            sizeof(TFTP_CB) + TFTP_BUFFER_SIZE_MIN + TFTP_HEADER_SIZE, NU_SUSPEND);
    }
    
    /* Otherwise, the blksize is large enough to transmit a request packet */
    else
    {
        /* Allocate memory for the TFTP Control Block & transmission buffer */
        status = NU_Allocate_Memory (&System_Memory, (VOID **)&tftp_con,
            (UNSIGNED)(sizeof(TFTP_CB) + ops->blksize + TFTP_HEADER_SIZE),
            NU_SUSPEND);
    }
    
    /* If we cannot allocate the necessary memory for the control block and
     * transmission buffer, return with an error
     */
    if (status != NU_SUCCESS)
    {
        FAL_Fclose(tftp_con->file_desc, 0);
        return(TFTP_NO_MEMORY);
    }
    
    /* Set the options that will be requested of the server - the tsize is
     * sent as 0, and the server will return the size of the request file
     */
    tftp_con->options.timeout = ops->timeout;
    tftp_con->options.blksize = ops->blksize;
    tftp_con->options.tsize = 0;
    
    /* Setup the file descriptor, path and READ_TYPE */
    tftp_con->file_desc = file_desc;
    tftp_con->file_name = rpath;
    tftp_con->type = READ_TYPE;

    /* Setup a pointer to the transmission buffer */
    tftp_con->trans_buf = (CHAR *)((UINT32)tftp_con + sizeof(TFTP_CB));
    
    /* Send a TFTP Read Request to a server */
    if ((status = TFTPC_Request(remote_ip, rpath, tftp_con)) <= 0)
    {
        FAL_Fclose(tftp_con->file_desc, 0);
        NU_Deallocate_Memory((VOID *) tftp_con);
        return(status);
    }
    
    /* Initialize retransmits. */
    retransmits = 0;
    
    /* Get the server's response - should be an OACK if the server is 
     * RFC 2347 compliant, an ACK otherwise 
     */
    while(((bytes_received = TFTPC_Recv(tftp_con)) == NU_NO_DATA) &&
        (retransmits < TFTP_NUM_RETRANS))
    {
        TFTPC_Retransmit(tftp_con, (INT32)status);
        retransmits++;
    }
    
    /* If we received a response, then set up the server's TID.  
     * Else return an error. 
     */
    if (bytes_received)
        tftp_con->tid = tftp_con->server_addr.port;
    else
    {
        FAL_Fclose(tftp_con->file_desc, 0);
        NU_Close_Socket(tftp_con->socket_number);
        NU_Deallocate_Memory((VOID *) tftp_con);
        return(TFTP_CON_FAILURE);
    }
    
    /* If we did not receive an OACK, the server is not RFC 2347 compliant;
     * therefore, we must set our values to conform to RFC 1350 and start
     * on block 1
     */
    if(GET16(tftp_con->trans_buf, 0) != TFTP_OACK_OPCODE)
    {
        tftp_con->options.blksize = TFTP_BLOCK_SIZE_DEFAULT;
        tftp_con->options.timeout = TFTP_TIMEOUT_DEFAULT;
        tftp_con->block_number++;
    }
    
    /* Process the first data packet that was received from the server. */
    if((status = TFTPC_Process_Data(tftp_con, bytes_received)) < 0)
    {
        FAL_Fclose(tftp_con->file_desc, 0);
        NU_Close_Socket(tftp_con->socket_number);
        NU_Deallocate_Memory((VOID *) tftp_con);
        return(status);
    }
    
    /* Get the rest of the file and process it */
    while (tftp_con->status == TRANSFERRING_FILE)
    {
        /* Initialize retransmits. */
        retransmits = 0;
        
        /* Retrieve the next data packet. */
        while(((bytes_received = TFTPC_Recv(tftp_con)) == NU_NO_DATA) &&
            (retransmits < TFTP_NUM_RETRANS))
        {
            TFTPC_Retransmit(tftp_con, TFTP_ACK_SIZE);
            retransmits++;
        } 
        
        /* If a data packet was received, then process it.  Else a problem
         * occured, and we need to exit. 
         */
        if (bytes_received)
        {
            if((status = TFTPC_Process_Data(tftp_con, bytes_received)) !=
                NU_SUCCESS)
                tftp_con->status = TFTP_CON_FAILURE;
        }
        
        /* We will exit the loop and return status */
        else
        {
            tftp_con->status = TFTP_CON_FAILURE;
            status = TFTP_CON_FAILURE;
        }
    } /* While transferring file */
   
    /* If everything went okay then calculate the number of bytes that were
     * received in this file. Else we should return the last error code that 
     * was received.  
     */
    if(status == NU_SUCCESS)
        total_bytes = FAL_Handle_File_Length(file_desc);
    else
        total_bytes = status;

    /* Close the file */
    FAL_Fclose(tftp_con->file_desc, 0);
    
    /* Close the socket, freeing any resources that were used. */
    NU_Close_Socket(tftp_con->socket_number);
    
    /* Deallocate the memory used for the TFTP control block. */
    NU_Deallocate_Memory((VOID *) tftp_con);
    
    return(total_bytes);
} /* end TFTPC_Get */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       TFTPC_Put                                                        
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       This function is called from a user application.  It puts a file 
*       to a TFTP server.                                                
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *remote_ip      Pointer to the target ip address.       
*       *rpath          What the file will be called on the remote host.
*       *lpath          The local file to be transferred.
*       *ops            Pointer to options the client requests of the 
*                       server.               
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       The number of bytes put to the server when succesful.  Else      
*       various error conditions are returned.                           
*                                                                       
*************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -