org.apache.commons.net.tftp.TFTPOptionAckPacket.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.commons.net.tftp.TFTPOptionAckPacket.java

Source

/*
 * Made by Wannes 'W' De Smet
 * (c) 2011 Wannes De Smet
 * All rights reserved.
 * 
 */
package org.apache.commons.net.tftp;

import java.net.DatagramPacket;
import java.net.InetAddress;
import java.util.Map;

/***
 * A final class derived from TFTPPacket defining the TFTP Acknowledgment
 * packet type.
 * <p>
 * Details regarding the TFTP protocol and the format of TFTP packets can
 * be found in RFC 783.  But the point of these classes is to keep you
 * from having to worry about the internals.  Additionally, only very
 * few people should have to care about any of the TFTPPacket classes
 * or derived classes.  Almost all users should only be concerned with the
 * {@link org.apache.commons.net.tftp.TFTPClient} class
 * {@link org.apache.commons.net.tftp.TFTPClient#receiveFile receiveFile()}
 * and
 * {@link org.apache.commons.net.tftp.TFTPClient#sendFile sendFile()}
 * methods.
 * <p>
 * <p>
 * @author Daniel F. Savarese
 * @see TFTPPacket
 * @see TFTPPacketException
 * @see TFTP
 ***/
public final class TFTPOptionAckPacket extends TFTPPacket {

    /*** The block number being acknowledged by the packet. ***/
    protected Map<String, Integer> options;

    /***
     * Creates an acknowledgment packet to be sent to a host at a given port
     * acknowledging receipt of a block.
     * <p>
     * @param destination  The host to which the packet is going to be sent.
     * @param port  The port to which the packet is going to be sent.
     * @param blockNumber  The block number being acknowledged.
     ***/
    public TFTPOptionAckPacket(InetAddress destination, int port, Map<String, Integer> options) {
        super(ExtendedTFTPPacket.OPTION_ACKNOWLEDGEMENT, destination, port);
        this.options = options;
    }

    /***
     * Creates an acknowledgment packet based from a received
     * datagram.  Assumes the datagram is at least length 4, else an
     * ArrayIndexOutOfBoundsException may be thrown.
     * <p>
     * @param datagram  The datagram containing the received acknowledgment.
     * @throws TFTPPacketException  If the datagram isn't a valid TFTP
     *         acknowledgment packet.
     ***/
    TFTPOptionAckPacket(DatagramPacket datagram) throws TFTPPacketException {
        super(ExtendedTFTPPacket.OPTION_ACKNOWLEDGEMENT, datagram.getAddress(), datagram.getPort());
        byte[] data;

        data = datagram.getData();

        if (getType() != data[1]) {
            throw new TFTPPacketException("TFTP operator code does not match type.");
        }

        //.blockNumber = (((data[2] & 0xff) << 8) | (data[3] & 0xff));
    }

    /***
     * This is a method only available within the package for
     * implementing efficient datagram transport by eliminating buffering.
     * It takes a datagram as an argument, and a byte buffer in which
     * to store the raw datagram data.  Inside the method, the data
     * is set as the datagram's data and the datagram returned.
     * <p>
     * @param datagram  The datagram to create.
     * @param data The buffer to store the packet and to use in the datagram.
     * @return The datagram argument.
     ***/
    @Override
    DatagramPacket _newDatagram(DatagramPacket datagram, byte[] data) {
        data[0] = 0;
        data[1] = (byte) ExtendedTFTPPacket.OPTION_ACKNOWLEDGEMENT;

        int index = 2;
        for (Map.Entry<String, Integer> entry : options.entrySet()) {
            char[] chars = entry.getKey().toCharArray();
            for (int i = 0; i < chars.length; i++) {
                data[index++] = (byte) chars[i];
            }

            data[index++] = 0;
            chars = ("" + entry.getValue()).toCharArray();
            for (int i = 0; i < chars.length; i++) {
                data[index++] = (byte) chars[i];
            }
            data[index++] = 0;
        }

        datagram.setAddress(_address);
        datagram.setPort(_port);
        datagram.setData(data);
        datagram.setLength(index);

        return datagram;
    }

    /***
     * Creates a UDP datagram containing all the TFTP
     * acknowledgment packet data in the proper format.
     * This is a method exposed to the programmer in case he
     * wants to implement his own TFTP client instead of using
     * the {@link org.apache.commons.net.tftp.TFTPClient}
     * class.  Under normal circumstances, you should not have a need to call this
     * method.
     * <p>
     * @return A UDP datagram containing the TFTP acknowledgment packet.
     ***/
    @Override
    public DatagramPacket newDatagram() {
        byte[] data = new byte[SEGMENT_SIZE];

        data[0] = 0;
        data[1] = (byte) ExtendedTFTPPacket.OPTION_ACKNOWLEDGEMENT;

        int index = 2;
        for (Map.Entry<String, Integer> entry : options.entrySet()) {
            char[] chars = entry.getKey().toCharArray();
            for (int i = 0; i < chars.length; i++) {
                data[index++] = (byte) chars[i];
            }

            data[index++] = 0;
            chars = ("" + entry.getValue()).toCharArray();
            for (int i = 0; i < chars.length; i++) {
                data[index++] = (byte) chars[i];
            }
            data[index++] = 0;
        }

        return new DatagramPacket(data, data.length, _address, _port);
    }

    public Map<String, Integer> getOptions() {
        return options;
    }

    public void setOptions(Map<String, Integer> options) {
        this.options = options;
    }
}