// Path: src/se/bitcraze/crazyflie/lib/Utilities.java
// public class Utilities {
// 
//     /**
//      * Returns byte array as comma separated string
//      * (for debugging purposes)
//      *
//      * @param data
//      * @return
//      */
//     public static String getByteString(byte[] data) {
//         StringBuffer sb = new StringBuffer();
//         for (byte b : data) {
//             sb.append(b);
//             sb.append(",");
//         }
//         return sb.toString();
//     }
// 
//     public static String getHexString(byte... array) {
//         StringBuffer sb = new StringBuffer();
//         for (byte b : array) {
//             sb.append(String.format("%02X", b));
//             sb.append(" ");
//         }
//         return sb.toString();
//     }
// 
//     /**
//      * Strip bytes of the beginning of an array
//      *
//      * @param array
//      * @param offset
//      * @return
//      */
//     public static byte[] strip(byte[] array, int offset) {
//         byte[] strippedArray = new byte[array.length-offset];
//         System.arraycopy(array, offset, strippedArray, 0, strippedArray.length);
//         return strippedArray;
//     }
//     
// }
// 
// Path: src/se/bitcraze/crazyflie/lib/crtp/CrtpDriver.java
// public abstract class CrtpDriver {
// 
//     protected Set<ConnectionListener> mConnectionListeners = new CopyOnWriteArraySet<ConnectionListener>();
// 
//     /**
//      * Driver constructor. Throw an exception if the driver is unable to open the URI
//      */
//     public CrtpDriver() {
//     }
// 
//     /**
//      * Connect the driver
//      *
//      * @throws IOException
//      */
//     public abstract void connect() throws IOException;
// 
//     /**
//      * Close the link
//      */
//     public abstract void disconnect();
// 
//     /**
//      * Check whether the link is connected.
//      *
//      * @return <code>true</code> if the link is connected.
//      */
//     public abstract boolean isConnected();
// 
//     /**
//      * Send a CRTP packet
//      *
//      * @param packet
//      */
//     public abstract void sendPacket(CrtpPacket packet);
// 
//     /**
//      * Receive a CRTP packet.
//      *
//      * @param wait The time to wait for a packet in milliseconds. -1 means forever
//      * @return One CRTP packet or None if no packet has been received.
//      */
//     public abstract CrtpPacket receivePacket(int wait);
// 
//     /* CONNECTION LISTENER */
// 
//     public void addConnectionListener(ConnectionListener listener) {
//         this.mConnectionListeners.add(listener);
//     }
// 
//     public void removeConnectionListener(ConnectionListener listener) {
//         this.mConnectionListeners.remove(listener);
//     }
// 
//     /**
//      * Notify all registered listeners about a requested connection
//      */
//     protected void notifyConnectionRequested(){
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.connectionRequested();
//         }
//     }
// 
//     /**
//      * Notify all registered listeners about a connect.
//      */
//     public void notifyConnected(){
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.connected();
//         }
//     }
//     /**
//      * Notify all registered listeners about a finished setup.
//      */
//     public void notifySetupFinished(){
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.setupFinished();
//         }
//     }
// 
//     /**
//      * Notify all registered listeners about a failed connection attempt.
//      *
//      * @param msg
//      */
//     protected void notifyConnectionFailed(String msg) {
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.connectionFailed(msg);
//         }
//     }
// 
//     /**
//      * Notify all registered listeners about a lost connection.
//      *
//      * @param msg
//      */
//     protected void notifyConnectionLost(String msg) {
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.connectionLost(msg);
//         }
//     }
// 
//     /**
//      * Notify all registered listeners about a disconnect.
//      */
//     protected void notifyDisconnected() {
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.disconnected();
//         }
//     }
// 
//     /**
//      * Notify all registered listeners about a link quality update.
//      *
//      * @param percent quality of the link (0 = connection lost, 100 = good)
//      */
//     protected void notifyLinkQualityUpdated(int percent) {
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.linkQualityUpdated(percent);
//         }
//     }
// 
// }


import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.bitcraze.crazyflie.lib.Utilities;
import se.bitcraze.crazyflie.lib.crtp.CrtpDriver;
import se.bitcraze.crazyflie.lib.crtp.CrtpPacket;
import se.bitcraze.crazyflie.lib.usb.CrazyUsbInterface;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
     * Sets the connection data (channel and data rate)
     * 
     * @param connectionData channel and data rate
     */
    public void setConnectionData(ConnectionData connectionData) {
        this.mConnectionData = connectionData;
    }

    /*
     *  Receive a packet though the link. This call is blocking but will
     *  timeout and return None if a timeout is supplied.
     */
    @Override
    public CrtpPacket receivePacket(int time) {
        try {
            return mInQueue.poll((long) time, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            mLogger.error("InterruptedException: " + e.getMessage());
            return null;
        }
    }

    /*
     * Send the packet though the link
     *
     *  (non-Javadoc)
     * @see cflib.crtp.CrtpDriver#sendPacket(cflib.crtp.CrtpPacket)
     */
    @Override
    public void sendPacket(CrtpPacket packet) {
// Path: src/se/bitcraze/crazyflie/lib/Utilities.java
// public class Utilities {
// 
//     /**
//      * Returns byte array as comma separated string
//      * (for debugging purposes)
//      *
//      * @param data
//      * @return
//      */
//     public static String getByteString(byte[] data) {
//         StringBuffer sb = new StringBuffer();
//         for (byte b : data) {
//             sb.append(b);
//             sb.append(",");
//         }
//         return sb.toString();
//     }
// 
//     public static String getHexString(byte... array) {
//         StringBuffer sb = new StringBuffer();
//         for (byte b : array) {
//             sb.append(String.format("%02X", b));
//             sb.append(" ");
//         }
//         return sb.toString();
//     }
// 
//     /**
//      * Strip bytes of the beginning of an array
//      *
//      * @param array
//      * @param offset
//      * @return
//      */
//     public static byte[] strip(byte[] array, int offset) {
//         byte[] strippedArray = new byte[array.length-offset];
//         System.arraycopy(array, offset, strippedArray, 0, strippedArray.length);
//         return strippedArray;
//     }
//     
// }
// 
// Path: src/se/bitcraze/crazyflie/lib/crtp/CrtpDriver.java
// public abstract class CrtpDriver {
// 
//     protected Set<ConnectionListener> mConnectionListeners = new CopyOnWriteArraySet<ConnectionListener>();
// 
//     /**
//      * Driver constructor. Throw an exception if the driver is unable to open the URI
//      */
//     public CrtpDriver() {
//     }
// 
//     /**
//      * Connect the driver
//      *
//      * @throws IOException
//      */
//     public abstract void connect() throws IOException;
// 
//     /**
//      * Close the link
//      */
//     public abstract void disconnect();
// 
//     /**
//      * Check whether the link is connected.
//      *
//      * @return <code>true</code> if the link is connected.
//      */
//     public abstract boolean isConnected();
// 
//     /**
//      * Send a CRTP packet
//      *
//      * @param packet
//      */
//     public abstract void sendPacket(CrtpPacket packet);
// 
//     /**
//      * Receive a CRTP packet.
//      *
//      * @param wait The time to wait for a packet in milliseconds. -1 means forever
//      * @return One CRTP packet or None if no packet has been received.
//      */
//     public abstract CrtpPacket receivePacket(int wait);
// 
//     /* CONNECTION LISTENER */
// 
//     public void addConnectionListener(ConnectionListener listener) {
//         this.mConnectionListeners.add(listener);
//     }
// 
//     public void removeConnectionListener(ConnectionListener listener) {
//         this.mConnectionListeners.remove(listener);
//     }
// 
//     /**
//      * Notify all registered listeners about a requested connection
//      */
//     protected void notifyConnectionRequested(){
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.connectionRequested();
//         }
//     }
// 
//     /**
//      * Notify all registered listeners about a connect.
//      */
//     public void notifyConnected(){
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.connected();
//         }
//     }
//     /**
//      * Notify all registered listeners about a finished setup.
//      */
//     public void notifySetupFinished(){
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.setupFinished();
//         }
//     }
// 
//     /**
//      * Notify all registered listeners about a failed connection attempt.
//      *
//      * @param msg
//      */
//     protected void notifyConnectionFailed(String msg) {
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.connectionFailed(msg);
//         }
//     }
// 
//     /**
//      * Notify all registered listeners about a lost connection.
//      *
//      * @param msg
//      */
//     protected void notifyConnectionLost(String msg) {
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.connectionLost(msg);
//         }
//     }
// 
//     /**
//      * Notify all registered listeners about a disconnect.
//      */
//     protected void notifyDisconnected() {
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.disconnected();
//         }
//     }
// 
//     /**
//      * Notify all registered listeners about a link quality update.
//      *
//      * @param percent quality of the link (0 = connection lost, 100 = good)
//      */
//     protected void notifyLinkQualityUpdated(int percent) {
//         for (ConnectionListener cl : this.mConnectionListeners) {
//             cl.linkQualityUpdated(percent);
//         }
//     }
// 
// }


// Path: src/se/bitcraze/crazyflie/lib/crazyradio/RadioDriver.java
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import se.bitcraze.crazyflie.lib.Utilities;
import se.bitcraze.crazyflie.lib.crtp.CrtpDriver;
import se.bitcraze.crazyflie.lib.crtp.CrtpPacket;
import se.bitcraze.crazyflie.lib.usb.CrazyUsbInterface;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;

     * Sets the connection data (channel and data rate)
     * 
     * @param connectionData channel and data rate
     */
    public void setConnectionData(ConnectionData connectionData) {
        this.mConnectionData = connectionData;
    }

    /*
     *  Receive a packet though the link. This call is blocking but will
     *  timeout and return None if a timeout is supplied.
     */
    @Override
    public CrtpPacket receivePacket(int time) {
        try {
            return mInQueue.poll((long) time, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            mLogger.error("InterruptedException: " + e.getMessage());
            return null;
        }
    }

    /*
     * Send the packet though the link
     *
     *  (non-Javadoc)
     * @see cflib.crtp.CrtpDriver#sendPacket(cflib.crtp.CrtpPacket)
     */
    @Override
    public void sendPacket(CrtpPacket packet) {
        if (this.mCradio == null) {