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

📄 tftp.c

📁 motorola 针对coldfire 5275 评估板的Dbug bootloader源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    tcxn.error = FALSE;

    /* Use Mac address as pseudo-random port */
    udp_prime_port((uint16)((nif->hwa[4] << 8) | nif->hwa[5]));
    tcxn.my_port = udp_obtain_free_port();
    udp_bind_port(tcxn.my_port,&tftp_handler);

    retries = 4;
    success = FALSE;

    while (--retries)
    {
        /* Make the TFTP Read/Write Request */
        if (!tftp_rwrq())
        {
            printf("Error: Couldn't send TFTP Write Request\n");
            udp_free_port(tcxn.my_port);
            return FALSE;
        }

        timer_set_secs(TIMER_NETWORK, TFTP_TIMEOUT);
        while (timer_get_reference(TIMER_NETWORK))
        {
            /* Has the server responded */
            if (tcxn.open)
            {
                success = TRUE;
                break;
            }
        }

        /* If the connection is open, we are done here */
        if (success || tcxn.error)
            break;
    }
    if (!retries)
    {
        printf("TFTP could not make connection to server.\n");
        udp_free_port(tcxn.my_port);
        return FALSE;
    }
    else if (tcxn.error)
    {
        printf("\bErrors in TFTP upload.\n");
        udp_free_port(tcxn.my_port);
        return FALSE;
    }

    bytes_to_send = end - begin;
    current = (uint8 *)begin;
    blocknum = 1;
    retries = 4;
    success = FALSE;

    while (--retries)
    {
        pNbuf = nbuf_alloc();
        if (pNbuf == NULL)
        {
            #if defined(DEBUG_PRINT)
                printf("TFTP: tftp_write() couldn't allocate Tx buffer\n");
            #endif
            return FALSE;
        }

        /* Build the packet */
        data = (DATA *)&pNbuf->data[TFTP_HDR_OFFSET];
        data->blocknum = blocknum;
        data->opcode = TFTP_DATA;

        this_size = (bytes_to_send > TFTP_PKTSIZE) ? \
                    TFTP_PKTSIZE : (uint16)bytes_to_send;

        for (i = 0; i < this_size; i++)
        {
            data->data[i] = current[i];
        }

        /* Set the packet length */
        pNbuf->length = (uint16)(4 + this_size);

        /* Attempt to send the packet */
        for (i=0; i<3; ++i)
        {
            result = udp_send(tcxn.nif, 
                              tcxn.server_ip, 
                              tcxn.my_port, 
                              tcxn.server_port, 
                              pNbuf);

            if (result == 1)
                break;
        }

        if (result == 0)
            nbuf_free(pNbuf);

        timer_set_secs(TIMER_NETWORK, TFTP_TIMEOUT);
        while (timer_get_reference(TIMER_NETWORK))
        {
            /* Has the server responded */
            if ((tcxn.exp_blocknum - 1) == blocknum)
            {
                success = TRUE;
                break;
            }
        }

        /* TFTP Write Compeleted successfully */
        if (success && (this_size < TFTP_PKTSIZE))
        {
            tcxn.bytes_sent += this_size;
            break;
        }

        if (tcxn.error)
            break;

        /* If an ACK was received, keep sending packets */
        if (success)
        {
            tcxn.bytes_sent += TFTP_PKTSIZE;
            bytes_to_send -= TFTP_PKTSIZE;
            current += TFTP_PKTSIZE;
            blocknum++;
            retries = 4;
            success = FALSE;
        }
    }
    if (tcxn.error)
    {
        printf("TFTP lost connection to server.\n");
        printf("Sent %d bytes (%d blocks)\n",   \
            tcxn.bytes_sent, tcxn.exp_blocknum - 1);
        udp_free_port(tcxn.my_port);
        return FALSE;
    }
    else
    {
        printf("\bTFTP upload successful\n");
        printf("Sent %d bytes (%d blocks)\n",   \
            tcxn.bytes_sent, tcxn.exp_blocknum - 1);
        udp_free_port(tcxn.my_port);
        return TRUE;
    }
}

/********************************************************************/
int
tftp_read (NIF *nif, char *fn, IP_ADDR_P server)
{
    uint32 retries;

    if (fn == 0 || server == 0)
        return 0;

    /* Setup initial connection status */
    tcxn.nif = nif;
    tcxn.file = fn;
    tcxn.server_ip[0] = server[0];
    tcxn.server_ip[1] = server[1];
    tcxn.server_ip[2] = server[2];
    tcxn.server_ip[3] = server[3];
    tcxn.server_port = UDP_PORT_TFTP;
    tcxn.exp_blocknum = 1;
    tcxn.last_ack = 0;
    tcxn.dir = TFTP_RRQ;
    tcxn.open = FALSE;
    tcxn.bytes_recv = 0;
    tcxn.rem_bytes = 0;
    tcxn.next_char = NULL;
    tcxn.error = FALSE;
    queue_init(&tcxn.queue);

    /* Use Mac address as pseudo-random port */
    udp_prime_port((uint16)((nif->hwa[4] << 8) | nif->hwa[5]));
    tcxn.my_port = udp_obtain_free_port();
    udp_bind_port(tcxn.my_port,&tftp_handler);

    retries = 4;

    while (--retries)
    {
        /* Make the TFTP Read/Write Request */
        if (!tftp_rwrq())
        {
            printf("Error: Couldn't send TFTP Read Request\n");
            udp_free_port(tcxn.my_port);
            return FALSE;
        }

        timer_set_secs(TIMER_NETWORK, TFTP_TIMEOUT);
        while (timer_get_reference(TIMER_NETWORK))
        {
            /* Has the server responded */
            if (tcxn.open == TRUE)
                break;
        }

        /* If the connection is open, we are done here */
        if ((tcxn.open == TRUE) || tcxn.error)
            break;
    }
    if (!retries)
    {
        printf("TFTP could not make connection to server.\n");
        udp_free_port(tcxn.my_port);
        return FALSE;
    }
    else if (tcxn.error)
    {
        printf("\bErrors in TFTP download.\n");
        udp_free_port(tcxn.my_port);
        return FALSE;
    }
    else
        return TRUE;
}

/********************************************************************/
int
tftp_in_char (void)
{
    union TFTPpacket *tftp_pkt;
    int retval;
    NBUF *pNbuf;

    if (tcxn.next_char != NULL)
    {
        /* 
         * A buffer is already being worked on - grab next 
         * byte from it
         */
        retval = *tcxn.next_char++;
        if (--tcxn.rem_bytes <= 0)
        {
            /* The buffer is depleted; add it back to the free queue */
            pNbuf = (NBUF *)queue_remove(&tcxn.queue);
            ASSERT(pNbuf);
            nbuf_free(pNbuf);
            tcxn.next_char = NULL;
        }
    }
    else
    {
        /* Is the connection still open? */
        if (tcxn.open == FALSE)
        {
            /*
             * The last packet has been received and the last data
             * buffer has been exhausted
             */
            retval = -1;
        }
        else
        {
            /* Get pointer to the next buffer */
            pNbuf = (NBUF *)queue_peek(&tcxn.queue);
            
            if (pNbuf == NULL)
            {
                int i;
                
                /* There was no buffer in the queue */
                for (i = 0; i < 3; ++i)
                {
                    timer_set_secs(TIMER_NETWORK, 1);
                    while (timer_get_reference(TIMER_NETWORK))
                    {
                        /* Has the server sent another DATA packet? */
                        if (!queue_isempty(&tcxn.queue))
                        {
                            pNbuf = (NBUF *)queue_peek(&tcxn.queue);
                            break;
                        }
                    }
                    if (pNbuf != NULL)
                        break;
                    
                    /* Ack the last packet again */
                    #ifdef DEBUG_PRINT
                        printf("Re-acking %d\n",tcxn.last_ack - 1);
                    #endif
                    retval = tftp_ack(tcxn.last_ack - 1);
                    ASSERT(retval);
                }
            }
            if (pNbuf == NULL)
            {
                /* The server didn't respond with the expected packet */
                tcxn.open = FALSE;
                tcxn.error = TRUE;
                printf("TFTP lost connection to server.\n");
                retval = -1;
            }
            else
            {
                tftp_pkt = (union TFTPpacket *)&pNbuf->data[pNbuf->offset];

                /* Subtract the TFTP header from the data length */
                tcxn.rem_bytes = pNbuf->length - 4;

                /* Point to first data byte in the packet */
                tcxn.next_char = tftp_pkt->data.data;

                /* Save off the block number */
                tcxn.last_ack = tftp_pkt->data.blocknum;

                /* Check to see if this is the last packet of the transfer */
                if (tcxn.rem_bytes < TFTP_PKTSIZE)
                    tcxn.open = FALSE;

                /* Check for empty termination packet */
                if (tcxn.rem_bytes == 0)
                {
                    pNbuf = (NBUF *)queue_remove(&tcxn.queue);
                    ASSERT(pNbuf);
                    nbuf_free(pNbuf);
                    tcxn.next_char = NULL;
                    retval = tftp_ack(tcxn.last_ack++);
                    ASSERT(retval);
                    retval = -1;
                }
                else
                {
                    retval = tftp_ack(tcxn.last_ack++);
                    ASSERT(retval);
                    retval = *tcxn.next_char++;

                    /* Check for a single byte packet */
                    if (--tcxn.rem_bytes == 0)
                    {
                        /* The buffer is depleted; add it back to the free queue */
                        pNbuf = (NBUF *)queue_remove(&tcxn.queue);
                        ASSERT(pNbuf);
                        nbuf_free(pNbuf);
                        tcxn.next_char = NULL;
                    }
                }
            }
        }
    }
    return retval;
}
/********************************************************************/

#endif /* #ifdef DBUG_NETWORK */

⌨️ 快捷键说明

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