Example usage for org.apache.commons.net.tftp TFTPOptionAckPacket TFTPOptionAckPacket

List of usage examples for org.apache.commons.net.tftp TFTPOptionAckPacket TFTPOptionAckPacket

Introduction

In this page you can find the example usage for org.apache.commons.net.tftp TFTPOptionAckPacket TFTPOptionAckPacket.

Prototype

public TFTPOptionAckPacket(InetAddress destination, int port, Map<String, Integer> options) 

Source Link

Document

Creates an acknowledgment packet to be sent to a host at a given port acknowledging receipt of a block.

Usage

From source file:org.xenmaster.connectivity.tftp.TFTPServer.java

protected void handlePacket(final TFTPPacket packet) throws IOException {
    switch (packet.getType()) {
    case TFTPPacket.READ_REQUEST:
        if (clientAddress == null) {
            TFTPOptionReadRequestPacket request = (TFTPOptionReadRequestPacket) packet;
            dataInputStream = null;/*from   ww  w. j  ava 2s  .  co m*/

            try {
                Logger.getLogger(getClass()).debug("Request for : " + request.getFilename() + " received from "
                        + packet.getAddress().getCanonicalHostName() + ":" + packet.getPort());

                for (ActivityListener al : listeners) {
                    InputStream is = al.pathRequest(request);
                    if (is != null) {
                        dataInputStream = is;
                    }
                    break;
                }

                if (dataInputStream == null) {
                    Logger.getLogger(getClass())
                            .debug("No ActivityListener provided valid InputStream for TFTP request");
                    tftp.bufferedSend(new TFTPErrorPacket(packet.getAddress(), packet.getPort(),
                            TFTPErrorPacket.FILE_NOT_FOUND, request.getFilename()));
                    return;
                }

                if (request.getOptions().size() > 0) {
                    HashMap<String, Integer> acks = new HashMap<>();
                    for (Map.Entry<String, Integer> entry : request.getOptions().entrySet()) {
                        switch (entry.getKey()) {
                        case "blksize":
                            blockSize = entry.getValue();
                            acks.put(entry.getKey(), blockSize);
                            tftp.restartBufferedOps(blockSize + 4);
                            break;
                        case "tsize":
                            // Client wants to know transfer size
                            acks.put(entry.getKey(), dataInputStream.available());
                            break;
                        }
                    }

                    blockNumber = 0;
                    clientAddress = packet.getAddress();

                    tftp.bufferedSend(new TFTPOptionAckPacket(packet.getAddress(), packet.getPort(), acks));

                    return;
                }

                blockNumber = 1;
                byte[] data = new byte[blockSize];
                final int bytesRead = dataInputStream.read(data);
                tftp.bufferedSend(new TFTPPXEDataPacket(packet.getAddress(), packet.getPort(), blockNumber,
                        data, 0, bytesRead));
                // if more blocks to send
                if (bytesRead == blockSize) {
                    clientAddress = packet.getAddress();
                } else {
                    dataInputStream.close();
                    clientAddress = null;
                }
            } catch (FileNotFoundException ex) {
                tftp.bufferedSend(new TFTPErrorPacket(packet.getAddress(), packet.getPort(),
                        TFTPErrorPacket.FILE_NOT_FOUND, ex.getMessage()));
                clientAddress = null;
            }
        }
        break;
    case TFTPPacket.ACKNOWLEDGEMENT:
        if (packet.getAddress().equals(clientAddress)) {
            TFTPAckPacket ackPacket = (TFTPAckPacket) packet;
            Logger.getLogger(getClass())
                    .debug("ACK : " + ackPacket.getBlockNumber() + " ~ " + blockNumber * blockSize + "/"
                            + dataInputStream.available() + " "
                            + ackPacket.getAddress().getCanonicalHostName());
            // Check if client ACKd correctly
            if (ackPacket.getBlockNumber() == blockNumber) {
                // send next block
                final byte[] data = new byte[blockSize];
                final int bytesRead = dataInputStream.read(data);
                blockNumber++;
                TFTPPXEDataPacket dataPacket = new TFTPPXEDataPacket(packet.getAddress(), packet.getPort(),
                        blockNumber, data, 0, bytesRead);

                Logger.getLogger(getClass()).debug("Sending " + blockNumber + " to "
                        + packet.getAddress().getCanonicalHostName() + " with " + bytesRead + " bytes");

                tftp.bufferedSend(dataPacket);
                resendTask.set(dataPacket, ackPacket.getBlockNumber());

                // It is done
                if (bytesRead < blockSize) {
                    clientAddress = null;
                    dataInputStream.close();
                    resendTask.chill();
                }
            }
        }
        break;
    case TFTPPacket.ERROR:
        TFTPErrorPacket tep = (TFTPErrorPacket) packet;
        Logger.getLogger(getClass()).warn("TFTP error : " + tep.getMessage());
        clientAddress = null;
        blockNumber = 0;
        break;
    }
}