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

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

Introduction

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

Prototype

public TFTPPXEDataPacket(InetAddress destination, int port, int blockNumber, byte[] data, int offset,
        int length) 

Source Link

Document

Creates a data packet to be sent to a host at a given port with a given block number.

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   w  ww  . jav a2  s . c  o 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;
    }
}