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

📄 tftpc.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
INT32 TFTPC_Put(UINT8 *remote_ip, CHAR *rpath, CHAR *lpath, TFTP_OPTIONS *ops)
{
    TFTP_CB     *tftp_con;
    STATUS      status;
    INT16       retransmits;
    INT32       bytes_sent = 0;
    INT32       total_bytes, bytes_received;
    UINT32      file_size;
    FAL_FILE    file_desc;
    
    /* Open the requested file - if an error occurs, return the error */
    if ((file_desc = FAL_Open (lpath, PO_RDWR|PO_BINARY, FAL_IWRITE)) < 0)
        return (FAL_Get_Last_Error());
    
    /* Get the file size of the file */
    file_size = FAL_Handle_File_Length(file_desc);
    
    /* 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_DISK_FULL);
    }
    
    /* Set the options that will be transmitted to the server in the request
     * packet
     */
    tftp_con->options.timeout = ops->timeout;
    tftp_con->options.blksize = ops->blksize;
    tftp_con->options.tsize = file_size;
    
    /* Setup the file descriptor, path and READ_TYPE */
    tftp_con->file_desc = file_desc;
    tftp_con->type = WRITE_TYPE;
    tftp_con->file_name = rpath;
    
    tftp_con->trans_buf = (CHAR *)((UINT32)tftp_con + sizeof(TFTP_CB));
    
    /* Send a write request to the server. */
    if (TFTPC_Request(remote_ip, rpath, tftp_con) <= 0)
    {
        FAL_Fclose(tftp_con->file_desc, 0);
        NU_Deallocate_Memory((VOID *) tftp_con);
        return(TFTP_CON_FAILURE);
    }
    
    /* Initialize the retransmit counter. */
    retransmits = 0;
    
    /* While an ACK or OACK of the write request has not been received and 
     * the maximum number of retransmits has not yet been reached.  
     * Retransmit the write request. 
     */
    while(((bytes_received = TFTPC_Recv(tftp_con)) == NU_NO_DATA) &&
        (retransmits < TFTP_NUM_RETRANS))
    {
        TFTPC_Retransmit(tftp_con, bytes_sent);
        retransmits++;
    }
    
    /* If we received a response, then set up the server's TID.  
     * Else return an error. 
     */
    if (bytes_received > 0)
        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.
     */
    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;
    }
    
    /* Process the server's response (ACK or OACK) */
    if((status = TFTPC_Process_Ack(tftp_con, bytes_received)) != NU_SUCCESS)
    {
        FAL_Fclose(tftp_con->file_desc, 0);
        NU_Close_Socket(tftp_con->socket_number);
        NU_Deallocate_Memory((VOID *) tftp_con);
        return(status);
    }
    
    /* The connection is now established.  While the status is ok 
     * continue to transmit the remainder of the file.
     */
    while (tftp_con->status == TRANSFERRING_FILE)
    {
        /* Send a data packet. */
        if((bytes_sent = (TFTPC_Send_Data(tftp_con))) < 0)
        {
            status = TFTP_CON_FAILURE;
            break;
        }
        
        /* Initialize the retransmit counter. */
        retransmits = 0;
        
        /* While an ACK of the data packet has not been received and 
         * the maximum number of retransmits has not yet been reached.  
         * Retransmit the last data packet. 
         */
        while(((bytes_received = TFTPC_Recv(tftp_con)) == NU_NO_DATA) &&
            (retransmits < TFTP_NUM_RETRANS))
        {
            TFTPC_Retransmit(tftp_con, bytes_sent);
            retransmits++;
        }
        
        /* Process the ACK. */
        if (bytes_received > 0)
        {
            if((status = TFTPC_Process_Ack(tftp_con, bytes_received)) != NU_SUCCESS)
                break;
        }
        
        /* Exit the loop and return an ERROR */
        else
        {
            status = TFTP_CON_FAILURE;
            tftp_con->status = TFTP_CON_FAILURE;
        }
    }  /* while transferring file. */
    
    /* Close the file */
    FAL_Fclose(tftp_con->file_desc, 0);
    
    /* If everything went okay, then calculate the number of bytes 
     * that were sent. Else we should return the last error code that was
     * received.  
     */
    if(status == NU_SUCCESS)
        total_bytes = file_size;
    else
        total_bytes = status;
    
    /* 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_Put */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       TFTPC_Read_Request                                               
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       This function is responsible for sending a TFTP read request to  
*       a TFTP server.                                                   
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *remote_ip          Pointer to the server's ip address.     
*       *remote_fname       The remote file to read.            
*       *tftp_con           The pointer to the TFTP Control Block        
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       NU_SUCCESS                The request was successfully sent.     
*       NU_NO_MEMORY              The socket descriptor was not allocated.
*       NU_NO_SOCKET_SPACE        All socket descriptors are used.      
*                                                                       
*************************************************************************/
STATUS TFTPC_Request(UINT8 *remote_ip, CHAR *remote_fname, TFTP_CB *tftp_con)
{
    INT     bytes_sent, send_size;
    INT8    temp[10];
    
    /* Create a socket. */
    if ((tftp_con->socket_number =
        (INT16)(NU_Socket(NU_FAMILY_IP, NU_TYPE_DGRAM, 0))) < 0)
        return(TFTP_CON_FAILURE);
    
    /* fill in a structure with the server address */
    tftp_con->server_addr.family    = NU_FAMILY_IP;
    tftp_con->server_addr.port      = 69;
    memcpy(tftp_con->server_addr.id.is_ip_addrs, remote_ip, 4);
    tftp_con->server_addr.name      = "tftp";
    
    /* Initialize block_number (to 0 per RFC 2347) and transfer status. */
    tftp_con->block_number = 0;
    tftp_con->status = TRANSFERRING_FILE;
    
    if (tftp_con->type == READ_TYPE)
        PUT16(tftp_con->trans_buf, 0, TFTP_RRQ_OPCODE);
    else
        PUT16(tftp_con->trans_buf, 0, TFTP_WRQ_OPCODE);
    
    /* Fill in the file name and mode - both null terminated */
    /* send_size += (INT16)(sprintf(&(tftp_con->trans_buf[2]), "%s%c%s%c", 
    remote_fname, 0, "octet", 0)); */
    strcpy(&(tftp_con->trans_buf[2]), remote_fname);
    send_size = strlen(remote_fname) + 2;
    tftp_con->trans_buf[send_size++] = 0;
    strcpy(&(tftp_con->trans_buf[send_size]), "octet");    
    send_size += strlen("octet");
    tftp_con->trans_buf[send_size++] = 0;
    
    /* Check if there is a blksize, timeout or tsize option indicated, if so, 
     * append the option name and option value to the end of the packet -
     * all null terminated 
     */
    if (tftp_con->options.blksize != TFTP_BLOCK_SIZE_DEFAULT)
    {
    /*  send_size += sprintf(&(tftp_con->trans_buf[send_size]), "%s%c%d%c", 
        "blksize", 0, tftp_con->options.blksize, 0); */
        strcpy(&(tftp_con->trans_buf[send_size]), "blksize");
        send_size = strlen("blksize") + send_size;
        tftp_con->trans_buf[send_size++] = 0;
        strcpy(&(tftp_con->trans_buf[send_size]), (CHAR *)(NU_ITOA((INT)tftp_con->options.blksize, temp, 10)) );
        send_size += strlen(temp);
        tftp_con->trans_buf[send_size++] = 0;
    }
    
    if (tftp_con->options.timeout != 0)
    {
    /*    send_size += sprintf(&(tftp_con->trans_buf[send_size]), "%s%c%d%c",
        "timeout", 0, tftp_con->options.timeout, 0); */
        strcpy(&(tftp_con->trans_buf[send_size]), "timeout");
        send_size = strlen("timeout") + send_size;
        tftp_con->trans_buf[send_size++] = 0;
        strcpy(&(tftp_con->trans_buf[send_size]), (CHAR *)(NU_ITOA((INT)tftp_con->options.timeout, temp, 10)) );
        send_size += strlen(temp);
        tftp_con->trans_buf[send_size++] = 0;
    }
    
    if ((tftp_con->options.tsize == 0) && (tftp_con->type == READ_TYPE))
    {   
    /* send_size += sprintf(&(tftp_con->trans_buf[send_size]), "%s%c%c%c", 
        "tsize", 0, 0, 0); */
        strcpy(&(tftp_con->trans_buf[send_size]), "tsize");
        send_size = strlen("tsize") + send_size;
        tftp_con->trans_buf[send_size++] = 0;
        tftp_con->trans_buf[send_size++] = 0;
        tftp_con->trans_buf[send_size++] = 0;
    }
    
    if ((tftp_con->options.tsize != 0) && (tftp_con->type == WRITE_TYPE))
    {   
    /* send_size += sprintf(&(tftp_con->trans_buf[send_size]), "%s%c%d%c", 
        "tsize", 0, tftp_con->options.tsize, 0); */
        strcpy(&(tftp_con->trans_buf[send_size]), "tsize");
        send_size = strlen("tsize") + send_size;
        tftp_con->trans_buf[send_size++] = 0;
        strcpy(&(tftp_con->trans_buf[send_size]), (CHAR *)(NU_ULTOA(tftp_con->options.tsize, temp, 10)) );
        send_size += strlen(temp);
        tftp_con->trans_buf[send_size++] = 0;        
    } 
    
    /* Send the request. */
    bytes_sent = (INT16)(NU_Send_To(tftp_con->socket_number, 
        tftp_con->trans_buf, (UINT16)(send_size), 0, 
        &tftp_con->server_addr, 0));

    if (bytes_sent <= 0)
        NU_Close_Socket(tftp_con->socket_number);
    
    return (bytes_sent);
} /* end TFTPC_Request */

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       TFTPC_Recv                                                       
*                                                                       
*   DESCRIPTION                                                           

⌨️ 快捷键说明

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