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

📄 tftpc.c

📁 凌阳SPCE3200 系统开发板随机自带源程序。共安排了32个子目录
💻 C
📖 第 1 页 / 共 3 页
字号:
 *
 * Note:            None
 ********************************************************************/
TFTP_RESULT TFTPIsPutReady(void)
{
    WORD_VAL opCode;
    WORD_VAL blockNumber;
    BOOL bTimeOut;

    // Check to see if timeout has occurred.
    bTimeOut = FALSE;
    if ( TickGetDiff(TickGet(), _tftpStartTick) >= TFTP_GET_TIMEOUT_VAL )
    {
        bTimeOut = TRUE;
        _tftpStartTick = TickGet();
    }

    switch(_tftpState)
    {
    case SM_TFTP_WAIT_FOR_ACK:
        // When timeout occurs in this state, application must retry.
        if ( bTimeOut )
        {
            if ( _tftpRetries++ > (TFTP_MAX_RETRIES-1) )
            {
                DEBUG(printf("TFTPIsPutReady(): Timeout.\n"));

                // Forget about all previous attempts.
                _tftpRetries = 1;

                return TFTP_TIMEOUT;
            }

            else
            {
                DEBUG(printf("TFTPIsPutReady(): Retry.\n"));
                return TFTP_RETRY;
            }
        }

        // Must wait for ACK from server before we transmit next block.
        if ( !UDPIsGetReady(_tftpSocket) )
            break;

        // Get opCode.
        UDPGet(&opCode.byte.MSB);
        UDPGet(&opCode.byte.LSB);

        // Get block number.
        UDPGet(&blockNumber.byte.MSB);
        UDPGet(&blockNumber.byte.LSB);

        // Discard everything else.
        UDPDiscard();

        // This must be ACK or else there is a problem.
        if ( opCode.Val == TFTP_OPCODE_ACK )
        {
            // Also the block number must match with what we are expecting.
            if ( MutExVar.group2._tftpBlockNumber.Val == blockNumber.Val )
            {
                // Mark that block we sent previously has been ack'ed.
                _tftpFlags.bits.bIsAcked = TRUE;

                // Since we have ack, forget about previous retry count.
                _tftpRetries = 1;

                // If this file is being closed, this must be last ack.
                // Declare it as closed.
                if ( _tftpFlags.bits.bIsClosing )
                {
                    _tftpFlags.bits.bIsClosed = TRUE;
                    return TFTP_OK;
                }

                // Or else, wait for put to become ready so that caller
                // can transfer more data blocks.
                _tftpState = SM_TFTP_WAIT;
            }

            else
            {
                DEBUG(printf("TFTPIsPutReady(): "\
                    "Unexpected block %d received - droping it...\n", \
                    blockNumber.Val));
                return TFTP_NOT_READY;
            }
        }

        else if ( opCode.Val == TFTP_OPCODE_ERROR )
        {
            // For error opCode, remember error code so that application
            // can read it later.
            _tftpError = blockNumber.Val;

            // Declare error.
            return TFTP_ERROR;
        }
        else
            break;


    case SM_TFTP_WAIT:
        // Wait for UDP is to be ready to transmit.
        if ( UDPIsPutReady(_tftpSocket) )
        {
            // Put next block of data.
            MutExVar.group2._tftpBlockNumber.Val++;
            UDPPut(0);
            UDPPut(TFTP_OPCODE_DATA);

            UDPPut(MutExVar.group2._tftpBlockNumber.byte.MSB);
            UDPPut(MutExVar.group2._tftpBlockNumber.byte.LSB);

            // Remember that this block is not yet flushed.
            _tftpFlags.bits.bIsFlushed = FALSE;

            // Remember that this block is not acknowledged.
            _tftpFlags.bits.bIsAcked = FALSE;

            // Now, TFTP module is ready to put more data.
            _tftpState = SM_TFTP_READY;

            return TFTP_OK;
        }
        break;

    case SM_TFTP_READY:
        // TFTP module is said to be ready only when underlying UDP
        // is ready to transmit.
        if ( UDPIsPutReady(_tftpSocket) )
            return TFTP_OK;
    }

    return TFTP_NOT_READY;
}



/*********************************************************************
 * Function:        void TFTPPut(BYTE c)
 *
 * PreCondition:    TFTPOpenFile() is called with TFTP_FILE_MODE_WRITE
 *                  and TFTPIsPutReady() = TRUE
 *
 * Input:           c       - Data byte that is to be written
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Puts given data byte into TFTP socket.
 *                  If end of data block is reached, it
 *                  transmits entire block.
 *
 * Note:            Use this function to write file to server.
 ********************************************************************/
void TFTPPut(BYTE c)
{
    // Put given byte directly to UDP
    UDPPut(c);

    // One more byte in data block.
    ++MutExVar.group2._tftpBlockLength.Val;

    // Check to see if data block is full.
    if ( MutExVar.group2._tftpBlockLength.byte.MSB == TFTP_BLOCK_SIZE_MSB )
    {
        // If it is, then transmit this block.
        UDPFlush();

        // Remember that current block is already flushed.
        _tftpFlags.bits.bIsFlushed = TRUE;

        // Prepare for next block.
        MutExVar.group2._tftpBlockLength.Val = 0;

        // Need to wait for ACK from server before putting
        // next block of data.
        _tftpState = SM_TFTP_WAIT_FOR_ACK;
    }
}


static void _TFTPSendFileName(TFTP_OPCODE opcode, char *fileName)
{
    BYTE c;

    // Write opCode
    UDPPut(0);
    UDPPut(opcode);

    // write file name, including NULL.
    do
    {
        c = *fileName++;
        UDPPut(c);
    } while ( c != '\0' );

    // Write mode - always use octet or binay mode to transmit files.
    UDPPut('o');
    UDPPut('c');
    UDPPut('t');
    UDPPut('e');
    UDPPut('t');
    UDPPut(0);

    // Transmit it.
    UDPFlush();

    // Reset data block length.
    MutExVar.group2._tftpBlockLength.Val = 0;

}

static void _TFTPSendAck(WORD_VAL blockNumber)
{
    // Write opCode.
    UDPPut(0);
    UDPPut(TFTP_OPCODE_ACK);

    // Write block number for this ack.
    UDPPut(blockNumber.byte.MSB);
    UDPPut(blockNumber.byte.LSB);

    // Transmit it.
    UDPFlush();
}

TFTP_RESULT TFTP_Connect(IP_ADDR *ServerIP)
{
    TFTP_RESULT TFTPc_Result;
    unsigned int cnt = 0;
    
    TFTPOpen( ServerIP );
    
    delay( 2 );

    do
    {
    	StackTask();
    	TFTPc_Result = TFTPIsOpened();
    	switch( TFTPc_Result )
    	{
    		case TFTP_TIMEOUT:      
    		// retry five times to connect,user can change the value.
    					if( cnt<5 )
    					{
    						TFTPOpen( ServerIP );
    						cnt++;
    						delay( 2 );

    						break;
    					}
    					else
    						return TFTP_ERROR;
    					
    		case TFTP_NOT_READY:
    					break;   					
    	}
    }	while ( TFTPc_Result != TFTP_OK );
    
    print1("\nSuccess to setup a connection with remote server !\n");    
    return TFTP_OK;
}

TFTP_RESULT TFTP_Operate(char* fileName, TFTP_FILE_MODE operateMode, BYTE* buff, unsigned int length)
{
    unsigned int cnt = 0;
    TFTP_RESULT TFTPc_Result;
    BYTE* tempBuff;
    tempBuff = buff;
    	
    TFTPOpenFile(fileName, operateMode);
    
    delay( 10 );

//    check if the file has been opened and 
//    using an active socket to read the file's content
    do
    {
    	StackTask();
    	TFTPc_Result = TFTPIsFileOpened();
    	switch( TFTPc_Result )
    	{
    		case TFTP_TIMEOUT:
    		case TFTP_RETRY:
    				// timeout five times to abord and return TFTP_ERROR
    				if ( cnt<5 )
    				{
    					TFTPOpenFile(fileName, operateMode);
    					cnt++;
    					delay( 10 );
    					break;
    				}
    				else
    					return TFTP_ERROR;
    		case TFTP_NOT_READY:
    		case TFTP_OK:
    				break;
    	}		
    }	while ( TFTPc_Result != TFTP_OK );
    
   /* debug info ouput to the PC through the UART  **************/ 
    switch(operateMode)
    {
    	case TFTP_FILE_MODE_READ:
    		print1("\nRead request to server is successful !\n");
    		break ;
    	case TFTP_FILE_MODE_WRITE:
    		print1("\nWrite request to server is successful !\n");
    		break;
    }
   /************************************************************/
    
	switch( operateMode )
	{
		case TFTP_FILE_MODE_READ:
                    	do
                    	{
                    		*buff = TFTPGet();
                    		if( buff > (tempBuff+length) )
                    			break;
                    		else
                    		    buff++;
                    	}	while( (TFTPIsGetReady() != TFTP_END_OF_FILE) );
                    	print1("\nReading data is finished,the next to close the connection !\n");
                //  close the connetion  
                   		TFTPCloseFile();	
                    	TFTPClose();
                    	print1("\nTFTP connect is successful closed !\n"); 
                   		break;
   		
		case TFTP_FILE_MODE_WRITE:
							cnt = 0;
                            do
                            {
                            	tempBuff = *buff;
                            	TFTPPut( tempBuff );
                            	buff++;
                            	cnt++;
                            }	while( cnt < length );
                            print1("\nWriting data is finished,the next to close the connection !\n");
               //  close the connetion
               				TFTPCloseFile();
               	//			delay(100);  
                    		do
                    		{
                    			StackTask();
    							TFTPc_Result = TFTPIsFileClosed();
                    			switch( TFTPc_Result )
                    			{
                    				case TFTP_TIMEOUT:
                    				case TFTP_ERROR:
                    						print1("\nTFTPIsPutReady(): Timeout or Error\n");
                    						return TFTP_ERROR;
                    				case TFTP_RETRY:
                    				case TFTP_NOT_READY:
                    						print1("\nTFTPIsPutReady(): Retry or Not_Ready\n");
                    						TFTPCloseFile();
                    						break;
                    			}
                    		}	while( TFTPc_Result != TFTP_OK );
                    		
                    		TFTPClose();
                    		print1("\nTFTP connect is successful closed !\n");
                    		break;
		default:
				print1("\nTFTP connect is successful closed !\n");
    }
            
    return TFTP_OK;	
}

⌨️ 快捷键说明

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