diff --git a/.gitignore b/.gitignore
index cde185cf2cea3df2ed46b7ded928641b730089a4..3f28e68886fbeeaf60b0f7115422ea2dd356d4e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@ config.json
 dist/*
 build/*
 cache
+src/cfclient.egg-info/*
 
 # PC client settings
 conf/*
@@ -17,4 +18,4 @@ msvcp90.dll
 
 # PyCharm
 .idea/*
-.DS_Store
\ No newline at end of file
+.DS_Store
diff --git a/MANIFEST.in b/MANIFEST.in
index 7092f9064c808cbedf0f8c96268bcb7dd60fa913..131e1124d51401f6b04e5b84895fcac4ea8732d0 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,2 +1,3 @@
 recursive-include src/cfclient/configs *.json
 recursive-include src/cfclient/ui *.ui
+recursive-include src/cfclient/resources *
diff --git a/README.md b/README.md
index c053496e458e50287f8eb932750dbbc195ab00cf..21291c50e9391fb93ded867bff23dfd602a024f6 100644
--- a/README.md
+++ b/README.md
@@ -6,30 +6,16 @@ where you would like to use the Crazyflie.
 
 For more info see our [wiki](http://wiki.bitcraze.se/ "Bitcraze Wiki").
 
-Installation
-------------
-
-## Linux
-
-To install the Crazyflie PC client in Linux, you can run the setup script with:
-
-```sudo setup_linux.sh```
-
-This will install the Crazyflie PC client systemwide, create a udev entry for
-the Crazyradio and setup the permissions so that the current user can use the
-radio without root permissions after restarting the computer. For further
-instructions on how to run from source and [install dependencies](https://github.com/SteveClement/crazyflie-clients-python#dependencies) see below.
-
-## Windows
-
-Follow these steps to install the binary distribution on Windows 7/8/10.
- - Download the latest release [here](https://github.com/bitcraze/crazyflie-clients-python/releases) (named cfclient-win32-install-*.exe)
- - Execute the installer. After the install the application will be added to the start menu.
- - Install the Crazyradio drivers by following [these instructions](https://wiki.bitcraze.io/doc:crazyradio:install_windows_zadig)
+Note. The project is currently being reorganized, which means that This
+documentation might become inacurate. You can track the reorganisation work in
+the ticket #227.
 
 Running from source
 -------------------
 
+The Crazyflie client requires [cflib](https://github.com/bitcraze/crazyflie-lib-python).
+Follow the cflib readme to install it.
+
 ## Windows (7/8/10)
 
 Install dependencies. With Windows installers (tested using only 32-bit installs on 64-bit OS):
@@ -43,7 +29,14 @@ Then install PyUSB, PyZMQ, PySDL2 and PyQtGraph using pip
 C:\Users\bitcraze>\Python34\python.exe -m pip install pyusb==1.0.0b2 pyzmq pysdl2 pyqtgraph
 ```
 
-Finally you run the client using the following command
+Install cflib from https://github.com/bitcraze/crazyflie-lib-python.
+
+Install cfclient to run it from source
+```
+C:\Users\bitcraze>\Python34\python.exe -m pip install -e .
+```
+
+Finally you can run the client using the following command
 ```
 \Python34\python bin\cfclient
 ```
@@ -90,6 +83,13 @@ they might or might not be affected by this.
     pip3 install pysdl2 pyusb pyqtgraph
     ```
 
+1. Install cflib from https://github.com/bitcraze/crazyflie-lib-python
+
+1. Install cfclient to run it from source. From the source folder run:
+    ```
+    pip3 install -e .
+    ```
+
 1. You now have all the dependencies needed to run the client. From the source folder, run it with the following command:
     ```
     python bin/cfclient
@@ -120,6 +120,12 @@ they might or might not be affected by this.
     ```
     sudo port install py34-pyqtgraph
     ```
+    Install cflib from https://github.com/bitcraze/crazyflie-lib-python
+
+    Install cfclient to run it from source. From the source folder run:
+    ```
+    pip3 install -e .
+    ```
     You can now run the client from the source folder with
     ```
     python bin/cfclient
@@ -142,6 +148,13 @@ they might or might not be affected by this.
 
 ### Launching the GUI application
 
+Install cflib from https://github.com/bitcraze/crazyflie-lib-python
+
+Install cfclient to run it from source. From the source folder run (to install
+for your user only you can add ```--user``` to the command):
+```
+pip3 install -e .
+```
 To launch the GUI application in the source folder type:
 ```python bin/cfclient```
 
@@ -185,33 +198,6 @@ Example commands to install these dependencies:
 
 ### Setting udev permissions
 
-The following steps make it possible to use the USB Radio without being root.
-
-Note: If using a fresh Debian install, you may need to install sudo first
-(executing exit command to exit from root shell first):
-
-```
-su -
-apt-get install sudo
-```
-
-Now, with sudo installed, you should be able to do the following commands
-
-```
-sudo groupadd plugdev
-sudo usermod -a -G plugdev <username>
-```
-
-Create a file named ```/etc/udev/rules.d/99-crazyradio.rules``` and add the
-following:
-```
-SUBSYSTEM=="usb", ATTRS{idVendor}=="1915", ATTRS{idProduct}=="7777", MODE="0664", GROUP="plugdev"
-```
-
-To connect Crazyflie 2.0 via usb, create a file name ```/etc/udev/rules.d/99-crazyflie.rules``` and add the following:
-```
-SUBSYSTEM=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="5740", MODE="0664", GROUP="plugdev"
-```
-
-Restart the computer and you are now able to access the USB radio dongle
-without being root.
+Using Crazyradio on Linux requires that you set udev permissions. See the cflib
+[readme](https://github.com/bitcraze/crazyflie-lib-python#setting-udev-permissions)
+for more information.
diff --git a/bin/cfclient b/bin/cfclient
index 294e865043a5651b93ad43d3b7e8ab4020e86b49..4e34e85f64766a421843554ec196a6c3b14d02df 100755
--- a/bin/cfclient
+++ b/bin/cfclient
@@ -1,116 +1,5 @@
 #!/usr/bin/env python3
+from cfclient.gui import main
 
-from __future__ import absolute_import
-
-import logging
-import os
-import os.path as _path
-from os.path import expanduser
-import sys
-
-APP_NAME = "cfclient"
-
-
-def init_config_path(isInSource):
-    """
-    Configure path for config files.
-
-    If the program is started in the source folder, use a folder "conf" in the
-    root source directory. Otherwise put it in a directory depending on system
-    architecture and configuration. If the chosen directory does not exist,
-    create it.
-    """
-
-    if isInSource:
-        configPath = _path.join(sys.path[0], "..", "conf")
-    else:
-        prefix = expanduser("~")
-
-        if sys.platform == "linux2":
-            if _path.exists(_path.join(prefix, ".local")):
-                configPath = _path.join(prefix, ".local", APP_NAME)
-            else:
-                configPath = _path.join(prefix, "." + APP_NAME)
-        elif sys.platform == "win32":
-            configPath = _path.join(os.environ['APPDATA'], APP_NAME)
-        elif sys.platform == "darwin":
-            from AppKit import NSSearchPathForDirectoriesInDomains
-            # FIXME: Copy-pasted from StackOverflow, not tested!
-            # http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSSearchPathForDirectoriesInDomains
-            # NSApplicationSupportDirectory = 14
-            # NSUserDomainMask = 1
-            # True for expanding the tilde into a fully qualified path
-            configPath = _path.join(NSSearchPathForDirectoriesInDomains(
-                14, 1, True)[0], APP_NAME)
-        else:
-            # Unknown OS, I hope this is good enough
-            configPath = _path.join(prefix, "." + APP_NAME)
-
-    if not _path.exists(configPath):
-        os.makedirs(configPath)
-
-    return configPath
-
-
-def init_paths():
-    """
-    Make the app work in the source tree.
-
-    This puts the root module folder in sys.path[0] and the config folder in
-    sys.path[1]
-    """
-
-    inSource = False
-
-    if hasattr(sys, "frozen"):
-        if sys.frozen in ('dll', 'console_exe', 'windows_exe'):
-            sys.path[0] = _path.normpath(
-                _path.dirname(_path.realpath(sys.executable)))
-        elif sys.frozen in ('macosx_app',):
-            # FIXME: Copy-pasted from StackOverflow, not tested!
-            # py2app:
-            # Notes on how to find stuff on MAC, by an expert (Bob Ippolito):
-            # http://mail.python.org/pipermail/pythonmac-sig/2004-November/012121.html
-            approot = os.environ['RESOURCEPATH']
-    else:
-        prefix = _path.normpath(
-            _path.join(
-                _path.dirname(_path.realpath(__file__)), '..'))
-
-        src_lib = _path.join(prefix, 'src')
-        share_lib = prefix
-        inSource = False
-        for location in [src_lib, share_lib] + sys.path:
-            main_ui = _path.join(location, 'cfclient', 'ui', 'main.ui')
-            if _path.exists(main_ui):
-                sys.path.insert(0, location)
-                if location == src_lib:
-                    inSource = True
-                break
-
-    if sys.path[0] == "":
-        raise Exception("Cannot find cfclient install folder!")
-
-    if inSource:
-        os.environ["PYSDL2_DLL_PATH"] = os.path.abspath(sys.path[0] + "\..")
-    else:
-        os.environ["PYSDL2_DLL_PATH"] = sys.path[0]
-
-    sys.path.insert(1, init_config_path(inSource))
-
-    # Add paths to modules.
-    sys.path.append(_path.join(src_lib, 'cflib'))
-
-
-if __name__ == '__main__':
-    if sys.version_info < (3,):
-        print("The Crazyflie Python client only works with Python 3+, and "
-              "you are running it using version {}.{}.{}".format(
-                  sys.version_info.major, sys.version_info.minor,
-                  sys.version_info.micro))
-        print("Exiting!")
-        sys.exit(1)
-    init_paths()
-    import cfclient
-
-    cfclient.main()
+if __name__ == "__main__":
+    main()
diff --git a/bin/cfheadless b/bin/cfheadless
index 24bed2b1334381ec14ddcbce190a7e92792e0dac..5d88e4e130a92e5e12c338cb263607d9457f50af 100755
--- a/bin/cfheadless
+++ b/bin/cfheadless
@@ -1,93 +1,5 @@
 #!/usr/bin/env python3
+from cfclient.headless import main
 
-from __future__ import absolute_import
-
-APP_NAME = "cfclient"
-
-
-def init_config_path(isInSource):
-    import sys
-    import os
-    import os.path as _path
-    from os.path import expanduser
-
-    if isInSource:
-        configPath = _path.join(sys.path[0], "..", "conf")
-    else:
-        prefix = expanduser("~")
-
-        if sys.platform == "linux2":
-            if _path.exists(_path.join(prefix, ".local")):
-                configPath = _path.join(prefix, ".local", APP_NAME)
-            else:
-                configPath = _path.join(prefix, "." + APP_NAME)
-        elif sys.platform == "win32":
-            configPath = _path.join(os.environ['APPDATA'], APP_NAME)
-        elif sys.platform == "darwin":
-            from AppKit import NSSearchPathForDirectoriesInDomains
-            # FIXME: Copy-pasted from StackOverflow, not tested!
-            # http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSSearchPathForDirectoriesInDomains
-            # NSApplicationSupportDirectory = 14
-            # NSUserDomainMask = 1
-            # True for expanding the tilde into a fully qualified path
-            configPath = path.join(
-                NSSearchPathForDirectoriesInDomains(14, 1, True)[0], APPNAME)
-        else:
-            # Unknown OS, I hope this is good enough
-            configPath = _path.join(prefix, "." + APP_NAME)
-
-    if not _path.exists(configPath):
-        os.makedirs(configPath)
-
-    return configPath
-
-
-def init_paths():
-    """Make the app work in the source tree.
-       This puts the root module folder in path[0] and the config folder in
-       path[1]"""
-    import sys
-    import os.path as _path
-
-    sys.path = ["", ""] + sys.path
-    inSource = False
-
-    if hasattr(sys, "frozen"):
-        if sys.frozen in ('dll', 'console_exe', 'windows_exe'):
-            sys.path[0] = _path.normpath(
-                _path.dirname(_path.realpath(sys.executable)))
-        elif frozen in ('macosx_app',):
-            # FIXME: Copy-pasted from StackOverflow, not tested!
-            # py2app:
-            # Notes on how to find stuff on MAC, by an expert (Bob Ippolito):
-            # http://mail.python.org/pipermail/pythonmac-sig/2004-November/012121.html
-            approot = os.environ['RESOURCEPATH']
-    else:
-        prefix = _path.normpath(
-            _path.join(_path.dirname(_path.realpath(__file__)), '..'))
-
-        src_lib = _path.join(prefix, 'src')
-        share_lib = prefix
-        inSource = False
-        for location in [src_lib, share_lib] + sys.path:
-            main_ui = _path.join(location, 'cfclient', 'ui', 'main.ui')
-            if _path.exists(main_ui):
-                sys.path[0] = location
-                if location == src_lib:
-                    inSource = True
-                break
-
-    if sys.path[0] == "":
-        raise Exception("Cannot find cfclient install folder!")
-
-    sys.path[1] = init_config_path(inSource)
-
-    # Add paths to modules.
-    sys.path.append(_path.join(src_lib, 'cflib'))
-
-
-if __name__ == '__main__':
-    init_paths()
-    import cfheadless
-
-    cfheadless.main()
+if __name__ == "__main__":
+    main()
diff --git a/bin/cfloader b/bin/cfloader
index 2b68dd209d71477ab2286f772d475bab32ad8276..0def9b718012121a6d6edbe0ca722414efb0644e 100755
--- a/bin/cfloader
+++ b/bin/cfloader
@@ -1,204 +1,5 @@
 #!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
+from cfloader import main
 
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-# Crazy Loader bootloader utility
-# Can reset bootload and reset back the bootloader
-
-import sys
-import os
-# Fix the path so imports works regardless from where it's run
-sys.path[0] = os.path.join(sys.path[0][:-4], "src/cflib")
-
-import cflib.crtp  # noqa
-from cflib.bootloader import Bootloader  # noqa
-from cflib.bootloader.boottypes import BootVersion, TargetTypes, Target  # noqa
-
-# Initialise the CRTP link driver
-link = None
-cload = None
-try:
-    cflib.crtp.init_drivers()
-    link = cflib.crtp.get_link_driver("radio://")
-except Exception as e:
-    print("Error: {}".format(str(e)))
-    if link:
-        link.close()
-    sys.exit(-1)
-
-# Set the default parameters
-# Default to Arnaud's copter
-cpu_id = "32:00:6e:06:58:37:35:32:60:58:01:43"
-clink = None
-action = "info"
-boot = "cold"
-
-if len(sys.argv) < 2:
-    print()
-    print("==============================")
-    print(" CrazyLoader Flash Utility")
-    print("==============================")
-    print()
-    print(" Usage:", sys.argv[0], "[CRTP options] <action> [parameters]")
-    print()
-    print("The CRTP options are described above")
-    print()
-    print("Crazyload option:")
-    print("   info                    : Print the info of the bootloader "
-          "and quit.")
-    print("                             Will let the target in bootloader "
-          "mode")
-    print("   reset                   : Reset the device in firmware mode")
-    print("   flash <file> [targets]  : flash the <img> binary file from "
-          "the first")
-    print("                             possible  page in flash and reset "
-          "to firmware")
-    print("                             mode.")
-    if link:
-        link.close()
-    sys.exit(0)
-
-# Analyse the command line parameters
-sys.argv = sys.argv[1:]
-argv = []
-
-warm_uri = None
-
-i = 0
-while i < len(sys.argv):
-    if sys.argv[i] == "-i":
-        i += 1
-        cpu_id = sys.argv[i]
-    elif sys.argv[i] == "--cold-boot" or sys.argv[i] == "-c":
-        boot = "cold"
-    elif sys.argv[i] == "--warm-boot" or sys.argv[i] == "-w":
-        boot = "reset"
-        i += 1
-        clink = sys.argv[i]
-    else:
-        argv += [sys.argv[i]]
-    i += 1
-sys.argv = argv
-
-# Analyse the command
-if len(sys.argv) < 1:
-    action = "info"
-elif sys.argv[0] == "info":
-    action = "info"
-elif sys.argv[0] == "reset":
-    action = "reset"
-elif sys.argv[0] == "flash":
-    # print len(sys.argv)
-    if len(sys.argv) < 2:
-        print("The flash action require a file name.")
-        link.close()
-        sys.exit(-1)
-    action = "flash"
-    filename = sys.argv[1]
-    targetnames = {}
-    for t in sys.argv[2:]:
-        [target, type] = t.split("-")
-        if target in targetnames:
-            targetnames[target] += (type,)
-        else:
-            targetnames[target] = (type,)
-else:
-    print("Action", sys.argv[0], "unknown!")
-    link.close()
-    sys.exit(-1)
-
-# Currently there's two different targets available
-targets = ()
-
-try:
-    # Initialise the bootloader lib
-    bl = Bootloader(clink)
-
-    #########################################
-    # Get the connection with the bootloader
-    #########################################
-    # The connection is done by reseting to the bootloader (default)
-    if boot == "reset":
-        print("Reset to bootloader mode ..."),
-        sys.stdout.flush()
-        if bl.start_bootloader(warm_boot=True):
-            print(" done!")
-        else:
-            print("Failed to warmboot")
-            bl.close()
-            sys.exit(-1)
-    else:  # The connection is done by a cold boot ...
-        print("Restart the Crazyflie you want to bootload in the next"),
-        print(" 10 seconds ..."),
-
-        sys.stdout.flush()
-        if bl.start_bootloader(warm_boot=False):
-            print(" done!")
-        else:
-            print("Cannot connect the bootloader!")
-            bl.close()
-            sys.exit(-1)
-
-    print("Connected to bootloader on {} (version=0x{:X})".format(
-        BootVersion.to_ver_string(bl.protocol_version),
-        bl.protocol_version))
-
-    if bl.protocol_version == BootVersion.CF2_PROTO_VER:
-        targets += (bl.get_target(TargetTypes.NRF51),)
-    targets += (bl.get_target(TargetTypes.STM32),)
-
-    ######################################
-    # Doing something (hopefully) useful
-    ######################################
-
-    # Print information about the targets
-    for target in targets:
-        print(target)
-    if action == "info":
-        None  # Already done ...
-    elif action == "reset":
-        print
-        print("Reset in firmware mode ...")
-        bl.reset_to_firmware()
-    elif action == "flash":
-        bl.flash(filename, targetnames)
-        print("Reset in firmware mode ...")
-        bl.reset_to_firmware()
-    else:
-        None
-except Exception as e:
-    import traceback
-
-    traceback.print_exc(file=sys.stdout)
-    print(e)
-
-finally:
-    #########################
-    # Closing the connection
-    #########################
-    if bl:
-        bl.close()
+if __name__ == "__main__":
+    main()
diff --git a/bin/cfzmq b/bin/cfzmq
index 3881a98a459f8d67e6201327ba94a93135496432..8cffe898d0d982f2232f06bb3f58fca75b795fec 100755
--- a/bin/cfzmq
+++ b/bin/cfzmq
@@ -1,93 +1,5 @@
 #!/usr/bin/env python3
+from cfzmq import main
 
-from __future__ import absolute_import
-
-APP_NAME = "cfzmq"
-
-
-def init_config_path(isInSource):
-    import sys
-    import os
-    import os.path as _path
-    from os.path import expanduser
-
-    if isInSource:
-        configPath = _path.join(sys.path[0], "..", "conf")
-    else:
-        prefix = expanduser("~")
-
-        if sys.platform == "linux2":
-            if _path.exists(_path.join(prefix, ".local")):
-                configPath = _path.join(prefix, ".local", APP_NAME)
-            else:
-                configPath = _path.join(prefix, "." + APP_NAME)
-        elif sys.platform == "win32":
-            configPath = _path.join(os.environ['APPDATA'], APP_NAME)
-        elif sys.platform == "darwin":
-            from AppKit import NSSearchPathForDirectoriesInDomains
-            # FIXME: Copy-pasted from StackOverflow, not tested!
-            # http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSSearchPathForDirectoriesInDomains
-            # NSApplicationSupportDirectory = 14
-            # NSUserDomainMask = 1
-            # True for expanding the tilde into a fully qualified path
-            configPath = path.join(
-                NSSearchPathForDirectoriesInDomains(14, 1, True)[0], APPNAME)
-        else:
-            # Unknown OS, I hope this is good enough
-            configPath = _path.join(prefix, "." + APP_NAME)
-
-    if not _path.exists(configPath):
-        os.makedirs(configPath)
-
-    return configPath
-
-
-def init_paths():
-    """Make the app work in the source tree.
-       This puts the root module folder in path[0] and the config folder in
-       path[1]"""
-    import sys
-    import os.path as _path
-
-    sys.path = ["", ""] + sys.path
-    inSource = False
-
-    if hasattr(sys, "frozen"):
-        if sys.frozen in ('dll', 'console_exe', 'windows_exe'):
-            sys.path[0] = _path.normpath(
-                _path.dirname(_path.realpath(sys.executable)))
-        elif frozen in ('macosx_app',):
-            # FIXME: Copy-pasted from StackOverflow, not tested!
-            # py2app:
-            # Notes on how to find stuff on MAC, by an expert (Bob Ippolito):
-            # http://mail.python.org/pipermail/pythonmac-sig/2004-November/012121.html
-            approot = os.environ['RESOURCEPATH']
-    else:
-        prefix = _path.normpath(
-            _path.join(_path.dirname(_path.realpath(__file__)), '..'))
-
-        src_lib = _path.join(prefix, 'src')
-        share_lib = prefix
-        inSource = False
-        for location in [src_lib, share_lib] + sys.path:
-            main_ui = _path.join(location, 'cfclient', 'ui', 'main.ui')
-            if _path.exists(main_ui):
-                sys.path[0] = location
-                if location == src_lib:
-                    inSource = True
-                break
-
-    if sys.path[0] == "":
-        raise Exception("Cannot find cfclient install folder!")
-
-    sys.path[1] = init_config_path(inSource)
-
-    # Add paths to modules.
-    sys.path.append(_path.join(src_lib, 'cflib'))
-
-
-if __name__ == '__main__':
-    init_paths()
-    import cfzmq
-
-    cfzmq.main()
+if __name__ == "__main__":
+    main()
diff --git a/setup.py b/setup.py
index ccc6b48a70ffcfd2d714d7396f5a8e7a2e5d1105..e7f311853a42173f77c0f094e7765f6aa80b8161 100644
--- a/setup.py
+++ b/setup.py
@@ -1,123 +1,57 @@
 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
-import glob
-import os
-import sys
-from distutils.core import setup
+import subprocess
 from subprocess import PIPE
 from subprocess import Popen
+from setuptools import setup, find_packages
 
 
 # Recover version from Git
-try:
-    process = Popen(["git", "describe", "--tags"], stdout=PIPE)
-    (output, err) = process.communicate()
-    exit_code = process.wait()
-except OSError:
-    raise Exception("Cannot run git: Git is required to generate packages!")
-
-VERSION = output.strip().decode("UTF-8")
-
-toplevel_data_files = ['README.md', 'LICENSE.txt']
-
-# Platform specific settings
-if sys.platform.startswith('win32'):
+def get_version():
     try:
-        import py2exe
-    except ImportError:
-        print("Warning: py2exe not usable")
+        process = Popen(["git", "describe", "--tags"], stdout=PIPE)
+        (output, err) = process.communicate()
+        process.wait()
+    except OSError:
+        raise Exception("Cannot run git: " +
+                        "Git is required to generate packages!")
 
-    setup_args = dict(
-        console=[{
-            "script": 'bin/cfclient',
-            "icon_resources": [(1, "bitcraze.ico")]
-        }],
-        options={"py2exe": {
-            "includes": [
-                "sip", "PyQt4",
-                "cfclient.ui.widgets",
-                "cflib.bootloader.cloader",
-                "cfclient.ui.toolboxes.*",
-                "cfclient.ui.*",
-                "cfclient.ui.tabs.*",
-                "cfclient.ui.widgets.*",
-                "cfclient.ui.dialogs.*",
-                "cfclient.utils.input.inputreaders.*",
-                "cfclient.utils.input.inputinterfaces.*",
-                'zmq.backend.cython'],
-            "excludes": [
-                "AppKit",
-                'zmq.libzmq'],
-            'dll_excludes': [
-                'libzmq.pyd'],
-            "skip_archive": True}})
+    version = output.strip().decode("UTF-8")
 
-    toplevel_data_files.append('SDL2.dll')
-else:
-    setup_args = dict(
-        scripts=['bin/cfclient', 'bin/cfheadless'])
-
-# Initial parameters
-setup_args = dict(name='cfclient',
-                  description='Bitcraze Cazyflie nano quadcopter client',
-                  version=VERSION,
-                  author='Bitcraze team',
-                  author_email='contact@bitcraze.se',
-                  url='http://www.bitcraze.se',
-                  package_dir={'': 'lib'},
-                  packages=['cfclient', 'cfclient.ui', 'cfclient.ui.tabs',
-                            'cfclient.ui.toolboxes', 'cfclient.ui.widgets',
-                            'cfclient.utils', 'cfclient.ui.dialogs', 'cflib',
-                            'cflib.bootloader', 'cflib.crazyflie',
-                            'cflib.drivers',
-                            'cflib.utils', 'cflib.crtp',
-                            'cfclient.utils.input',
-                            'cfclient.utils.input.inputinterfaces',
-                            'cfclient.utils.input.mux',
-                            'cfclient.utils.input.inputreaders'],
-                  data_files=[('', toplevel_data_files),
-                              ('cfclient/ui',
-                               glob.glob('src/cfclient/ui/*.ui')),
-                              ('cfclient/ui/tabs',
-                               glob.glob('src/cfclient/ui/tabs/*.ui')),
-                              ('cfclient/ui/widgets',
-                               glob.glob('src/cfclient/ui/widgets/*.ui')),
-                              ('cfclient/ui/toolboxes',
-                               glob.glob('src/cfclient/ui/toolboxes/*.ui')),
-                              ('cfclient/ui/dialogs',
-                               glob.glob('src/cfclient/ui/dialogs/*.ui')),
-                              ('cfclient/configs',
-                               glob.glob('src/cfclient/configs/*.json')),
-                              ('cflib/cache',
-                               glob.glob('src/cflib/cache/*.json')),
-                              ('cfclient/configs/input',
-                               glob.glob('src/cfclient/configs/input/*.json')),
-                              ('cfclient/configs/log',
-                               glob.glob('src/cfclient/configs/log/*.json')),
-                              ('cfclient',
-                               glob.glob('src/cfclient/*.png'))],
-                  **setup_args)
+    if subprocess.call(["git", "diff-index", "--quiet", "HEAD"]) != 0:
+        version += "_modified"
 
+    return version
 
-# Fetch values from package.xml when using catkin
-if os.getenv('CATKIN_TEST_RESULTS_DIR'):
-    from catkin_pkg.python_setup import generate_distutils_setup
-    # Delete keys which should not match catkin packaged variant
-    for k in ('version', 'url'):
-        setup_args.pop(k, None)
-    setup_args = generate_distutils_setup(**setup_args)
+VERSION = get_version()
 
-
-# Write a temp file to pass verision into script
-version_file = os.path.join(os.path.dirname(__file__),
-                            "lib", "cfclient", "version.py")
-try:
-    with open(version_file, "w") as versionpy:
-        versionpy.write("VERSION='{}'".format(VERSION))
-except:
-    print("Warning: Version file cannot be written.")
-
-setup(**setup_args)
-
-if (os.path.isfile(version_file)):
-    os.remove(version_file)
+# Initial parameters
+setup(
+    name='cfclient',
+    description='Bitcraze Cazyflie quadcopter client',
+    version=VERSION,
+    author='Bitcraze team',
+    author_email='contact@bitcraze.se',
+    url='http://www.bitcraze.io',
+
+    classifiers=[
+        'License :: OSI Approved :: GPLv2 License',
+
+        'Programming Language :: Python :: 3.4',
+        'Programming Language :: Python :: 3.5',
+    ],
+
+    keywords='quadcopter crazyflie',
+
+    package_dir={'': 'src'},
+    packages=['cfclient', 'cfzmq', 'cfloader'],
+
+    entry_points={
+        'console_scripts': [
+            'cfclient=cfclient.gui:main',
+            'cfheadless=cfclient.headless:main',
+            'cfloader=cfloader:main',
+            'cfzmq=cfzmq:main'
+        ],
+    }
+)
diff --git a/setup_linux.sh b/setup_linux.sh
deleted file mode 100755
index 648265d533075a717f332a153f8dbf214a9a1bfa..0000000000000000000000000000000000000000
--- a/setup_linux.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-# Install the Crazyflie PC client and set up permissions so that it can be used
-# by the current user immediately
-# Caution! This installs the Crazyflie PC client as root to your Python
-# site-packages directory. If you wish to install it as a normal user, use the
-# instructions on the Wiki at
-# http://wiki.bitcraze.se/projects:crazyflie:pc_utils:install
-# After installation, the Crazyflie PC client can be started with `cfclient`.
-# @author Daniel Lee 2013
-
-# Allow user to use USB radio without root permission
-groupadd plugdev
-usermod -a -G plugdev $USER
-echo SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"1915\", ATTRS{idProduct}==\"7777\", \
-MODE=\"0664\", GROUP=\"plugdev\" > /etc/udev/rules.d/99-crazyradio.rules
-echo SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"0483\", ATTRS{idProduct}==\"5740\", \
-MODE=\"0664\", GROUP=\"plugdev\" > /etc/udev/rules.d/99-crazyflie.rules
-
-# Install Crazyflie PC client
-python3 setup.py install
-
diff --git a/src/cfclient/__init__.py b/src/cfclient/__init__.py
index a9b1b5711ab4853df14e42efd489721c75e37dba..d0782e593c116ad6f0bc224750e3a9ac1eeadef4 100644
--- a/src/cfclient/__init__.py
+++ b/src/cfclient/__init__.py
@@ -24,24 +24,50 @@
 #  this program; if not, write to the Free Software Foundation, Inc., 51
 #  Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
-from .cfclient import main
+import os
+import pkg_resources
+
+
+def _init_config_path():
+    import sys
+    import os
+    import os.path as _path
+    from os.path import expanduser
+
+    prefix = expanduser("~")
+
+    if sys.platform == "linux2":
+        if _path.exists(_path.join(prefix, ".local")):
+            configPath = _path.join(prefix, ".local", __name__)
+        else:
+            configPath = _path.join(prefix, "." + __name__)
+    elif sys.platform == "win32":
+        configPath = _path.join(os.environ['APPDATA'], __name__)
+    elif sys.platform == "darwin":
+        from AppKit import NSSearchPathForDirectoriesInDomains
+        # FIXME: Copy-pasted from StackOverflow, not tested!
+        # http://developer.apple.com/DOCUMENTATION/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSSearchPathForDirectoriesInDomains # noqa
+        # NSApplicationSupportDirectory = 14
+        # NSUserDomainMask = 1
+        # True for expanding the tilde into a fully qualified path
+        configPath = _path.join(
+            NSSearchPathForDirectoriesInDomains(14, 1, True)[0], __name__)
+    else:
+        # Unknown OS, I hope this is good enough
+        configPath = _path.join(prefix, "." + __name__)
+
+    if not _path.exists(configPath):
+        os.makedirs(configPath)
+
+    return configPath
+
+# Path used all over the application
+# FIXME: module_path is missused: it should not be used to load ressources if
+#        we want to be able to follow PEP302 and run from zip!
+module_path = os.path.dirname(__file__)
+config_path = _init_config_path()
 
 try:
-    from .version import VERSION
-except:
-    try:
-        import subprocess
-
-        VERSION = subprocess.check_output(["git", "describe"]).encode('utf-8')
-    except:
-        VERSION = "dev"
-
-    try:
-        import subprocess
-
-        ret = subprocess.call(["git", "diff", "--quiet", "HEAD"]
-                              ).encode('utf-8')
-        if ret > 0:
-            VERSION += "+"
-    except:
-        VERSION += "+"
+    VERSION = pkg_resources.require("cfclient")[0].version
+except pkg_resources.DistributionNotFound:
+    VERSION = "dev"
diff --git a/src/cfclient/cfclient.py b/src/cfclient/gui.py
similarity index 96%
rename from src/cfclient/cfclient.py
rename to src/cfclient/gui.py
index 901234ab5f03b8df027261756292b68a5bbdad6c..b53a4971e41eb64ff1b3a01779c44272b157a029 100644
--- a/src/cfclient/cfclient.py
+++ b/src/cfclient/gui.py
@@ -33,6 +33,8 @@ import datetime
 
 import logging
 
+import cfclient
+
 __author__ = 'Bitcraze AB'
 __all__ = ['']
 
@@ -80,7 +82,7 @@ def main():
 
     logger = logging.getLogger(__name__)
 
-    logger.debug("Using config path {}".format(sys.path[1]))
+    logger.debug("Using config path {}".format(cfclient.config_path))
     logger.debug("sys.path={}".format(sys.path))
 
     # Try all the imports used in the project here to control what happens....
@@ -135,7 +137,7 @@ def main():
 
     app = QApplication(sys.argv)
 
-    app.setWindowIcon(QIcon(sys.path[0] + "/cfclient/icon-256.png"))
+    app.setWindowIcon(QIcon(cfclient.module_path + "/icon-256.png"))
     # Make sure the right icon is set in Windows 7+ taskbar
     if os.name == 'nt':
         import ctypes
@@ -150,3 +152,6 @@ def main():
     main_window = MainUI()
     main_window.show()
     sys.exit(app.exec_())
+
+if __name__ == "__main__":
+    main()
diff --git a/src/cfheadless.py b/src/cfclient/headless.py
similarity index 96%
rename from src/cfheadless.py
rename to src/cfclient/headless.py
index 5c14ee8315e13d0fdf2d621b18dd50386f6d648f..683975e4065f9609c4dfdd6aa2f37f258ad9c886 100644
--- a/src/cfheadless.py
+++ b/src/cfclient/headless.py
@@ -57,8 +57,8 @@ class HeadlessClient():
 
         self._jr = JoystickReader(do_device_discovery=False)
 
-        self._cf = Crazyflie(ro_cache=sys.path[0] + "/cflib/cache",
-                             rw_cache=sys.path[1] + "/cache")
+        self._cf = Crazyflie(ro_cache=None,
+                             rw_cache=cfclient.config_path + "/cache")
 
         signal.signal(signal.SIGINT, signal.SIG_DFL)
 
@@ -90,7 +90,7 @@ class HeadlessClient():
         for i, dev in enumerate(self._devs):
             print(" - Controller #{}: {}".format(i, dev))
         print("\nAvailable input mapping:")
-        for map in os.listdir(sys.path[1] + '/input'):
+        for map in os.listdir(cfclient.config_path + '/input'):
             print(" - " + map.split(".json")[0])
 
     def connect_crazyflie(self, link_uri):
@@ -168,3 +168,6 @@ def main():
             headless.connect_crazyflie(link_uri=args.uri)
         else:
             print("No input-device connected, exiting!")
+
+if __name__ == "__main__":
+    main()
diff --git a/src/cfclient/ui/dialogs/about.py b/src/cfclient/ui/dialogs/about.py
index 730b880b9326d479b07342db7e86beef1b82817f..6647b6b508d7e3075767306516c810e5c434c746 100644
--- a/src/cfclient/ui/dialogs/about.py
+++ b/src/cfclient/ui/dialogs/about.py
@@ -26,6 +26,7 @@
 """
 The about dialog.
 """
+
 import sys
 
 import cfclient
@@ -42,8 +43,8 @@ __author__ = 'Bitcraze AB'
 __all__ = ['AboutDialog']
 
 (about_widget_class,
- about_widget_base_class) = (uic.loadUiType(sys.path[0] +
-                                            '/cfclient/ui/dialogs/about.ui'))
+ about_widget_base_class) = (uic.loadUiType(cfclient.module_path +
+                                            '/ui/dialogs/about.ui'))
 
 DEBUG_INFO_FORMAT = """
 <b>Cfclient</b><br>
diff --git a/src/cfclient/ui/dialogs/bootloader.py b/src/cfclient/ui/dialogs/bootloader.py
index 41f17fbbea5cff9c583ec7a3e7a4cfa6a4713867..99a2113351616e3b34f706f6488c40b250c1eae3 100644
--- a/src/cfclient/ui/dialogs/bootloader.py
+++ b/src/cfclient/ui/dialogs/bootloader.py
@@ -32,7 +32,6 @@ read/write the configuration block in the Crazyflie flash.
 from cflib.bootloader import Bootloader
 
 import struct
-import sys
 import time
 
 import logging
@@ -40,6 +39,7 @@ import logging
 from PyQt4 import QtCore, QtGui, uic
 from PyQt4.QtCore import Qt, pyqtSlot, pyqtSignal, QThread, SIGNAL
 
+import cfclient
 from cfclient.ui.tab import Tab
 
 import cflib.crtp
@@ -51,8 +51,8 @@ __all__ = ['BootloaderDialog']
 
 logger = logging.getLogger(__name__)
 
-service_dialog_class = uic.loadUiType(sys.path[0] +
-                                      "/cfclient/ui/dialogs/bootloader.ui")[0]
+service_dialog_class = uic.loadUiType(cfclient.module_path +
+                                      "/ui/dialogs/bootloader.ui")[0]
 
 
 class UIState:
diff --git a/src/cfclient/ui/dialogs/cf1config.py b/src/cfclient/ui/dialogs/cf1config.py
index 752d47845b3b07cc7b29ce4c7934ccb87bd8d9cc..98ad3a660437d67fec0607935f64386f5a9ca324 100644
--- a/src/cfclient/ui/dialogs/cf1config.py
+++ b/src/cfclient/ui/dialogs/cf1config.py
@@ -31,7 +31,6 @@ read/write the configuration block in the Crazyflie flash.
 """
 
 import struct
-import sys
 from cflib.bootloader import Bootloader
 
 import logging
@@ -39,6 +38,7 @@ import logging
 from PyQt4 import QtCore, QtGui, uic
 from PyQt4.QtCore import Qt, pyqtSlot, pyqtSignal, QThread, SIGNAL
 
+import cfclient
 from cfclient.utils.config import Config
 from functools import reduce
 
@@ -47,8 +47,8 @@ __all__ = ['Cf1ConfigDialog']
 
 logger = logging.getLogger(__name__)
 
-service_dialog_class = uic.loadUiType(sys.path[0] +
-                                      "/cfclient/ui/dialogs/cf1config.ui")[0]
+service_dialog_class = uic.loadUiType(cfclient.module_path +
+                                      "/ui/dialogs/cf1config.ui")[0]
 
 
 class UIState:
diff --git a/src/cfclient/ui/dialogs/cf2config.py b/src/cfclient/ui/dialogs/cf2config.py
index de278d213d9a32635c928c234b9f9e0e489c6be2..03e1527ea7722246d4f62235ced961c6b20da3bd 100644
--- a/src/cfclient/ui/dialogs/cf2config.py
+++ b/src/cfclient/ui/dialogs/cf2config.py
@@ -28,25 +28,21 @@ The bootloader dialog is used to update the Crazyflie firmware and to
 read/write the configuration block in the Crazyflie flash.
 """
 import logging
-import sys
 
+import cfclient
 from cflib.crazyflie.mem import MemoryElement
-from PyQt4 import QtCore
+
 from PyQt4 import QtGui
 from PyQt4 import uic
 from PyQt4.QtCore import pyqtSignal
-from PyQt4.QtCore import pyqtSlot
-from PyQt4.QtCore import Qt
-from PyQt4.QtCore import QThread
-from PyQt4.QtCore import SIGNAL
 
 __author__ = 'Bitcraze AB'
 __all__ = ['CfConfig']
 
 logger = logging.getLogger(__name__)
 
-service_dialog_class = uic.loadUiType(sys.path[0] +
-                                      "/cfclient/ui/dialogs/cf2config.ui")[0]
+service_dialog_class = uic.loadUiType(cfclient.module_path +
+                                      "/ui/dialogs/cf2config.ui")[0]
 
 
 class Cf2ConfigDialog(QtGui.QWidget, service_dialog_class):
diff --git a/src/cfclient/ui/dialogs/inputconfigdialogue.py b/src/cfclient/ui/dialogs/inputconfigdialogue.py
index 504bf96fe01b608fa299db51ca8fea5e28ebd156..58dd95682327def13cab4141789caff1b6903ee1 100644
--- a/src/cfclient/ui/dialogs/inputconfigdialogue.py
+++ b/src/cfclient/ui/dialogs/inputconfigdialogue.py
@@ -29,8 +29,8 @@ buttons and axis to match controls for the Crazyflie.
 """
 import json
 import logging
-import sys
 
+import cfclient
 from cfclient.utils.config_manager import ConfigManager
 from cfclient.utils.input import JoystickReader
 from cflib.crtp.exceptions import CommunicationException
@@ -48,7 +48,7 @@ __all__ = ['InputConfigDialogue']
 logger = logging.getLogger(__name__)
 
 (inputconfig_widget_class, connect_widget_base_class) = (
-    uic.loadUiType(sys.path[0] + '/cfclient/ui/dialogs/inputconfigdialogue.ui')
+    uic.loadUiType(cfclient.module_path + '/ui/dialogs/inputconfigdialogue.ui')
 )
 
 
diff --git a/src/cfclient/ui/dialogs/logconfigdialogue.py b/src/cfclient/ui/dialogs/logconfigdialogue.py
index 51d1354f880ef4ed1e888c341e8d7ff160c0566d..4f90026e3f85ca06ce7f3859bb96fe19b560f6b4 100644
--- a/src/cfclient/ui/dialogs/logconfigdialogue.py
+++ b/src/cfclient/ui/dialogs/logconfigdialogue.py
@@ -31,10 +31,10 @@ enable logging of data from the Crazyflie. These can then be used in different
 views in the UI.
 """
 
-import sys
 import os
 import logging
 
+import cfclient
 from PyQt4 import Qt, QtCore, QtGui, uic
 from PyQt4.QtCore import *
 from PyQt4.QtGui import *
@@ -48,7 +48,7 @@ __all__ = ['LogConfigDialogue']
 logger = logging.getLogger(__name__)
 
 (logconfig_widget_class, connect_widget_base_class) = (
-    uic.loadUiType(sys.path[0] + '/cfclient/ui/dialogs/logconfigdialogue.ui'))
+    uic.loadUiType(cfclient.module_path + '/ui/dialogs/logconfigdialogue.ui'))
 
 NAME_FIELD = 0
 ID_FIELD = 1
diff --git a/src/cfclient/ui/main.py b/src/cfclient/ui/main.py
index cea132070435555587e3f65c7982a2bb3aab45e8..54cbbc0f293148182fbecdf3578d8d57ec7e51d7 100644
--- a/src/cfclient/ui/main.py
+++ b/src/cfclient/ui/main.py
@@ -29,6 +29,7 @@ The main file for the Crazyflie control application.
 import logging
 import sys
 
+import cfclient
 import cfclient.ui.tabs
 import cfclient.ui.toolboxes
 import cflib.crtp
@@ -74,8 +75,8 @@ logger = logging.getLogger(__name__)
 INTERFACE_PROMPT_TEXT = 'Select an interface'
 
 (main_window_class,
- main_windows_base_class) = (uic.loadUiType(sys.path[0] +
-                                            '/cfclient/ui/main.ui'))
+ main_windows_base_class) = (uic.loadUiType(cfclient.module_path +
+                                            '/ui/main.ui'))
 
 
 class MyDockWidget(QtGui.QDockWidget):
@@ -168,8 +169,8 @@ class MainUI(QtGui.QMainWindow, main_window_class):
 
         ######################################################
 
-        self.cf = Crazyflie(ro_cache=sys.path[0] + "/cflib/cache",
-                            rw_cache=sys.path[1] + "/cache")
+        self.cf = Crazyflie(ro_cache=None,
+                            rw_cache=cfclient.config_path + "/cache")
 
         cflib.crtp.init_drivers(enable_debug_driver=Config()
                                 .get("enable_debug_driver"))
@@ -789,8 +790,9 @@ class MainUI(QtGui.QMainWindow, main_window_class):
         self._update_input_device_footer()
 
     def _open_config_folder(self):
-        QDesktopServices.openUrl(QUrl("file:///" +
-                                      QDir.toNativeSeparators(sys.path[1])))
+        QDesktopServices.openUrl(
+            QUrl("file:///" +
+                 QDir.toNativeSeparators(cfclient.config_path)))
 
     def closeAppRequest(self):
         self.close()
diff --git a/src/cfclient/ui/tabs/ConsoleTab.py b/src/cfclient/ui/tabs/ConsoleTab.py
index 29a77bd6990ec74bff96eaad2bca801829bae231..3e173277332afd1dca34ae3d24b32cda22028630 100644
--- a/src/cfclient/ui/tabs/ConsoleTab.py
+++ b/src/cfclient/ui/tabs/ConsoleTab.py
@@ -30,13 +30,13 @@ The console tab is used as a console for printouts from the Crazyflie.
 """
 
 import time
-import sys
 
 import logging
 
 from PyQt4 import QtCore, QtGui, uic
 from PyQt4.QtCore import pyqtSlot, pyqtSignal
 
+import cfclient
 from cfclient.ui.tab import Tab
 
 __author__ = 'Bitcraze AB'
@@ -44,8 +44,8 @@ __all__ = ['ConsoleTab']
 
 logger = logging.getLogger(__name__)
 
-console_tab_class = uic.loadUiType(sys.path[0] +
-                                   "/cfclient/ui/tabs/consoleTab.ui")[0]
+console_tab_class = uic.loadUiType(cfclient.module_path +
+                                   "/ui/tabs/consoleTab.ui")[0]
 
 
 class ConsoleTab(Tab, console_tab_class):
diff --git a/src/cfclient/ui/tabs/ExampleTab.py b/src/cfclient/ui/tabs/ExampleTab.py
index 16936bbe29018055812293e0a9e570bfc8c4e703..fe40b5aba74d018d030e6e34f6994686acf03ac4 100644
--- a/src/cfclient/ui/tabs/ExampleTab.py
+++ b/src/cfclient/ui/tabs/ExampleTab.py
@@ -33,12 +33,12 @@ connects the connected/disconnected callbacks.
 """
 
 import logging
-import sys
 
 from PyQt4 import QtCore, QtGui, uic
 from PyQt4.QtCore import pyqtSlot, pyqtSignal, QThread, Qt
 from PyQt4.QtGui import QMessageBox
 
+import cfclient
 from cfclient.ui.tab import Tab
 
 from cflib.crazyflie.log import LogConfig, Log
@@ -49,8 +49,8 @@ __all__ = ['ExampleTab']
 
 logger = logging.getLogger(__name__)
 
-example_tab_class = uic.loadUiType(sys.path[0] +
-                                   "/cfclient/ui/tabs/exampleTab.ui")[0]
+example_tab_class = uic.loadUiType(cfclient.module_path +
+                                   "/ui/tabs/exampleTab.ui")[0]
 
 
 class ExampleTab(Tab, example_tab_class):
diff --git a/src/cfclient/ui/tabs/FlightTab.py b/src/cfclient/ui/tabs/FlightTab.py
index b2ec43983bf9d3d2323b5ad96bd2d759a467a67c..22195db5f743d26b60d31ecb3355d425e335f5f5 100644
--- a/src/cfclient/ui/tabs/FlightTab.py
+++ b/src/cfclient/ui/tabs/FlightTab.py
@@ -29,8 +29,6 @@
 The flight control tab shows telemetry data and flight settings.
 """
 
-import sys
-
 import logging
 
 from time import time
@@ -41,6 +39,7 @@ from PyQt4.QtGui import QMessageBox
 
 from cflib.crazyflie import Crazyflie
 
+import cfclient
 from cfclient.ui.widgets.ai import AttitudeIndicator
 
 from cfclient.utils.config import Config
@@ -55,8 +54,8 @@ __all__ = ['FlightTab']
 
 logger = logging.getLogger(__name__)
 
-flight_tab_class = uic.loadUiType(sys.path[0] +
-                                  "/cfclient/ui/tabs/flightTab.ui")[0]
+flight_tab_class = uic.loadUiType(cfclient.module_path +
+                                  "/ui/tabs/flightTab.ui")[0]
 
 MAX_THRUST = 65365.0
 
diff --git a/src/cfclient/ui/tabs/GpsTab.py b/src/cfclient/ui/tabs/GpsTab.py
index f29370228a805b00004714e4e2eec22eaf4371f8..bb69974ec34e21042c4e9d74c25aa088d1ab6bbe 100644
--- a/src/cfclient/ui/tabs/GpsTab.py
+++ b/src/cfclient/ui/tabs/GpsTab.py
@@ -30,8 +30,8 @@ pre-configured.
 """
 import logging
 import math
-import sys
 
+import cfclient
 from cfclient.ui.tab import Tab
 from cflib.crazyflie.log import LogConfig
 from PyQt4 import QtCore
@@ -47,8 +47,8 @@ __all__ = ['GpsTab']
 
 logger = logging.getLogger(__name__)
 
-gps_tab_class = uic.loadUiType(sys.path[0] +
-                               "/cfclient/ui/tabs/gpsTab.ui")[0]
+gps_tab_class = uic.loadUiType(cfclient.module_path +
+                               "/ui/tabs/gpsTab.ui")[0]
 
 
 class GpsTab(Tab, gps_tab_class):
@@ -81,7 +81,7 @@ class GpsTab(Tab, gps_tab_class):
 
         view.page().mainFrame().addToJavaScriptWindowObject("MainWindow", self)
         view.page().setLinkDelegationPolicy(QtWebKit.QWebPage.DelegateAllLinks)
-        view.load(QtCore.QUrl(sys.path[0] + "/cfclient/resources/map.html"))
+        view.load(QtCore.QUrl(cfclient.module_path + "/resources/map.html"))
         view.loadFinished.connect(self.onLoadFinished)
         view.linkClicked.connect(QtGui.QDesktopServices.openUrl)
 
@@ -104,7 +104,7 @@ class GpsTab(Tab, gps_tab_class):
         self._max_speed = 0.0
 
     def onLoadFinished(self):
-        with open(sys.path[0] + "/cfclient/resources/map.js", 'r') as f:
+        with open(cfclient.module_path + "/resources/map.js", 'r') as f:
             frame = self.view.page().mainFrame()
             frame.evaluateJavaScript(f.read())
 
diff --git a/src/cfclient/ui/tabs/LEDTab.py b/src/cfclient/ui/tabs/LEDTab.py
index 5751a278fbced482294b09c949e9f03cafd380d5..d8430b63f2f419c3d5b1ddb2e52d7e46a7c6aebf 100644
--- a/src/cfclient/ui/tabs/LEDTab.py
+++ b/src/cfclient/ui/tabs/LEDTab.py
@@ -31,12 +31,12 @@ Basic tab to be able to set (and test) colors in the LED-ring.
 """
 
 import logging
-import sys
 
 from PyQt4 import QtGui, uic
 from PyQt4.QtCore import pyqtSignal
 from PyQt4.QtGui import QColorDialog
 
+import cfclient
 from cfclient.ui.tab import Tab
 
 from cflib.crazyflie.mem import MemoryElement
@@ -46,8 +46,8 @@ __all__ = ['LEDTab']
 
 logger = logging.getLogger(__name__)
 
-led_tab_class = uic.loadUiType(sys.path[0] +
-                               "/cfclient/ui/tabs/ledTab.ui")[0]
+led_tab_class = uic.loadUiType(cfclient.module_path +
+                               "/ui/tabs/ledTab.ui")[0]
 
 
 class LEDTab(Tab, led_tab_class):
diff --git a/src/cfclient/ui/tabs/LogBlockDebugTab.py b/src/cfclient/ui/tabs/LogBlockDebugTab.py
index 17abd4ed81d248f1e3714ed7a7a2f9d2fb49aa24..3c518b101ef95cc9c61e5318bd4f00114da28fe0 100644
--- a/src/cfclient/ui/tabs/LogBlockDebugTab.py
+++ b/src/cfclient/ui/tabs/LogBlockDebugTab.py
@@ -31,18 +31,18 @@ to edit them.
 """
 
 import time
-import sys
 
 from PyQt4 import QtCore, QtGui, uic
 from PyQt4.QtCore import Qt, pyqtSlot, pyqtSignal, QThread, SIGNAL
 
+import cfclient
 from cfclient.ui.tab import Tab
 
 __author__ = 'Bitcraze AB'
 __all__ = ['LogBlockTab']
 
-logblock_tab_class = uic.loadUiType(sys.path[0] +
-                                    "/cfclient/ui/tabs/logBlockDebugTab.ui")[0]
+logblock_tab_class = uic.loadUiType(cfclient.module_path +
+                                    "/ui/tabs/logBlockDebugTab.ui")[0]
 
 
 class LogBlockDebugTab(Tab, logblock_tab_class):
diff --git a/src/cfclient/ui/tabs/LogBlockTab.py b/src/cfclient/ui/tabs/LogBlockTab.py
index 7f557cc8cb238f185015a383eceb780ad5abfbf7..536cdca1f9b900233d0b0b42bc977ab64af1a839 100644
--- a/src/cfclient/ui/tabs/LogBlockTab.py
+++ b/src/cfclient/ui/tabs/LogBlockTab.py
@@ -31,11 +31,10 @@ This tab shows all log blocks that are registered and can be used to start the
 logging and also to write the logging data to file.
 """
 
-import sys
-
 from PyQt4 import QtCore, QtGui, uic
 from PyQt4.QtCore import Qt, pyqtSlot, pyqtSignal, QThread, SIGNAL
 
+import cfclient
 from cfclient.ui.tab import Tab
 
 import logging
@@ -52,7 +51,7 @@ __author__ = 'Bitcraze AB'
 __all__ = ['LogBlockTab']
 
 logblock_tab_class = uic.loadUiType(
-    sys.path[0] + "/cfclient/ui/tabs/logBlockTab.ui")[0]
+    cfclient.module_path + "/ui/tabs/logBlockTab.ui")[0]
 
 logger = logging.getLogger(__name__)
 
diff --git a/src/cfclient/ui/tabs/LogTab.py b/src/cfclient/ui/tabs/LogTab.py
index 3fe977ccb030ef8089731736b6a7a46146d74540..9814f230b12573c65c524ac94f4c20be15e5bf85 100644
--- a/src/cfclient/ui/tabs/LogTab.py
+++ b/src/cfclient/ui/tabs/LogTab.py
@@ -26,9 +26,9 @@
 """
 Shows the Log TOC of available variables in the Crazyflie.
 """
-import sys
 import time
 
+import cfclient
 from cfclient.ui.tab import Tab
 from cflib.crazyflie import Crazyflie
 from PyQt4 import QtCore
@@ -43,8 +43,8 @@ from PyQt4.QtCore import SIGNAL
 __author__ = 'Bitcraze AB'
 __all__ = ['LogTab']
 
-param_tab_class = uic.loadUiType(sys.path[0] +
-                                 "/cfclient/ui/tabs/logTab.ui")[0]
+param_tab_class = uic.loadUiType(cfclient.module_path +
+                                 "/ui/tabs/logTab.ui")[0]
 
 
 class LogTab(Tab, param_tab_class):
diff --git a/src/cfclient/ui/tabs/ParamTab.py b/src/cfclient/ui/tabs/ParamTab.py
index 23e295e7eda48bff8c9ae07f597a61fcecfc03f7..51aa5f43fa1d5b39306b6f15f5f4830ae6081578 100644
--- a/src/cfclient/ui/tabs/ParamTab.py
+++ b/src/cfclient/ui/tabs/ParamTab.py
@@ -30,7 +30,6 @@ Shows all the parameters available in the Crazyflie and also gives the ability
 to edit them.
 """
 
-import sys
 import logging
 
 from PyQt4 import QtCore, QtGui, uic
@@ -40,13 +39,14 @@ from PyQt4.QtGui import QApplication, QStyledItemDelegate, QAbstractItemView, \
     QBrush, QColor
 from PyQt4.QtGui import QSortFilterProxyModel
 
+import cfclient
 from cfclient.ui.tab import Tab
 
 __author__ = 'Bitcraze AB'
 __all__ = ['ParamTab']
 
 param_tab_class = uic.loadUiType(
-    sys.path[0] + "/cfclient/ui/tabs/paramTab.ui")[0]
+    cfclient.module_path + "/ui/tabs/paramTab.ui")[0]
 
 logger = logging.getLogger(__name__)
 
diff --git a/src/cfclient/ui/tabs/PlotTab.py b/src/cfclient/ui/tabs/PlotTab.py
index 5af6fbd340f61c68ce89cf196cd14a323b97e58b..be9774a13f3bf1a4cf4a1294fb5aee0fa206e3a9 100644
--- a/src/cfclient/ui/tabs/PlotTab.py
+++ b/src/cfclient/ui/tabs/PlotTab.py
@@ -52,13 +52,15 @@ from PyQt4.QtGui import QApplication
 from PyQt4.QtGui import QMessageBox
 from PyQt4.QtGui import QStyledItemDelegate
 
+import cfclient
+
 __author__ = 'Bitcraze AB'
 __all__ = ['PlotTab']
 
 logger = logging.getLogger(__name__)
 
-plot_tab_class = uic.loadUiType(sys.path[0] +
-                                "/cfclient/ui/tabs/plotTab.ui")[0]
+plot_tab_class = uic.loadUiType(cfclient.module_path +
+                                "/ui/tabs/plotTab.ui")[0]
 
 
 class LogConfigModel(QAbstractItemModel):
diff --git a/src/cfclient/ui/toolboxes/ConsoleToolbox.py b/src/cfclient/ui/toolboxes/ConsoleToolbox.py
index ab2f5c19550bdeea979e14cc5d1020a5e8e2a730..e636576ec8fb6c0a94204f4d2c52b068f88a6663 100644
--- a/src/cfclient/ui/toolboxes/ConsoleToolbox.py
+++ b/src/cfclient/ui/toolboxes/ConsoleToolbox.py
@@ -26,8 +26,6 @@
 """
 A detachable toolbox for showing console printouts from the Crazyflie
 """
-import sys
-
 from PyQt4 import QtCore
 from PyQt4 import QtGui
 from PyQt4 import uic
@@ -35,11 +33,13 @@ from PyQt4.QtCore import pyqtSignal
 from PyQt4.QtCore import pyqtSlot
 from PyQt4.QtCore import Qt
 
+import cfclient
+
 __author__ = 'Bitcraze AB'
 __all__ = ['ConsoleToolbox']
 
 console_class = uic.loadUiType(
-    sys.path[0] + "/cfclient/ui/toolboxes/consoleToolbox.ui")[0]
+    cfclient.module_path + "/ui/toolboxes/consoleToolbox.ui")[0]
 
 
 class ConsoleToolbox(QtGui.QWidget, console_class):
diff --git a/src/cfclient/ui/toolboxes/CrtpSharkToolbox.py b/src/cfclient/ui/toolboxes/CrtpSharkToolbox.py
index 046f0130286b6bb306a9da4f0a8724d06f2cf6cb..7b1f1051aa0f7f298fecb2fb1222111ae5a7c418 100644
--- a/src/cfclient/ui/toolboxes/CrtpSharkToolbox.py
+++ b/src/cfclient/ui/toolboxes/CrtpSharkToolbox.py
@@ -28,7 +28,6 @@ Toolbox for showing packets that is sent via the communication link when
 debugging.
 """
 import os
-import sys
 from time import time
 
 from PyQt4 import QtCore
@@ -40,11 +39,13 @@ from PyQt4.QtCore import Qt
 from PyQt4.QtCore import QThread
 from PyQt4.QtCore import SIGNAL
 
+import cfclient
+
 __author__ = 'Bitcraze AB'
 __all__ = ['CrtpSharkBoolbox']
 
 param_tab_class = uic.loadUiType(
-    sys.path[0] + "/cfclient/ui/toolboxes/crtpSharkToolbox.ui")[0]
+    cfclient.module_path + "/ui/toolboxes/crtpSharkToolbox.ui")[0]
 
 
 class CrtpSharkToolbox(QtGui.QWidget, param_tab_class):
@@ -116,7 +117,7 @@ class CrtpSharkToolbox(QtGui.QWidget, param_tab_class):
         return Qt.RightDockWidgetArea
 
     def _save_data(self):
-        dir = os.path.join(sys.path[1], "logdata")
+        dir = os.path.join(cfclient.config_path, "logdata")
         fname = os.path.join(dir, "shark_data.csv")
         if not os.path.exists(dir):
             os.makedirs(dir)
diff --git a/src/cfclient/ui/toolboxes/DebugDriverToolbox.py b/src/cfclient/ui/toolboxes/DebugDriverToolbox.py
index 615c5b3f604404539556bf82a381ccfe211dd52e..335ad65a22b6fd1ee58eddadc7cf7a79fe8aa1f6 100644
--- a/src/cfclient/ui/toolboxes/DebugDriverToolbox.py
+++ b/src/cfclient/ui/toolboxes/DebugDriverToolbox.py
@@ -28,7 +28,6 @@ Toolbox used to interact with the DebugDriver using a designated port. It's
 intended to be used for debugging.
 """
 import struct
-import sys
 import time
 
 from cflib.crtp.crtpstack import CRTPPacket
@@ -42,12 +41,14 @@ from PyQt4.QtCore import Qt
 from PyQt4.QtCore import QThread
 from PyQt4.QtCore import SIGNAL
 
+import cfclient
+
 __author__ = 'Bitcraze AB'
 __all__ = ['DebugDriverToolbox']
 
 debugdriver_tab_class = uic.loadUiType(
-    sys.path[0] +
-    "/cfclient/ui/toolboxes/debugDriverToolbox.ui")[0]
+    cfclient.module_path +
+    "/ui/toolboxes/debugDriverToolbox.ui")[0]
 
 
 class DebugDriverToolbox(QtGui.QWidget, debugdriver_tab_class):
diff --git a/src/cfclient/ui/widgets/plotwidget.py b/src/cfclient/ui/widgets/plotwidget.py
index 7c3cadc58e0ba40b5ba02befd57dffec35c3e410..9c0a7688565cb0eb4887dd490c02acc500b4a3cf 100644
--- a/src/cfclient/ui/widgets/plotwidget.py
+++ b/src/cfclient/ui/widgets/plotwidget.py
@@ -41,8 +41,6 @@ import math
 
 import logging
 
-import sys
-
 from PyQt4 import Qt, QtCore, QtGui, uic
 from PyQt4.QtGui import QButtonGroup
 from PyQt4.QtCore import *
@@ -50,13 +48,15 @@ from PyQt4.QtGui import *
 from PyQt4.Qt import *
 from time import time
 
+import cfclient
+
 __author__ = 'Bitcraze AB'
 __all__ = ['PlotWidget']
 
 logger = logging.getLogger(__name__)
 
 (plot_widget_class, connect_widget_base_class) = (
-    uic.loadUiType(sys.path[0] + '/cfclient/ui/widgets/plotter.ui'))
+    uic.loadUiType(cfclient.module_path + '/ui/widgets/plotter.ui'))
 
 # Try the imports for PyQtGraph to see if it is installed
 try:
diff --git a/src/cfclient/utils/config.py b/src/cfclient/utils/config.py
index cbbe3ef2e460123e72e93a0f902e367a24095fa3..2bfe88af00037e1518de1f70f2ef051d97f13cd8 100644
--- a/src/cfclient/utils/config.py
+++ b/src/cfclient/utils/config.py
@@ -29,12 +29,12 @@
 """
 Gives access for reading and writing application configuration parameters
 """
-
-import sys
 import json
 import logging
 from .singleton import Singleton
 
+import cfclient
+
 __author__ = 'Bitcraze AB'
 __all__ = ['Config']
 
@@ -46,8 +46,8 @@ class Config(metaclass=Singleton):
 
     def __init__(self):
         """ Initializes the singleton and reads the config files """
-        self._dist_config = sys.path[0] + "/cfclient/configs/config.json"
-        self._config = sys.path[1] + "/config.json"
+        self._dist_config = cfclient.module_path + "/configs/config.json"
+        self._config = cfclient.config_path + "/config.json"
 
         [self._readonly, self._data] = self._read_distfile()
 
diff --git a/src/cfclient/utils/config_manager.py b/src/cfclient/utils/config_manager.py
index f92414054d8836ef3cd3ccb71c738e91945702ee..b535240501653b0805cdb74225fb06a5792a801b 100644
--- a/src/cfclient/utils/config_manager.py
+++ b/src/cfclient/utils/config_manager.py
@@ -41,6 +41,8 @@ import copy
 from .singleton import Singleton
 from cflib.utils.callbacks import Caller
 
+import cfclient
+
 __author__ = 'Bitcraze AB/Allyn Bauer'
 __all__ = ['ConfigManager']
 
@@ -50,7 +52,7 @@ logger = logging.getLogger(__name__)
 class ConfigManager(metaclass=Singleton):
     """ Singleton class for managing input processing """
     conf_needs_reload = Caller()
-    configs_dir = sys.path[1] + "/input"
+    configs_dir = cfclient.config_path + "/input"
 
     def __init__(self):
         """Initialize and create empty config list"""
diff --git a/src/cfclient/utils/input/__init__.py b/src/cfclient/utils/input/__init__.py
index ccb06c3262ddb3786dad9037d25dee95803da7ab..3024c4d9ad8c98428b08c3e7d881d714f5323e3c 100644
--- a/src/cfclient/utils/input/__init__.py
+++ b/src/cfclient/utils/input/__init__.py
@@ -38,8 +38,6 @@ Windows drivers.
 The input device's axes and buttons are mapped to software inputs using a
 configuration file.
 """
-
-import sys
 import os
 import re
 import glob
@@ -50,6 +48,7 @@ import shutil
 from . import inputreaders as readers
 from . import inputinterfaces as interfaces
 
+import cfclient
 from cfclient.utils.config import Config
 from cfclient.utils.config_manager import ConfigManager
 
@@ -144,7 +143,7 @@ class JoystickReader(object):
             os.makedirs(ConfigManager().configs_dir)
 
         for f in glob.glob(
-                sys.path[0] + "/cfclient/configs/input/[A-Za-z]*.json"):
+                cfclient.module_path + "/configs/input/[A-Za-z]*.json"):
             dest = os.path.join(ConfigManager().
                                 configs_dir, os.path.basename(f))
             if not os.path.isfile(dest):
diff --git a/src/cfclient/utils/logconfigreader.py b/src/cfclient/utils/logconfigreader.py
index 36d539266053db1c173bbaf5ac2d06c5676f32e3..c3a8403bc093fd7cd8c9940914c00bad81c2e4bb 100644
--- a/src/cfclient/utils/logconfigreader.py
+++ b/src/cfclient/utils/logconfigreader.py
@@ -40,15 +40,15 @@ import json
 import logging
 import os
 import shutil
-import sys
 
 from PyQt4 import QtCore, QtGui, uic
 from PyQt4.QtCore import pyqtSlot, pyqtSignal
 
+import cfclient
 from cflib.crazyflie.log import LogVariable, LogConfig
 
 __author__ = 'Bitcraze AB'
-__all__ = ['LogVariable', 'LogConfigReader', 'LogConfigRemoveThis']
+__all__ = ['LogVariable', 'LogConfigReader']
 
 logger = logging.getLogger(__name__)
 
@@ -59,24 +59,25 @@ class LogConfigReader():
     def __init__(self, crazyflie):
         self.dsList = []
         # Check if user config exists, otherwise copy files
-        if (not os.path.exists(sys.path[1] + "/log")):
+        if (not os.path.exists(cfclient.config_path + "/log")):
             logger.info("No user config found, copying dist files")
-            os.makedirs(sys.path[1] + "/log")
+            os.makedirs(cfclient.config_path + "/log")
             for f in glob.glob(
-                    sys.path[0] + "/cfclient/configs/log/[A-Za-z]*.json"):
-                shutil.copy2(f, sys.path[1] + "/log")
+                    cfclient.module_path + "/configs/log/[A-Za-z]*.json"):
+                shutil.copy2(f, cfclient.config_path + "/log")
         self._cf = crazyflie
         self._cf.connected.add_callback(self._connected)
 
     def _read_config_files(self):
         """Read and parse log configurations"""
         configsfound = [os.path.basename(f) for f in
-                        glob.glob(sys.path[1] + "/log/[A-Za-z_-]*.json")]
+                        glob.glob(cfclient.config_path +
+                                  "/log/[A-Za-z_-]*.json")]
         new_dsList = []
         for conf in configsfound:
             try:
                 logger.info("Parsing [%s]", conf)
-                json_data = open(sys.path[1] + "/log/%s" % conf)
+                json_data = open(cfclient.config_path + "/log/%s" % conf)
                 self.data = json.load(json_data)
                 infoNode = self.data["logconfig"]["logblock"]
 
@@ -115,7 +116,7 @@ class LogConfigReader():
 
     def saveLogConfigFile(self, logconfig):
         """Save a log configuration to file"""
-        filename = sys.path[1] + "/log/" + logconfig.name + ".json"
+        filename = cfclient.config_path + "/log/" + logconfig.name + ".json"
         logger.info("Saving config for [%s]", filename)
 
         # Build tree for JSON
diff --git a/src/cfclient/utils/logdatawriter.py b/src/cfclient/utils/logdatawriter.py
index 3a7d365d30c2cedf313131c5ffb1cdb022d8bf7b..924934fc8967289981c6af6e9822541743e38614 100644
--- a/src/cfclient/utils/logdatawriter.py
+++ b/src/cfclient/utils/logdatawriter.py
@@ -55,7 +55,7 @@ class LogWriter():
         self._dir = directory
         self._connected_ts = connected_ts
 
-        self._dir = os.path.join(sys.path[1], "logdata",
+        self._dir = os.path.join(cfclient.config_path, "logdata",
                                  connected_ts.strftime("%Y%m%dT%H-%M-%S"))
         self._file = None
         self._header_written = False
diff --git a/src/cflib/cflib/__init__.py b/src/cflib/cflib/__init__.py
deleted file mode 100644
index 536acc1111695aade66f938f03689f8a10d71d4c..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/__init__.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-The Crazyflie Micro Quadcopter library API used to communicate with the
-Crazyflie Micro Quadcopter via a communication link.
-
-The API takes care of scanning, opening and closing the communication link
-as well as sending/receiving data from the Crazyflie.
-
-A link is described using an URI of the following format:
-    <interface>://<interface defined data>.
-See each link for the data that can be included in the URI for that interface.
-
-The two main uses-cases are scanning for Crazyflies available on a
-communication link and opening a communication link to a Crazyflie.
-
-Example of scanning for available Crazyflies on all communication links:
-cflib.crtp.init_drivers()
-available = cflib.crtp.scan_interfaces()
-for i in available:
-    print "Found Crazyflie on URI [%s] with comment [%s]"
-            % (available[0], available[1])
-
-Example of connecting to a Crazyflie with know URI (radio dongle 0 and
-radio channel 125):
-cf = Crazyflie()
-cf.open_link("radio://0/125")
-...
-cf.close_link()
-"""
diff --git a/src/cflib/cflib/bootloader/__init__.py b/src/cflib/cflib/bootloader/__init__.py
deleted file mode 100644
index 4e6bec5ca53592c658692e144dd7035a6e7c9c98..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/bootloader/__init__.py
+++ /dev/null
@@ -1,388 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-Bootloading utilities for the Crazyflie.
-"""
-
-from cflib.utils.callbacks import Caller
-from .cloader import Cloader
-from .boottypes import BootVersion, TargetTypes, Target
-import zipfile
-import json
-import sys
-import time
-import logging
-
-logger = logging.getLogger(__name__)
-
-__author__ = 'Bitcraze AB'
-__all__ = ['Bootloader']
-
-
-class Bootloader:
-    """Bootloader utility for the Crazyflie"""
-
-    def __init__(self, clink=None):
-        """Init the communication class by starting to communicate with the
-        link given. clink is the link address used after resetting to the
-        bootloader.
-
-        The device is actually considered in firmware mode.
-        """
-        self.clink = clink
-        self.in_loader = False
-
-        self.page_size = 0
-        self.buffer_pages = 0
-        self.flash_pages = 0
-        self.start_page = 0
-        self.cpuid = "N/A"
-        self.error_code = 0
-        self.protocol_version = 0
-
-        # Outgoing callbacks for progress
-        # int
-        self.progress_cb = None
-        # msg
-        self.error_cb = None
-        # bool
-        self.in_bootloader_cb = None
-        # Target
-        self.dev_info_cb = None
-
-        # self.dev_info_cb.add_callback(self._dev_info)
-        # self.in_bootloader_cb.add_callback(self._bootloader_info)
-
-        self._boot_plat = None
-
-        self._cload = Cloader(clink,
-                              info_cb=self.dev_info_cb,
-                              in_boot_cb=self.in_bootloader_cb)
-
-    def start_bootloader(self, warm_boot=False):
-        if warm_boot:
-            self._cload.open_bootloader_uri(self.clink)
-            started = self._cload.reset_to_bootloader(TargetTypes.NRF51)
-            if started:
-                started = self._cload.check_link_and_get_info()
-        else:
-            uri = self._cload.scan_for_bootloader()
-
-            # Workaround for libusb on Windows (open/close too fast)
-            time.sleep(1)
-
-            if uri:
-                self._cload.open_bootloader_uri(uri)
-                started = self._cload.check_link_and_get_info()
-            else:
-                started = False
-
-        if started:
-            self.protocol_version = self._cload.protocol_version
-
-            if (self.protocol_version == BootVersion.CF1_PROTO_VER_0 or
-                    self.protocol_version == BootVersion.CF1_PROTO_VER_1):
-                # Nothing more to do
-                pass
-            elif self.protocol_version == BootVersion.CF2_PROTO_VER:
-                self._cload.request_info_update(TargetTypes.NRF51)
-            else:
-                print("Bootloader protocol 0x{:X} not "
-                      "supported!".self.protocol_version)
-
-        return started
-
-    def get_target(self, target_id):
-        return self._cload.request_info_update(target_id)
-
-    def read_cf1_config(self):
-        """Read a flash page from the specified target"""
-        target = self._cload.targets[0xFF]
-        config_page = target.flash_pages - 1
-
-        return self._cload.read_flash(addr=0xFF, page=config_page)
-
-    def write_cf1_config(self, data):
-        target = self._cload.targets[0xFF]
-        config_page = target.flash_pages - 1
-
-        to_flash = {"target": target, "data": data, "type": "CF1 config",
-                    "start_page": config_page}
-
-        self._internal_flash(target=to_flash)
-
-    def flash(self, filename, targets):
-        for target in targets:
-            if TargetTypes.from_string(target) not in self._cload.targets:
-                print("Target {} not found by bootloader".format(target))
-                return False
-
-        files_to_flash = ()
-        if zipfile.is_zipfile(filename):
-            # Read the manifest (don't forget to check so there is one!)
-            try:
-                zf = zipfile.ZipFile(filename)
-                js = zf.read("manifest.json").decode("UTF-8")
-                j = json.loads(js)
-                files = j["files"]
-                platform_id = self._get_platform_id()
-                files_for_platform = self._filter_platform(files, platform_id)
-                if len(targets) == 0:
-                    targets = self._extract_targets_from_manifest_files(
-                        files_for_platform)
-
-                zip_targets = self._extract_zip_targets(files_for_platform)
-            except KeyError as e:
-                print(e)
-                print("No manifest.json in {}".format(filename))
-                return
-
-            try:
-                # Match and create targets
-                for target in targets:
-                    t = targets[target]
-                    for type in t:
-                        file_to_flash = {}
-                        current_target = "{}-{}".format(target, type)
-                        file_to_flash["type"] = type
-                        # Read the data, if this fails we bail
-                        file_to_flash["target"] = self._cload.targets[
-                            TargetTypes.from_string(target)]
-                        file_to_flash["data"] = zf.read(
-                            zip_targets[target][type]["filename"])
-                        file_to_flash["start_page"] = file_to_flash[
-                            "target"].start_page
-                        files_to_flash += (file_to_flash,)
-            except KeyError as e:
-                print("Could not find a file for {} in {}".format(
-                    current_target, filename))
-                return False
-
-        else:
-            if len(targets) != 1:
-                print("Not an archive, must supply one target to flash")
-            else:
-                file_to_flash = {}
-                file_to_flash["type"] = "binary"
-                f = open(filename, 'rb')
-                for t in targets:
-                    file_to_flash["target"] = self._cload.targets[
-                        TargetTypes.from_string(t)]
-                    file_to_flash["type"] = targets[t][0]
-                    file_to_flash["start_page"] = file_to_flash[
-                        "target"].start_page
-                file_to_flash["data"] = f.read()
-                f.close()
-                files_to_flash += (file_to_flash,)
-
-        if not self.progress_cb:
-            print("")
-
-        file_counter = 0
-        for target in files_to_flash:
-            file_counter += 1
-            self._internal_flash(target, file_counter, len(files_to_flash))
-
-    def _filter_platform(self, files, platform_id):
-        result = {}
-        for file in files:
-            file_info = files[file]
-            file_platform = file_info["platform"]
-            if platform_id == file_platform:
-                result[file] = file_info
-        return result
-
-    def _extract_zip_targets(self, files):
-        zip_targets = {}
-        for file in files:
-            file_name = file
-            file_info = files[file]
-            file_target = file_info["target"]
-            file_type = file_info["type"]
-            if file_target not in zip_targets:
-                zip_targets[file_target] = {}
-            zip_targets[file_target][file_type] = {
-                "filename": file_name}
-        return zip_targets
-
-    def _extract_targets_from_manifest_files(self, files):
-        targets = {}
-        for file in files:
-            file_info = files[file]
-            file_target = file_info["target"]
-            file_type = file_info["type"]
-            if file_target in targets:
-                targets[file_target] += (file_type,)
-            else:
-                targets[file_target] = (file_type,)
-
-        return targets
-
-    def reset_to_firmware(self):
-        if self._cload.protocol_version == BootVersion.CF2_PROTO_VER:
-            self._cload.reset_to_firmware(TargetTypes.NRF51)
-        else:
-            self._cload.reset_to_firmware(TargetTypes.STM32)
-
-    def close(self):
-        if self._cload:
-            self._cload.close()
-
-    def _internal_flash(self, target, current_file_number=1, total_files=1):
-
-        image = target["data"]
-        t_data = target["target"]
-
-        start_page = target["start_page"]
-
-        # If used from a UI we need some extra things for reporting progress
-        factor = (100.0 * t_data.page_size) / len(image)
-        progress = 0
-
-        if self.progress_cb:
-            self.progress_cb(
-                "({}/{}) Starting...".format(current_file_number, total_files),
-                int(progress))
-        else:
-            sys.stdout.write(
-                "Flashing {} of {} to {} ({}): ".format(
-                    current_file_number, total_files,
-                    TargetTypes.to_string(t_data.id), target["type"]))
-            sys.stdout.flush()
-
-        if len(image) > ((t_data.flash_pages - start_page) *
-                         t_data.page_size):
-            if self.progress_cb:
-                self.progress_cb(
-                    "Error: Not enough space to flash the image file.",
-                    int(progress))
-            else:
-                print("Error: Not enough space to flash the image file.")
-            raise Exception()
-
-        if not self.progress_cb:
-            logger.info(("%d bytes (%d pages) " % (
-                (len(image) - 1), int(len(image) / t_data.page_size) + 1)))
-            sys.stdout.write(("%d bytes (%d pages) " % (
-                (len(image) - 1), int(len(image) / t_data.page_size) + 1)))
-            sys.stdout.flush()
-
-        # For each page
-        ctr = 0  # Buffer counter
-        for i in range(0, int((len(image) - 1) / t_data.page_size) + 1):
-            # Load the buffer
-            if ((i + 1) * t_data.page_size) > len(image):
-                self._cload.upload_buffer(
-                    t_data.addr, ctr, 0, image[i * t_data.page_size:])
-            else:
-                self._cload.upload_buffer(
-                    t_data.addr, ctr, 0,
-                    image[i * t_data.page_size: (i + 1) * t_data.page_size])
-
-            ctr += 1
-
-            if self.progress_cb:
-                progress += factor
-                self.progress_cb("({}/{}) Uploading buffer to {}...".format(
-                    current_file_number,
-                    total_files,
-                    TargetTypes.to_string(t_data.id)),
-
-                    int(progress))
-            else:
-                sys.stdout.write(".")
-                sys.stdout.flush()
-
-            # Flash when the complete buffers are full
-            if ctr >= t_data.buffer_pages:
-                if self.progress_cb:
-                    self.progress_cb("({}/{}) Writing buffer to {}...".format(
-                        current_file_number,
-                        total_files,
-                        TargetTypes.to_string(t_data.id)),
-
-                        int(progress))
-                else:
-                    sys.stdout.write("%d" % ctr)
-                    sys.stdout.flush()
-                if not self._cload.write_flash(t_data.addr, 0,
-                                               start_page + i - (ctr - 1),
-                                               ctr):
-                    if self.progress_cb:
-                        self.progress_cb(
-                            "Error during flash operation (code %d)".format(
-                                self._cload.error_code),
-                            int(progress))
-                    else:
-                        print("\nError during flash operation (code %d). "
-                              "Maybe wrong radio link?" %
-                              self._cload.error_code)
-                    raise Exception()
-
-                ctr = 0
-
-        if ctr > 0:
-            if self.progress_cb:
-                self.progress_cb("({}/{}) Writing buffer to {}...".format(
-                    current_file_number,
-                    total_files,
-                    TargetTypes.to_string(t_data.id)),
-                    int(progress))
-            else:
-                sys.stdout.write("%d" % ctr)
-                sys.stdout.flush()
-            if not self._cload.write_flash(
-                    t_data.addr, 0,
-                    (start_page + (int((len(image) - 1) / t_data.page_size)) -
-                     (ctr - 1)), ctr):
-                if self.progress_cb:
-                    self.progress_cb(
-                        "Error during flash operation (code %d)".format(
-                            self._cload.error_code),
-                        int(progress))
-                else:
-                    print("\nError during flash operation (code %d). Maybe"
-                          " wrong radio link?" % self._cload.error_code)
-                raise Exception()
-
-        if self.progress_cb:
-            self.progress_cb(
-                "({}/{}) Flashing done!".format(current_file_number,
-                                                total_files),
-                int(100))
-        else:
-            print("")
-
-    def _get_platform_id(self):
-        """Get platform identifier used in the zip manifest for curr copter"""
-        identifier = "cf1"
-        if (BootVersion.is_cf2(self.protocol_version)):
-            identifier = "cf2"
-
-        return identifier
diff --git a/src/cflib/cflib/bootloader/boottypes.py b/src/cflib/cflib/bootloader/boottypes.py
deleted file mode 100644
index c762bb70e6db38230636137fa7eae2e6fc08ae1c..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/bootloader/boottypes.py
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-Bootloading utilities for the Crazyflie.
-"""
-
-__author__ = 'Bitcraze AB'
-__all__ = ['BootVersion', 'TargetTypes', 'Target']
-
-
-class BootVersion:
-    CF1_PROTO_VER_0 = 0x00
-    CF1_PROTO_VER_1 = 0x01
-    CF2_PROTO_VER = 0x10
-
-    @staticmethod
-    def to_ver_string(ver):
-        if (ver == BootVersion.CF1_PROTO_VER_0 or ver == BootVersion.
-                CF1_PROTO_VER_1):
-            return "Crazyflie Nano Quadcopter (1.0)"
-        if ver == BootVersion.CF2_PROTO_VER:
-            return "Crazyflie 2.0"
-        return "Unknown"
-
-    @staticmethod
-    def is_cf2(ver):
-        return ver == BootVersion.CF2_PROTO_VER
-
-
-class TargetTypes:
-    STM32 = 0xFF
-    NRF51 = 0xFE
-
-    @staticmethod
-    def to_string(target):
-        if target == TargetTypes.STM32:
-            return "stm32"
-        if target == TargetTypes.NRF51:
-            return "nrf51"
-        return "Unknown"
-
-    @staticmethod
-    def from_string(name):
-        if name == "stm32":
-            return TargetTypes.STM32
-        if name == "nrf51":
-            return TargetTypes.NRF51
-        return 0
-
-
-class Target:
-
-    def __init__(self, id):
-        self.id = id
-        self.protocol_version = 0xFF
-        self.page_size = 0
-        self.buffer_pages = 0
-        self.flash_pages = 0
-        self.start_page = 0
-        self.cpuid = ""
-        self.data = None
-
-    def __str__(self):
-        ret = ""
-        ret += "Target info: {} (0x{:X})\n".format(
-            TargetTypes.to_string(self.id), self.id)
-        ret += "Flash pages: %d | Page size: %d | Buffer pages: %d |" \
-               " Start page: %d\n" % (self.flash_pages, self.page_size,
-                                      self.buffer_pages, self.start_page)
-        ret += "%d KBytes of flash available for firmware image." % (
-            (self.flash_pages - self.start_page) * self.page_size / 1024)
-        return ret
diff --git a/src/cflib/cflib/bootloader/cloader.py b/src/cflib/cflib/bootloader/cloader.py
deleted file mode 100644
index 1bffeb15bfd1b741f8960920deb587550ec9ff73..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/bootloader/cloader.py
+++ /dev/null
@@ -1,423 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-Crazyflie radio bootloader for flashing firmware.
-"""
-
-import logging
-
-import time
-import struct
-import math
-import random
-
-import cflib.crtp
-from cflib.crtp.crtpstack import CRTPPacket, CRTPPort
-
-from .boottypes import TargetTypes, Target
-
-__author__ = 'Bitcraze AB'
-__all__ = ['Cloader']
-
-logger = logging.getLogger(__name__)
-
-
-class Cloader:
-    """Bootloader utility for the Crazyflie"""
-
-    def __init__(self, link, info_cb=None, in_boot_cb=None):
-        """Init the communication class by starting to communicate with the
-        link given. clink is the link address used after resetting to the
-        bootloader.
-
-        The device is actually considered in firmware mode.
-        """
-        self.link = None
-        self.uri = link
-        self.in_loader = False
-
-        self.page_size = 0
-        self.buffer_pages = 0
-        self.flash_pages = 0
-        self.start_page = 0
-        self.cpuid = "N/A"
-        self.error_code = 0
-        self.protocol_version = 0xFF
-
-        self._info_cb = info_cb
-        self._in_boot_cb = in_boot_cb
-
-        self.targets = {}
-        self.mapping = None
-        self._available_boot_uri = ("radio://0/110/2M", "radio://0/0/2M")
-
-    def close(self):
-        """ Close the link """
-        if self.link:
-            self.link.close()
-
-    def scan_for_bootloader(self):
-        link = cflib.crtp.get_link_driver("radio://0")
-        ts = time.time()
-        res = ()
-        while len(res) == 0 and (time.time() - ts) < 10:
-            res = link.scan_selected(self._available_boot_uri)
-
-        link.close()
-
-        if len(res) > 0:
-            return res[0]
-        return None
-
-    def reset_to_bootloader(self, target_id):
-        retry_counter = 5
-        pk = CRTPPacket()
-        pk.set_header(0xFF, 0xFF)
-        pk.data = (target_id, 0xFF)
-        self.link.send_packet(pk)
-
-        pk = self.link.receive_packet(1)
-
-        while ((not pk or pk.header != 0xFF or
-                struct.unpack("<BB", pk.data[0:2]) != (target_id, 0xFF)
-                ) and retry_counter >= 0):
-            pk = self.link.receive_packet(1)
-            retry_counter -= 1
-
-        if pk:
-            new_address = (0xb1,) + struct.unpack("<BBBB", pk.data[2:6][::-1])
-
-            pk = CRTPPacket()
-            pk.set_header(0xFF, 0xFF)
-            pk.data = (target_id, 0xF0, 0x00)
-            self.link.send_packet(pk)
-
-            addr = int(struct.pack("B" * 5, *new_address).encode('hex'), 16)
-
-            time.sleep(0.2)
-            self.link.close()
-            time.sleep(0.2)
-            self.link = cflib.crtp.get_link_driver(
-                "radio://0/0/2M/{}".format(addr))
-
-            return True
-        else:
-            return False
-
-    def reset_to_bootloader1(self, cpu_id):
-        """ Reset to the bootloader
-        The parameter cpuid shall correspond to the device to reset.
-
-        Return true if the reset has been done and the contact with the
-        bootloader is established.
-        """
-        # Send an echo request and wait for the answer
-        # Mainly aim to bypass a bug of the crazyflie firmware that prevents
-        # reset before normal CRTP communication
-        pk = CRTPPacket()
-        pk.port = CRTPPort.LINKCTRL
-        pk.data = (1, 2, 3) + cpu_id
-        self.link.send_packet(pk)
-
-        pk = None
-        while True:
-            pk = self.link.receive_packet(2)
-            if not pk:
-                return False
-
-            if pk.port == CRTPPort.LINKCTRL:
-                break
-
-        # Send the reset to bootloader request
-        pk = CRTPPacket()
-        pk.set_header(0xFF, 0xFF)
-        pk.data = (0xFF, 0xFE) + cpu_id
-        self.link.send_packet(pk)
-
-        # Wait to ack the reset ...
-        pk = None
-        while True:
-            pk = self.link.receive_packet(2)
-            if not pk:
-                return False
-
-            if pk.port == 0xFF and tuple(pk.data) == (0xFF, 0xFE) + cpu_id:
-                pk.data = (0xFF, 0xF0) + cpu_id
-                self.link.send_packet(pk)
-                break
-
-        time.sleep(0.1)
-        self.link.close()
-        self.link = cflib.crtp.get_link_driver(self.clink_address)
-        # time.sleep(0.1)
-
-        return self._update_info()
-
-    def reset_to_firmware(self, target_id):
-        """ Reset to firmware
-        The parameter cpuid shall correspond to the device to reset.
-
-        Return true if the reset has been done
-        """
-        # The fake CPU ID is legacy from the Crazyflie 1.0
-        # In order to reset the CPU id had to be sent, but this
-        # was removed before launching it. But the length check is
-        # still in the bootloader. So to work around this bug so
-        # some extra data needs to be sent.
-        fake_cpu_id = (1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12)
-        # Send the reset to bootloader request
-        pk = CRTPPacket()
-        pk.set_header(0xFF, 0xFF)
-        pk.data = (target_id, 0xFF) + fake_cpu_id
-        self.link.send_packet(pk)
-
-        # Wait to ack the reset ...
-        pk = None
-        while True:
-            pk = self.link.receive_packet(2)
-            if not pk:
-                return False
-
-            if (pk.header == 0xFF and struct.unpack(
-                    "B" * len(pk.data), pk.data)[:2] == (target_id, 0xFF)):
-                # Difference in CF1 and CF2 (CPU ID)
-                if target_id == 0xFE:
-                    pk.data = (target_id, 0xF0, 0x01)
-                else:
-                    pk.data = (target_id, 0xF0) + fake_cpu_id
-                self.link.send_packet(pk)
-                break
-
-        time.sleep(0.1)
-
-    def open_bootloader_uri(self, uri=None):
-        if self.link:
-            self.link.close()
-        if uri:
-            self.link = cflib.crtp.get_link_driver(uri)
-        else:
-            self.link = cflib.crtp.get_link_driver(self.clink_address)
-
-    def check_link_and_get_info(self, target_id=0xFF):
-        """Try to get a connection with the bootloader by requesting info
-        5 times. This let roughly 10 seconds to boot the copter ..."""
-        for _ in range(0, 5):
-            if self._update_info(target_id):
-                if self._in_boot_cb:
-                    self._in_boot_cb.call(True, self.targets[
-                        target_id].protocol_version)
-                if self._info_cb:
-                    self._info_cb.call(self.targets[target_id])
-                if self.protocol_version != 1:
-                    return True
-                # Set radio link to a random address
-                addr = [0xbc] + [random.randint(0, 255) for x in range(4)]
-                return self._set_address(addr)
-        return False
-
-    def _set_address(self, new_address):
-        """ Change copter radio address.
-            This function works only with crazyradio CRTP link.
-        """
-
-        logging.debug("Setting bootloader radio address to"
-                      " {}".format(new_address))
-
-        if len(new_address) != 5:
-            raise Exception("Radio address should be 5 bytes long")
-
-        self.link.pause()
-
-        for _ in range(10):
-            logging.debug("Trying to set new radio address")
-            self.link.cradio.set_address((0xE7,) * 5)
-            pkdata = (0xFF, 0xFF, 0x11) + tuple(new_address)
-            self.link.cradio.send_packet(pkdata)
-            self.link.cradio.set_address(tuple(new_address))
-            if self.link.cradio.send_packet((0xff,)).ack:
-                logging.info("Bootloader set to radio address"
-                             " {}".format(new_address))
-                self.link.restart()
-                return True
-
-        self.link.restart()
-        return False
-
-    def request_info_update(self, target_id):
-        if target_id not in self.targets:
-            self._update_info(target_id)
-        if self._info_cb:
-            self._info_cb.call(self.targets[target_id])
-        return self.targets[target_id]
-
-    def _update_info(self, target_id):
-        """ Call the command getInfo and fill up the information received in
-        the fields of the object
-        """
-
-        # Call getInfo ...
-        pk = CRTPPacket()
-        pk.set_header(0xFF, 0xFF)
-        pk.data = (target_id, 0x10)
-        self.link.send_packet(pk)
-
-        # Wait for the answer
-        pk = self.link.receive_packet(2)
-
-        if (pk and pk.header == 0xFF and struct.unpack("<BB", pk.data[0:2]) ==
-                (target_id, 0x10)):
-            tab = struct.unpack("BBHHHH", pk.data[0:10])
-            cpuid = struct.unpack("B" * 12, pk.data[10:22])
-            if target_id not in self.targets:
-                self.targets[target_id] = Target(target_id)
-            self.targets[target_id].addr = target_id
-            if len(pk.data) > 22:
-                self.targets[target_id].protocol_version = pk.datat[22]
-                self.protocol_version = pk.datat[22]
-            self.targets[target_id].page_size = tab[2]
-            self.targets[target_id].buffer_pages = tab[3]
-            self.targets[target_id].flash_pages = tab[4]
-            self.targets[target_id].start_page = tab[5]
-            self.targets[target_id].cpuid = "%02X" % cpuid[0]
-            for i in cpuid[1:]:
-                self.targets[target_id].cpuid += ":%02X" % i
-
-            if (self.protocol_version == 0x10 and
-                    target_id == TargetTypes.STM32):
-                self._update_mapping(target_id)
-
-            return True
-
-        return False
-
-    def _update_mapping(self, target_id):
-        pk = CRTPPacket()
-        pk.set_header(0xff, 0xff)
-        pk.data = (target_id, 0x12)
-        self.link.send_packet(pk)
-
-        pk = self.link.receive_packet(2)
-
-        if (pk and pk.header == 0xFF and struct.unpack("<BB", pk.data[0:2]) ==
-                (target_id, 0x12)):
-            m = pk.datat[2:]
-
-            if (len(m) % 2) != 0:
-                raise Exception("Malformed flash mapping packet")
-
-            self.mapping = []
-            page = 0
-            for i in range(int(len(m) / 2)):
-                for j in range(m[2 * i]):
-                    self.mapping.append(page)
-                    page += m[(2 * i) + 1]
-
-    def upload_buffer(self, target_id, page, address, buff):
-        """Upload data into a buffer on the Crazyflie"""
-        # print len(buff)
-        count = 0
-        pk = CRTPPacket()
-        pk.set_header(0xFF, 0xFF)
-        pk.data = struct.pack("=BBHH", target_id, 0x14, page, address)
-
-        for i in range(0, len(buff)):
-            pk.data.append(buff[i])
-
-            count += 1
-
-            if count > 24:
-                self.link.send_packet(pk)
-                count = 0
-                pk = CRTPPacket()
-                pk.set_header(0xFF, 0xFF)
-                pk.data = struct.pack("=BBHH", target_id, 0x14, page,
-                                      i + address + 1)
-
-        self.link.send_packet(pk)
-
-    def read_flash(self, addr=0xFF, page=0x00):
-        """Read back a flash page from the Crazyflie and return it"""
-        buff = bytearray()
-
-        page_size = self.targets[addr].page_size
-
-        for i in range(0, int(math.ceil(page_size / 25.0))):
-            pk = None
-            retry_counter = 5
-            while ((not pk or pk.header != 0xFF or
-                    struct.unpack("<BB", pk.data[0:2]) != (addr, 0x1C)) and
-                    retry_counter >= 0):
-                pk = CRTPPacket()
-                pk.set_header(0xFF, 0xFF)
-                pk.data = struct.pack("<BBHH", addr, 0x1C, page, (i * 25))
-                self.link.send_packet(pk)
-
-                pk = self.link.receive_packet(1)
-                retry_counter -= 1
-            if (retry_counter < 0):
-                return None
-            else:
-                buff += pk.data[6:]
-
-        # For some reason we get one byte extra here...
-        return buff[0:page_size]
-
-    def write_flash(self, addr, page_buffer, target_page, page_count):
-        """Initiate flashing of data in the buffer to flash."""
-        # print "Write page", flashPage
-        # print "Writing page [%d] and [%d] forward" % (flashPage, nPage)
-        pk = None
-        retry_counter = 5
-        # print "Flasing to 0x{:X}".format(addr)
-        while ((not pk or pk.header != 0xFF or
-                struct.unpack("<BB", pk.data[0:2]) != (addr, 0x18)) and
-               retry_counter >= 0):
-            pk = CRTPPacket()
-            pk.set_header(0xFF, 0xFF)
-            pk.data = struct.pack("<BBHHH", addr, 0x18, page_buffer,
-                                  target_page, page_count)
-            self.link.send_packet(pk)
-            pk = self.link.receive_packet(1)
-            retry_counter -= 1
-
-        if retry_counter < 0:
-            self.error_code = -1
-            return False
-
-        self.error_code = pk.data[3]
-
-        return pk.data[2] == 1
-
-    def decode_cpu_id(self, cpuid):
-        """Decode the CPU id into a string"""
-        ret = ()
-        for i in cpuid.split(':'):
-            ret += (eval("0x" + i),)
-
-        return ret
diff --git a/src/cflib/cflib/cache/27A2C4BA.json b/src/cflib/cflib/cache/27A2C4BA.json
deleted file mode 100644
index 50c15e65834d9f0795439a4e3196dff1f6ddcb37..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/cache/27A2C4BA.json
+++ /dev/null
@@ -1,257 +0,0 @@
-{
-  "sensorfusion6": {
-    "ki": {
-      "ident": 24,
-      "group": "sensorfusion6",
-      "name": "ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "kp": {
-      "ident": 23,
-      "group": "sensorfusion6",
-      "name": "kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "cpu": {
-    "flash": {
-      "ident": 1,
-      "group": "cpu",
-      "name": "flash",
-      "pytype": "<H",
-      "__class__": "ParamTocElement",
-      "ctype": "uint16_t",
-      "access": 0
-    },
-    "id2": {
-      "ident": 4,
-      "group": "cpu",
-      "name": "id2",
-      "pytype": "<L",
-      "__class__": "ParamTocElement",
-      "ctype": "uint32_t",
-      "access": 0
-    },
-    "id0": {
-      "ident": 2,
-      "group": "cpu",
-      "name": "id0",
-      "pytype": "<L",
-      "__class__": "ParamTocElement",
-      "ctype": "uint32_t",
-      "access": 0
-    },
-    "id1": {
-      "ident": 3,
-      "group": "cpu",
-      "name": "id1",
-      "pytype": "<L",
-      "__class__": "ParamTocElement",
-      "ctype": "uint32_t",
-      "access": 0
-    }
-  },
-  "version": {
-    "revision0": {
-      "ident": 25,
-      "group": "version",
-      "name": "revision0",
-      "pytype": "<L",
-      "__class__": "ParamTocElement",
-      "ctype": "uint32_t",
-      "access": 0
-    },
-    "revision1": {
-      "ident": 26,
-      "group": "version",
-      "name": "revision1",
-      "pytype": "<H",
-      "__class__": "ParamTocElement",
-      "ctype": "uint16_t",
-      "access": 0
-    }
-  },
-  "pid_rate": {
-    "yaw_kp": {
-      "ident": 11,
-      "group": "pid_rate",
-      "name": "yaw_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_kd": {
-      "ident": 7,
-      "group": "pid_rate",
-      "name": "roll_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_kp": {
-      "ident": 8,
-      "group": "pid_rate",
-      "name": "pitch_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_ki": {
-      "ident": 6,
-      "group": "pid_rate",
-      "name": "roll_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_ki": {
-      "ident": 9,
-      "group": "pid_rate",
-      "name": "pitch_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_kp": {
-      "ident": 5,
-      "group": "pid_rate",
-      "name": "roll_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "yaw_kd": {
-      "ident": 13,
-      "group": "pid_rate",
-      "name": "yaw_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "yaw_ki": {
-      "ident": 12,
-      "group": "pid_rate",
-      "name": "yaw_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_kd": {
-      "ident": 10,
-      "group": "pid_rate",
-      "name": "pitch_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "pid_attitude": {
-    "yaw_kp": {
-      "ident": 20,
-      "group": "pid_attitude",
-      "name": "yaw_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_kd": {
-      "ident": 16,
-      "group": "pid_attitude",
-      "name": "roll_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_kp": {
-      "ident": 17,
-      "group": "pid_attitude",
-      "name": "pitch_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_ki": {
-      "ident": 15,
-      "group": "pid_attitude",
-      "name": "roll_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_ki": {
-      "ident": 18,
-      "group": "pid_attitude",
-      "name": "pitch_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_kp": {
-      "ident": 14,
-      "group": "pid_attitude",
-      "name": "roll_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "yaw_kd": {
-      "ident": 22,
-      "group": "pid_attitude",
-      "name": "yaw_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "yaw_ki": {
-      "ident": 21,
-      "group": "pid_attitude",
-      "name": "yaw_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_kd": {
-      "ident": 19,
-      "group": "pid_attitude",
-      "name": "pitch_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "imu_acc_lpf": {
-    "factor": {
-      "ident": 0,
-      "group": "imu_acc_lpf",
-      "name": "factor",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 0
-    }
-  }
-}
diff --git a/src/cflib/cflib/cache/81204C68.json b/src/cflib/cflib/cache/81204C68.json
deleted file mode 100644
index 9394972b2b2dacc541956b54eebf9aedf4183fcb..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/cache/81204C68.json
+++ /dev/null
@@ -1,317 +0,0 @@
-{
-  "acc": {
-    "y": {
-      "ident": 26,
-      "group": "acc",
-      "name": "y",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "x": {
-      "ident": 25,
-      "group": "acc",
-      "name": "x",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "z": {
-      "ident": 27,
-      "group": "acc",
-      "name": "z",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "zw": {
-      "ident": 28,
-      "group": "acc",
-      "name": "zw",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "gyro": {
-    "y": {
-      "ident": 4,
-      "group": "gyro",
-      "name": "y",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "x": {
-      "ident": 3,
-      "group": "gyro",
-      "name": "x",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "z": {
-      "ident": 5,
-      "group": "gyro",
-      "name": "z",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "sys": {
-    "canfly": {
-      "ident": 2,
-      "group": "sys",
-      "name": "canfly",
-      "pytype": "<b",
-      "__class__": "LogTocElement",
-      "ctype": "int8_t",
-      "access": 0
-    }
-  },
-  "stabilizer": {
-    "thrust": {
-      "ident": 9,
-      "group": "stabilizer",
-      "name": "thrust",
-      "pytype": "<H",
-      "__class__": "LogTocElement",
-      "ctype": "uint16_t",
-      "access": 0
-    },
-    "yaw": {
-      "ident": 8,
-      "group": "stabilizer",
-      "name": "yaw",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll": {
-      "ident": 6,
-      "group": "stabilizer",
-      "name": "roll",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch": {
-      "ident": 7,
-      "group": "stabilizer",
-      "name": "pitch",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "motor": {
-    "m4": {
-      "ident": 21,
-      "group": "motor",
-      "name": "m4",
-      "pytype": "<i",
-      "__class__": "LogTocElement",
-      "ctype": "int32_t",
-      "access": 0
-    },
-    "m1": {
-      "ident": 22,
-      "group": "motor",
-      "name": "m1",
-      "pytype": "<i",
-      "__class__": "LogTocElement",
-      "ctype": "int32_t",
-      "access": 0
-    },
-    "m3": {
-      "ident": 24,
-      "group": "motor",
-      "name": "m3",
-      "pytype": "<i",
-      "__class__": "LogTocElement",
-      "ctype": "int32_t",
-      "access": 0
-    },
-    "m2": {
-      "ident": 23,
-      "group": "motor",
-      "name": "m2",
-      "pytype": "<i",
-      "__class__": "LogTocElement",
-      "ctype": "int32_t",
-      "access": 0
-    }
-  },
-  "altHold": {
-    "vSpeed": {
-      "ident": 18,
-      "group": "altHold",
-      "name": "vSpeed",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "target": {
-      "ident": 16,
-      "group": "altHold",
-      "name": "target",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "err": {
-      "ident": 15,
-      "group": "altHold",
-      "name": "err",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "vSpeedASL": {
-      "ident": 19,
-      "group": "altHold",
-      "name": "vSpeedASL",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "vSpeedAcc": {
-      "ident": 20,
-      "group": "altHold",
-      "name": "vSpeedAcc",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "zSpeed": {
-      "ident": 17,
-      "group": "altHold",
-      "name": "zSpeed",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "vpid": {
-    "i": {
-      "ident": 31,
-      "group": "vpid",
-      "name": "i",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "p": {
-      "ident": 30,
-      "group": "vpid",
-      "name": "p",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pid": {
-      "ident": 29,
-      "group": "vpid",
-      "name": "pid",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "d": {
-      "ident": 32,
-      "group": "vpid",
-      "name": "d",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "baro": {
-    "aslRaw": {
-      "ident": 11,
-      "group": "baro",
-      "name": "aslRaw",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "aslLong": {
-      "ident": 12,
-      "group": "baro",
-      "name": "aslLong",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pressure": {
-      "ident": 14,
-      "group": "baro",
-      "name": "pressure",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "temp": {
-      "ident": 13,
-      "group": "baro",
-      "name": "temp",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "asl": {
-      "ident": 10,
-      "group": "baro",
-      "name": "asl",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "pm": {
-    "state": {
-      "ident": 1,
-      "group": "pm",
-      "name": "state",
-      "pytype": "<b",
-      "__class__": "LogTocElement",
-      "ctype": "int8_t",
-      "access": 0
-    },
-    "vbat": {
-      "ident": 0,
-      "group": "pm",
-      "name": "vbat",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  }
-}
diff --git a/src/cflib/cflib/cache/892049D2.json b/src/cflib/cflib/cache/892049D2.json
deleted file mode 100644
index 3d6fa5f288fb998266b3c0966f7b17701561000a..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/cache/892049D2.json
+++ /dev/null
@@ -1,89 +0,0 @@
-{
-  "stabilizer": {
-    "thrust": {
-      "ident": 4,
-      "group": "stabilizer",
-      "name": "thrust",
-      "pytype": "<H",
-      "__class__": "LogTocElement",
-      "ctype": "uint16_t",
-      "access": 0
-    },
-    "yaw": {
-      "ident": 3,
-      "group": "stabilizer",
-      "name": "yaw",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll": {
-      "ident": 1,
-      "group": "stabilizer",
-      "name": "roll",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch": {
-      "ident": 2,
-      "group": "stabilizer",
-      "name": "pitch",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "motor": {
-    "m4": {
-      "ident": 5,
-      "group": "motor",
-      "name": "m4",
-      "pytype": "<i",
-      "__class__": "LogTocElement",
-      "ctype": "int32_t",
-      "access": 0
-    },
-    "m1": {
-      "ident": 6,
-      "group": "motor",
-      "name": "m1",
-      "pytype": "<i",
-      "__class__": "LogTocElement",
-      "ctype": "int32_t",
-      "access": 0
-    },
-    "m3": {
-      "ident": 8,
-      "group": "motor",
-      "name": "m3",
-      "pytype": "<i",
-      "__class__": "LogTocElement",
-      "ctype": "int32_t",
-      "access": 0
-    },
-    "m2": {
-      "ident": 7,
-      "group": "motor",
-      "name": "m2",
-      "pytype": "<i",
-      "__class__": "LogTocElement",
-      "ctype": "int32_t",
-      "access": 0
-    }
-  },
-  "pm": {
-    "vbat": {
-      "ident": 0,
-      "group": "pm",
-      "name": "vbat",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  }
-}
diff --git a/src/cflib/cflib/cache/9E5F2E7D.json b/src/cflib/cflib/cache/9E5F2E7D.json
deleted file mode 100644
index a960b53caeab96ec5cfecacab2dc59b5738bfcb9..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/cache/9E5F2E7D.json
+++ /dev/null
@@ -1,355 +0,0 @@
-{
-  "acc": {
-    "y": {
-      "ident": 4,
-      "group": "acc",
-      "name": "y",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "x": {
-      "ident": 3,
-      "group": "acc",
-      "name": "x",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "z": {
-      "ident": 5,
-      "group": "acc",
-      "name": "z",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "zw": {
-      "ident": 6,
-      "group": "acc",
-      "name": "zw",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "mag2": {
-      "ident": 7,
-      "group": "acc",
-      "name": "mag2",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "mag": {
-    "y": {
-      "ident": 35,
-      "group": "mag",
-      "name": "y",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "x": {
-      "ident": 34,
-      "group": "mag",
-      "name": "x",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "z": {
-      "ident": 36,
-      "group": "mag",
-      "name": "z",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "gyro": {
-    "y": {
-      "ident": 28,
-      "group": "gyro",
-      "name": "y",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "x": {
-      "ident": 27,
-      "group": "gyro",
-      "name": "x",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "z": {
-      "ident": 29,
-      "group": "gyro",
-      "name": "z",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "sys": {
-    "canfly": {
-      "ident": 2,
-      "group": "sys",
-      "name": "canfly",
-      "pytype": "<b",
-      "__class__": "LogTocElement",
-      "ctype": "int8_t",
-      "access": 0
-    }
-  },
-  "stabilizer": {
-    "thrust": {
-      "ident": 20,
-      "group": "stabilizer",
-      "name": "thrust",
-      "pytype": "<H",
-      "__class__": "LogTocElement",
-      "ctype": "uint16_t",
-      "access": 0
-    },
-    "yaw": {
-      "ident": 19,
-      "group": "stabilizer",
-      "name": "yaw",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll": {
-      "ident": 17,
-      "group": "stabilizer",
-      "name": "roll",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch": {
-      "ident": 18,
-      "group": "stabilizer",
-      "name": "pitch",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "motor": {
-    "m4": {
-      "ident": 13,
-      "group": "motor",
-      "name": "m4",
-      "pytype": "<i",
-      "__class__": "LogTocElement",
-      "ctype": "int32_t",
-      "access": 0
-    },
-    "m1": {
-      "ident": 14,
-      "group": "motor",
-      "name": "m1",
-      "pytype": "<i",
-      "__class__": "LogTocElement",
-      "ctype": "int32_t",
-      "access": 0
-    },
-    "m3": {
-      "ident": 16,
-      "group": "motor",
-      "name": "m3",
-      "pytype": "<i",
-      "__class__": "LogTocElement",
-      "ctype": "int32_t",
-      "access": 0
-    },
-    "m2": {
-      "ident": 15,
-      "group": "motor",
-      "name": "m2",
-      "pytype": "<i",
-      "__class__": "LogTocElement",
-      "ctype": "int32_t",
-      "access": 0
-    }
-  },
-  "altHold": {
-    "vSpeed": {
-      "ident": 24,
-      "group": "altHold",
-      "name": "vSpeed",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "target": {
-      "ident": 22,
-      "group": "altHold",
-      "name": "target",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "err": {
-      "ident": 21,
-      "group": "altHold",
-      "name": "err",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "vSpeedASL": {
-      "ident": 25,
-      "group": "altHold",
-      "name": "vSpeedASL",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "vSpeedAcc": {
-      "ident": 26,
-      "group": "altHold",
-      "name": "vSpeedAcc",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "zSpeed": {
-      "ident": 23,
-      "group": "altHold",
-      "name": "zSpeed",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "vpid": {
-    "i": {
-      "ident": 32,
-      "group": "vpid",
-      "name": "i",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "p": {
-      "ident": 31,
-      "group": "vpid",
-      "name": "p",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pid": {
-      "ident": 30,
-      "group": "vpid",
-      "name": "pid",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "d": {
-      "ident": 33,
-      "group": "vpid",
-      "name": "d",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "baro": {
-    "aslRaw": {
-      "ident": 9,
-      "group": "baro",
-      "name": "aslRaw",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "aslLong": {
-      "ident": 10,
-      "group": "baro",
-      "name": "aslLong",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pressure": {
-      "ident": 12,
-      "group": "baro",
-      "name": "pressure",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "temp": {
-      "ident": 11,
-      "group": "baro",
-      "name": "temp",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "asl": {
-      "ident": 8,
-      "group": "baro",
-      "name": "asl",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "pm": {
-    "state": {
-      "ident": 1,
-      "group": "pm",
-      "name": "state",
-      "pytype": "<b",
-      "__class__": "LogTocElement",
-      "ctype": "int8_t",
-      "access": 0
-    },
-    "vbat": {
-      "ident": 0,
-      "group": "pm",
-      "name": "vbat",
-      "pytype": "<f",
-      "__class__": "LogTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  }
-}
diff --git a/src/cflib/cflib/cache/E20076B8.json b/src/cflib/cflib/cache/E20076B8.json
deleted file mode 100644
index 1d743ab0fe9dc58a1f51f2f46fea04e18a064092..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/cache/E20076B8.json
+++ /dev/null
@@ -1,499 +0,0 @@
-{
-  "imu_sensors": {
-    "HMC5883L": {
-      "ident": 3,
-      "group": "imu_sensors",
-      "name": "HMC5883L",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 1
-    },
-    "MS5611": {
-      "ident": 4,
-      "group": "imu_sensors",
-      "name": "MS5611",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 1
-    }
-  },
-  "sensorfusion6": {
-    "ki": {
-      "ident": 30,
-      "group": "sensorfusion6",
-      "name": "ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "kp": {
-      "ident": 29,
-      "group": "sensorfusion6",
-      "name": "kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "flightmode": {
-    "althold": {
-      "ident": 10,
-      "group": "flightmode",
-      "name": "althold",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 0
-    }
-  },
-  "firmware": {
-    "revision0": {
-      "ident": 50,
-      "group": "firmware",
-      "name": "revision0",
-      "pytype": "<L",
-      "__class__": "ParamTocElement",
-      "ctype": "uint32_t",
-      "access": 1
-    },
-    "revision1": {
-      "ident": 51,
-      "group": "firmware",
-      "name": "revision1",
-      "pytype": "<H",
-      "__class__": "ParamTocElement",
-      "ctype": "uint16_t",
-      "access": 1
-    },
-    "modified": {
-      "ident": 52,
-      "group": "firmware",
-      "name": "modified",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 1
-    }
-  },
-  "cpu": {
-    "flash": {
-      "ident": 6,
-      "group": "cpu",
-      "name": "flash",
-      "pytype": "<H",
-      "__class__": "ParamTocElement",
-      "ctype": "uint16_t",
-      "access": 1
-    },
-    "id2": {
-      "ident": 9,
-      "group": "cpu",
-      "name": "id2",
-      "pytype": "<L",
-      "__class__": "ParamTocElement",
-      "ctype": "uint32_t",
-      "access": 1
-    },
-    "id0": {
-      "ident": 7,
-      "group": "cpu",
-      "name": "id0",
-      "pytype": "<L",
-      "__class__": "ParamTocElement",
-      "ctype": "uint32_t",
-      "access": 1
-    },
-    "id1": {
-      "ident": 8,
-      "group": "cpu",
-      "name": "id1",
-      "pytype": "<L",
-      "__class__": "ParamTocElement",
-      "ctype": "uint32_t",
-      "access": 1
-    }
-  },
-  "pid_rate": {
-    "yaw_kp": {
-      "ident": 17,
-      "group": "pid_rate",
-      "name": "yaw_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_kd": {
-      "ident": 13,
-      "group": "pid_rate",
-      "name": "roll_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_kp": {
-      "ident": 14,
-      "group": "pid_rate",
-      "name": "pitch_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_ki": {
-      "ident": 12,
-      "group": "pid_rate",
-      "name": "roll_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_ki": {
-      "ident": 15,
-      "group": "pid_rate",
-      "name": "pitch_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_kp": {
-      "ident": 11,
-      "group": "pid_rate",
-      "name": "roll_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "yaw_kd": {
-      "ident": 19,
-      "group": "pid_rate",
-      "name": "yaw_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "yaw_ki": {
-      "ident": 18,
-      "group": "pid_rate",
-      "name": "yaw_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_kd": {
-      "ident": 16,
-      "group": "pid_rate",
-      "name": "pitch_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "pid_attitude": {
-    "yaw_kp": {
-      "ident": 26,
-      "group": "pid_attitude",
-      "name": "yaw_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_kd": {
-      "ident": 22,
-      "group": "pid_attitude",
-      "name": "roll_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_kp": {
-      "ident": 23,
-      "group": "pid_attitude",
-      "name": "pitch_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_ki": {
-      "ident": 21,
-      "group": "pid_attitude",
-      "name": "roll_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_ki": {
-      "ident": 24,
-      "group": "pid_attitude",
-      "name": "pitch_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_kp": {
-      "ident": 20,
-      "group": "pid_attitude",
-      "name": "roll_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "yaw_kd": {
-      "ident": 28,
-      "group": "pid_attitude",
-      "name": "yaw_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "yaw_ki": {
-      "ident": 27,
-      "group": "pid_attitude",
-      "name": "yaw_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_kd": {
-      "ident": 25,
-      "group": "pid_attitude",
-      "name": "pitch_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "altHold": {
-    "vSpeedAccFac": {
-      "ident": 43,
-      "group": "altHold",
-      "name": "vSpeedAccFac",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "vSpeedASLDeadband": {
-      "ident": 44,
-      "group": "altHold",
-      "name": "vSpeedASLDeadband",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "errDeadband": {
-      "ident": 33,
-      "group": "altHold",
-      "name": "errDeadband",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "altHoldErrMax": {
-      "ident": 35,
-      "group": "altHold",
-      "name": "altHoldErrMax",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "kd": {
-      "ident": 36,
-      "group": "altHold",
-      "name": "kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pidAslFac": {
-      "ident": 40,
-      "group": "altHold",
-      "name": "pidAslFac",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "maxThrust": {
-      "ident": 48,
-      "group": "altHold",
-      "name": "maxThrust",
-      "pytype": "<H",
-      "__class__": "ParamTocElement",
-      "ctype": "uint16_t",
-      "access": 0
-    },
-    "ki": {
-      "ident": 37,
-      "group": "altHold",
-      "name": "ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "vSpeedLimit": {
-      "ident": 46,
-      "group": "altHold",
-      "name": "vSpeedLimit",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "aslAlpha": {
-      "ident": 31,
-      "group": "altHold",
-      "name": "aslAlpha",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "kp": {
-      "ident": 38,
-      "group": "altHold",
-      "name": "kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "baseThrust": {
-      "ident": 47,
-      "group": "altHold",
-      "name": "baseThrust",
-      "pytype": "<H",
-      "__class__": "ParamTocElement",
-      "ctype": "uint16_t",
-      "access": 0
-    },
-    "vBiasAlpha": {
-      "ident": 42,
-      "group": "altHold",
-      "name": "vBiasAlpha",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pidAlpha": {
-      "ident": 39,
-      "group": "altHold",
-      "name": "pidAlpha",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "altHoldChangeSens": {
-      "ident": 34,
-      "group": "altHold",
-      "name": "altHoldChangeSens",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "minThrust": {
-      "ident": 49,
-      "group": "altHold",
-      "name": "minThrust",
-      "pytype": "<H",
-      "__class__": "ParamTocElement",
-      "ctype": "uint16_t",
-      "access": 0
-    },
-    "vAccDeadband": {
-      "ident": 41,
-      "group": "altHold",
-      "name": "vAccDeadband",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "aslAlphaLong": {
-      "ident": 32,
-      "group": "altHold",
-      "name": "aslAlphaLong",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "vSpeedASLFac": {
-      "ident": 45,
-      "group": "altHold",
-      "name": "vSpeedASLFac",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "imu_tests": {
-    "HMC5883L": {
-      "ident": 1,
-      "group": "imu_tests",
-      "name": "HMC5883L",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 1
-    },
-    "MS5611": {
-      "ident": 2,
-      "group": "imu_tests",
-      "name": "MS5611",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 1
-    },
-    "MPU6050": {
-      "ident": 0,
-      "group": "imu_tests",
-      "name": "MPU6050",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 1
-    }
-  },
-  "imu_acc_lpf": {
-    "factor": {
-      "ident": 5,
-      "group": "imu_acc_lpf",
-      "name": "factor",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 0
-    }
-  }
-}
diff --git a/src/cflib/cflib/cache/E8BC7DAD.json b/src/cflib/cflib/cache/E8BC7DAD.json
deleted file mode 100644
index 1d743ab0fe9dc58a1f51f2f46fea04e18a064092..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/cache/E8BC7DAD.json
+++ /dev/null
@@ -1,499 +0,0 @@
-{
-  "imu_sensors": {
-    "HMC5883L": {
-      "ident": 3,
-      "group": "imu_sensors",
-      "name": "HMC5883L",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 1
-    },
-    "MS5611": {
-      "ident": 4,
-      "group": "imu_sensors",
-      "name": "MS5611",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 1
-    }
-  },
-  "sensorfusion6": {
-    "ki": {
-      "ident": 30,
-      "group": "sensorfusion6",
-      "name": "ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "kp": {
-      "ident": 29,
-      "group": "sensorfusion6",
-      "name": "kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "flightmode": {
-    "althold": {
-      "ident": 10,
-      "group": "flightmode",
-      "name": "althold",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 0
-    }
-  },
-  "firmware": {
-    "revision0": {
-      "ident": 50,
-      "group": "firmware",
-      "name": "revision0",
-      "pytype": "<L",
-      "__class__": "ParamTocElement",
-      "ctype": "uint32_t",
-      "access": 1
-    },
-    "revision1": {
-      "ident": 51,
-      "group": "firmware",
-      "name": "revision1",
-      "pytype": "<H",
-      "__class__": "ParamTocElement",
-      "ctype": "uint16_t",
-      "access": 1
-    },
-    "modified": {
-      "ident": 52,
-      "group": "firmware",
-      "name": "modified",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 1
-    }
-  },
-  "cpu": {
-    "flash": {
-      "ident": 6,
-      "group": "cpu",
-      "name": "flash",
-      "pytype": "<H",
-      "__class__": "ParamTocElement",
-      "ctype": "uint16_t",
-      "access": 1
-    },
-    "id2": {
-      "ident": 9,
-      "group": "cpu",
-      "name": "id2",
-      "pytype": "<L",
-      "__class__": "ParamTocElement",
-      "ctype": "uint32_t",
-      "access": 1
-    },
-    "id0": {
-      "ident": 7,
-      "group": "cpu",
-      "name": "id0",
-      "pytype": "<L",
-      "__class__": "ParamTocElement",
-      "ctype": "uint32_t",
-      "access": 1
-    },
-    "id1": {
-      "ident": 8,
-      "group": "cpu",
-      "name": "id1",
-      "pytype": "<L",
-      "__class__": "ParamTocElement",
-      "ctype": "uint32_t",
-      "access": 1
-    }
-  },
-  "pid_rate": {
-    "yaw_kp": {
-      "ident": 17,
-      "group": "pid_rate",
-      "name": "yaw_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_kd": {
-      "ident": 13,
-      "group": "pid_rate",
-      "name": "roll_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_kp": {
-      "ident": 14,
-      "group": "pid_rate",
-      "name": "pitch_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_ki": {
-      "ident": 12,
-      "group": "pid_rate",
-      "name": "roll_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_ki": {
-      "ident": 15,
-      "group": "pid_rate",
-      "name": "pitch_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_kp": {
-      "ident": 11,
-      "group": "pid_rate",
-      "name": "roll_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "yaw_kd": {
-      "ident": 19,
-      "group": "pid_rate",
-      "name": "yaw_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "yaw_ki": {
-      "ident": 18,
-      "group": "pid_rate",
-      "name": "yaw_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_kd": {
-      "ident": 16,
-      "group": "pid_rate",
-      "name": "pitch_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "pid_attitude": {
-    "yaw_kp": {
-      "ident": 26,
-      "group": "pid_attitude",
-      "name": "yaw_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_kd": {
-      "ident": 22,
-      "group": "pid_attitude",
-      "name": "roll_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_kp": {
-      "ident": 23,
-      "group": "pid_attitude",
-      "name": "pitch_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_ki": {
-      "ident": 21,
-      "group": "pid_attitude",
-      "name": "roll_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_ki": {
-      "ident": 24,
-      "group": "pid_attitude",
-      "name": "pitch_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "roll_kp": {
-      "ident": 20,
-      "group": "pid_attitude",
-      "name": "roll_kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "yaw_kd": {
-      "ident": 28,
-      "group": "pid_attitude",
-      "name": "yaw_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "yaw_ki": {
-      "ident": 27,
-      "group": "pid_attitude",
-      "name": "yaw_ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pitch_kd": {
-      "ident": 25,
-      "group": "pid_attitude",
-      "name": "pitch_kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "altHold": {
-    "vSpeedAccFac": {
-      "ident": 43,
-      "group": "altHold",
-      "name": "vSpeedAccFac",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "vSpeedASLDeadband": {
-      "ident": 44,
-      "group": "altHold",
-      "name": "vSpeedASLDeadband",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "errDeadband": {
-      "ident": 33,
-      "group": "altHold",
-      "name": "errDeadband",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "altHoldErrMax": {
-      "ident": 35,
-      "group": "altHold",
-      "name": "altHoldErrMax",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "kd": {
-      "ident": 36,
-      "group": "altHold",
-      "name": "kd",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pidAslFac": {
-      "ident": 40,
-      "group": "altHold",
-      "name": "pidAslFac",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "maxThrust": {
-      "ident": 48,
-      "group": "altHold",
-      "name": "maxThrust",
-      "pytype": "<H",
-      "__class__": "ParamTocElement",
-      "ctype": "uint16_t",
-      "access": 0
-    },
-    "ki": {
-      "ident": 37,
-      "group": "altHold",
-      "name": "ki",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "vSpeedLimit": {
-      "ident": 46,
-      "group": "altHold",
-      "name": "vSpeedLimit",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "aslAlpha": {
-      "ident": 31,
-      "group": "altHold",
-      "name": "aslAlpha",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "kp": {
-      "ident": 38,
-      "group": "altHold",
-      "name": "kp",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "baseThrust": {
-      "ident": 47,
-      "group": "altHold",
-      "name": "baseThrust",
-      "pytype": "<H",
-      "__class__": "ParamTocElement",
-      "ctype": "uint16_t",
-      "access": 0
-    },
-    "vBiasAlpha": {
-      "ident": 42,
-      "group": "altHold",
-      "name": "vBiasAlpha",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "pidAlpha": {
-      "ident": 39,
-      "group": "altHold",
-      "name": "pidAlpha",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "altHoldChangeSens": {
-      "ident": 34,
-      "group": "altHold",
-      "name": "altHoldChangeSens",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "minThrust": {
-      "ident": 49,
-      "group": "altHold",
-      "name": "minThrust",
-      "pytype": "<H",
-      "__class__": "ParamTocElement",
-      "ctype": "uint16_t",
-      "access": 0
-    },
-    "vAccDeadband": {
-      "ident": 41,
-      "group": "altHold",
-      "name": "vAccDeadband",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "aslAlphaLong": {
-      "ident": 32,
-      "group": "altHold",
-      "name": "aslAlphaLong",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    },
-    "vSpeedASLFac": {
-      "ident": 45,
-      "group": "altHold",
-      "name": "vSpeedASLFac",
-      "pytype": "<f",
-      "__class__": "ParamTocElement",
-      "ctype": "float",
-      "access": 0
-    }
-  },
-  "imu_tests": {
-    "HMC5883L": {
-      "ident": 1,
-      "group": "imu_tests",
-      "name": "HMC5883L",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 1
-    },
-    "MS5611": {
-      "ident": 2,
-      "group": "imu_tests",
-      "name": "MS5611",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 1
-    },
-    "MPU6050": {
-      "ident": 0,
-      "group": "imu_tests",
-      "name": "MPU6050",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 1
-    }
-  },
-  "imu_acc_lpf": {
-    "factor": {
-      "ident": 5,
-      "group": "imu_acc_lpf",
-      "name": "factor",
-      "pytype": "<B",
-      "__class__": "ParamTocElement",
-      "ctype": "uint8_t",
-      "access": 0
-    }
-  }
-}
diff --git a/src/cflib/cflib/crazyflie/__init__.py b/src/cflib/cflib/crazyflie/__init__.py
deleted file mode 100644
index 698fef1eca0b632a9b1f62c83401ab91f4bc1ef6..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crazyflie/__init__.py
+++ /dev/null
@@ -1,400 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-The Crazyflie module is used to easily connect/send/receive data
-from a Crazyflie.
-
-Each function in the Crazyflie has a class in the module that can be used
-to access that functionality. The same design is then used in the Crazyflie
-firmware which makes the mapping 1:1 in most cases.
-"""
-
-import logging
-
-import time
-import datetime
-from threading import Thread
-from threading import Timer, Lock
-from collections import namedtuple
-
-from .commander import Commander
-from .console import Console
-from .param import Param
-from .log import Log
-from .toccache import TocCache
-from .mem import Memory
-from .platformservice import PlatformService
-
-import cflib.crtp
-
-from cflib.utils.callbacks import Caller
-
-__author__ = 'Bitcraze AB'
-__all__ = ['Crazyflie']
-
-logger = logging.getLogger(__name__)
-
-
-class State:
-    """Stat of the connection procedure"""
-    DISCONNECTED = 0
-    INITIALIZED = 1
-    CONNECTED = 2
-    SETUP_FINISHED = 3
-
-
-class Crazyflie():
-    """The Crazyflie class"""
-
-    # Called on disconnect, no matter the reason
-    disconnected = Caller()
-    # Called on unintentional disconnect only
-    connection_lost = Caller()
-    # Called when the first packet in a new link is received
-    link_established = Caller()
-    # Called when the user requests a connection
-    connection_requested = Caller()
-    # Called when the link is established and the TOCs (that are not cached)
-    # have been downloaded
-    connected = Caller()
-    # Called if establishing of the link fails (i.e times out)
-    connection_failed = Caller()
-    # Called for every packet received
-    packet_received = Caller()
-    # Called for every packet sent
-    packet_sent = Caller()
-    # Called when the link driver updates the link quality measurement
-    link_quality_updated = Caller()
-
-    state = State.DISCONNECTED
-
-    def __init__(self, link=None, ro_cache=None, rw_cache=None):
-        """
-        Create the objects from this module and register callbacks.
-
-        ro_cache -- Path to read-only cache (string)
-        rw_cache -- Path to read-write cache (string)
-        """
-        self.link = link
-        self._toc_cache = TocCache(ro_cache=ro_cache,
-                                   rw_cache=rw_cache)
-
-        self.incoming = _IncomingPacketHandler(self)
-        self.incoming.setDaemon(True)
-        self.incoming.start()
-
-        self.commander = Commander(self)
-        self.log = Log(self)
-        self.console = Console(self)
-        self.param = Param(self)
-        self.mem = Memory(self)
-        self.platform = PlatformService(self)
-
-        self.link_uri = ""
-
-        # Used for retry when no reply was sent back
-        self.packet_received.add_callback(self._check_for_initial_packet_cb)
-        self.packet_received.add_callback(self._check_for_answers)
-
-        self._answer_patterns = {}
-
-        self._send_lock = Lock()
-
-        self.connected_ts = None
-
-        # Connect callbacks to logger
-        self.disconnected.add_callback(
-            lambda uri: logger.info("Callback->Disconnected from [%s]", uri))
-        self.disconnected.add_callback(self._disconnected)
-        self.link_established.add_callback(
-            lambda uri: logger.info("Callback->Connected to [%s]", uri))
-        self.connection_lost.add_callback(
-            lambda uri, errmsg: logger.info(
-                "Callback->Connection lost to [%s]: %s", uri, errmsg))
-        self.connection_failed.add_callback(
-            lambda uri, errmsg: logger.info(
-                "Callback->Connected failed to [%s]: %s", uri, errmsg))
-        self.connection_requested.add_callback(
-            lambda uri: logger.info(
-                "Callback->Connection initialized[%s]", uri))
-        self.connected.add_callback(
-            lambda uri: logger.info(
-                "Callback->Connection setup finished [%s]", uri))
-
-    def _disconnected(self, link_uri):
-        """ Callback when disconnected."""
-        self.connected_ts = None
-
-    def _start_connection_setup(self):
-        """Start the connection setup by refreshing the TOCs"""
-        logger.info("We are connected[%s], request connection setup",
-                    self.link_uri)
-        self.log.refresh_toc(self._log_toc_updated_cb, self._toc_cache)
-
-    def _param_toc_updated_cb(self):
-        """Called when the param TOC has been fully updated"""
-        logger.info("Param TOC finished updating")
-        self.connected_ts = datetime.datetime.now()
-        self.connected.call(self.link_uri)
-        # Trigger the update for all the parameters
-        self.param.request_update_of_all_params()
-
-    def _mems_updated_cb(self):
-        """Called when the memories have been identified"""
-        logger.info("Memories finished updating")
-        self.param.refresh_toc(self._param_toc_updated_cb, self._toc_cache)
-
-    def _log_toc_updated_cb(self):
-        """Called when the log TOC has been fully updated"""
-        logger.info("Log TOC finished updating")
-        self.mem.refresh(self._mems_updated_cb)
-
-    def _link_error_cb(self, errmsg):
-        """Called from the link driver when there's an error"""
-        logger.warning("Got link error callback [%s] in state [%s]",
-                       errmsg, self.state)
-        if (self.link is not None):
-            self.link.close()
-        self.link = None
-        if (self.state == State.INITIALIZED):
-            self.connection_failed.call(self.link_uri, errmsg)
-        if (self.state == State.CONNECTED or
-                self.state == State.SETUP_FINISHED):
-            self.disconnected.call(self.link_uri)
-            self.connection_lost.call(self.link_uri, errmsg)
-        self.state = State.DISCONNECTED
-
-    def _link_quality_cb(self, percentage):
-        """Called from link driver to report link quality"""
-        self.link_quality_updated.call(percentage)
-
-    def _check_for_initial_packet_cb(self, data):
-        """
-        Called when first packet arrives from Crazyflie.
-
-        This is used to determine if we are connected to something that is
-        answering.
-        """
-        self.state = State.CONNECTED
-        self.link_established.call(self.link_uri)
-        self.packet_received.remove_callback(self._check_for_initial_packet_cb)
-
-    def open_link(self, link_uri):
-        """
-        Open the communication link to a copter at the given URI and setup the
-        connection (download log/parameter TOC).
-        """
-        self.connection_requested.call(link_uri)
-        self.state = State.INITIALIZED
-        self.link_uri = link_uri
-        try:
-            self.link = cflib.crtp.get_link_driver(
-                link_uri, self._link_quality_cb, self._link_error_cb)
-
-            if not self.link:
-                message = "No driver found or malformed URI: {}" \
-                    .format(link_uri)
-                logger.warning(message)
-                self.connection_failed.call(link_uri, message)
-            else:
-                # Add a callback so we can check that any data is coming
-                # back from the copter
-                self.packet_received.add_callback(
-                    self._check_for_initial_packet_cb)
-
-                self._start_connection_setup()
-        except Exception as ex:  # pylint: disable=W0703
-            # We want to catch every possible exception here and show
-            # it in the user interface
-            import traceback
-
-            logger.error("Couldn't load link driver: %s\n\n%s",
-                         ex, traceback.format_exc())
-            exception_text = "Couldn't load link driver: %s\n\n%s" % (
-                ex, traceback.format_exc())
-            if self.link:
-                self.link.close()
-                self.link = None
-            self.connection_failed.call(link_uri, exception_text)
-
-    def close_link(self):
-        """Close the communication link."""
-        logger.info("Closing link")
-        if (self.link is not None):
-            self.commander.send_setpoint(0, 0, 0, 0)
-        if (self.link is not None):
-            self.link.close()
-            self.link = None
-        self._answer_patterns = {}
-        self.disconnected.call(self.link_uri)
-
-    def add_port_callback(self, port, cb):
-        """Add a callback to cb on port"""
-        self.incoming.add_port_callback(port, cb)
-
-    def remove_port_callback(self, port, cb):
-        """Remove the callback cb on port"""
-        self.incoming.remove_port_callback(port, cb)
-
-    def _no_answer_do_retry(self, pk, pattern):
-        """Resend packets that we have not gotten answers to"""
-        logger.info("Resending for pattern %s", pattern)
-        # Set the timer to None before trying to send again
-        self.send_packet(pk, expected_reply=pattern, resend=True)
-
-    def _check_for_answers(self, pk):
-        """
-        Callback called for every packet received to check if we are
-        waiting for an answer on this port. If so, then cancel the retry
-        timer.
-        """
-        longest_match = ()
-        if len(self._answer_patterns) > 0:
-            data = (pk.header,) + tuple(pk.data)
-            for p in list(self._answer_patterns.keys()):
-                logger.debug("Looking for pattern match on %s vs %s", p, data)
-                if len(p) <= len(data):
-                    if p == data[0:len(p)]:
-                        match = data[0:len(p)]
-                        if len(match) >= len(longest_match):
-                            logger.debug("Found new longest match %s", match)
-                            longest_match = match
-        if len(longest_match) > 0:
-            self._answer_patterns[longest_match].cancel()
-            del self._answer_patterns[longest_match]
-
-    def send_packet(self, pk, expected_reply=(), resend=False, timeout=0.2):
-        """
-        Send a packet through the link interface.
-
-        pk -- Packet to send
-        expect_answer -- True if a packet from the Crazyflie is expected to
-                         be sent back, otherwise false
-
-        """
-        self._send_lock.acquire()
-        if self.link is not None:
-            if len(expected_reply) > 0 and not resend and \
-                    self.link.needs_resending:
-                pattern = (pk.header,) + expected_reply
-                logger.debug(
-                    "Sending packet and expecting the %s pattern back",
-                    pattern)
-                new_timer = Timer(timeout,
-                                  lambda: self._no_answer_do_retry(pk,
-                                                                   pattern))
-                self._answer_patterns[pattern] = new_timer
-                new_timer.start()
-            elif resend:
-                # Check if we have gotten an answer, if not try again
-                pattern = expected_reply
-                if pattern in self._answer_patterns:
-                    logger.debug("We want to resend and the pattern is there")
-                    if self._answer_patterns[pattern]:
-                        new_timer = Timer(timeout,
-                                          lambda:
-                                          self._no_answer_do_retry(
-                                              pk, pattern))
-                        self._answer_patterns[pattern] = new_timer
-                        new_timer.start()
-                else:
-                    logger.debug("Resend requested, but no pattern found: %s",
-                                 self._answer_patterns)
-            self.link.send_packet(pk)
-            self.packet_sent.call(pk)
-        self._send_lock.release()
-
-
-_CallbackContainer = namedtuple("CallbackConstainer",
-                                "port port_mask channel channel_mask callback")
-
-
-class _IncomingPacketHandler(Thread):
-    """Handles incoming packets and sends the data to the correct receivers"""
-
-    def __init__(self, cf):
-        Thread.__init__(self)
-        self.cf = cf
-        self.cb = []
-
-    def add_port_callback(self, port, cb):
-        """Add a callback for data that comes on a specific port"""
-        logger.debug("Adding callback on port [%d] to [%s]", port, cb)
-        self.add_header_callback(cb, port, 0, 0xff, 0x0)
-
-    def remove_port_callback(self, port, cb):
-        """Remove a callback for data that comes on a specific port"""
-        logger.debug("Removing callback on port [%d] to [%s]", port, cb)
-        for port_callback in self.cb:
-            if port_callback.port == port and port_callback.callback == cb:
-                self.cb.remove(port_callback)
-
-    def add_header_callback(self, cb, port, channel, port_mask=0xFF,
-                            channel_mask=0xFF):
-        """
-        Add a callback for a specific port/header callback with the
-        possibility to add a mask for channel and port for multiple
-        hits for same callback.
-        """
-        self.cb.append(_CallbackContainer(port, port_mask,
-                                          channel, channel_mask, cb))
-
-    def run(self):
-        while True:
-            if self.cf.link is None:
-                time.sleep(1)
-                continue
-            pk = self.cf.link.receive_packet(1)
-
-            if pk is None:
-                continue
-
-            # All-packet callbacks
-            self.cf.packet_received.call(pk)
-
-            found = False
-            for cb in (cb for cb in self.cb
-                       if cb.port == (pk.port & cb.port_mask) and
-                       cb.channel == (pk.channel & cb.channel_mask)):
-                try:
-                    cb.callback(pk)
-                except Exception:  # pylint: disable=W0703
-                    # Disregard pylint warning since we want to catch all
-                    # exceptions and we can't know what will happen in
-                    # the callbacks.
-                    import traceback
-
-                    logger.warning("Exception while doing callback on port"
-                                   " [%d]\n\n%s", pk.port,
-                                   traceback.format_exc())
-                if cb.port != 0xFF:
-                    found = True
-
-            if not found:
-                pass
diff --git a/src/cflib/cflib/crazyflie/commander.py b/src/cflib/cflib/crazyflie/commander.py
deleted file mode 100644
index c9477212c5f1b5175fd14e34319e167fcc805128..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crazyflie/commander.py
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-"""
-Used for sending control setpoints to the Crazyflie
-"""
-import struct
-
-from cflib.crtp.crtpstack import CRTPPacket
-from cflib.crtp.crtpstack import CRTPPort
-
-__author__ = 'Bitcraze AB'
-__all__ = ['Commander']
-
-
-class Commander():
-    """
-    Used for sending control setpoints to the Crazyflie
-    """
-
-    def __init__(self, crazyflie=None):
-        """
-        Initialize the commander object. By default the commander is in
-        +-mode (not x-mode).
-        """
-        self._cf = crazyflie
-        self._x_mode = False
-
-    def set_client_xmode(self, enabled):
-        """
-        Enable/disable the client side X-mode. When enabled this recalculates
-        the setpoints before sending them to the Crazyflie.
-        """
-        self._x_mode = enabled
-
-    def send_setpoint(self, roll, pitch, yaw, thrust):
-        """
-        Send a new control setpoint for roll/pitch/yaw/thrust to the copter
-
-        The arguments roll/pitch/yaw/trust is the new setpoints that should
-        be sent to the copter
-        """
-        if thrust > 0xFFFF or thrust < 0:
-            raise ValueError("Thrust must be between 0 and 0xFFFF")
-
-        if self._x_mode:
-            roll, pitch = 0.707 * (roll - pitch), 0.707 * (roll + pitch)
-
-        pk = CRTPPacket()
-        pk.port = CRTPPort.COMMANDER
-        pk.data = struct.pack('<fffH', roll, -pitch, yaw, thrust)
-        self._cf.send_packet(pk)
diff --git a/src/cflib/cflib/crazyflie/console.py b/src/cflib/cflib/crazyflie/console.py
deleted file mode 100644
index 26b9f9fda5e478178b95dffa4308bcbc2a85d669..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crazyflie/console.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-"""
-Crazyflie console is used to receive characters printed using printf
-from the firmware.
-"""
-
-import struct
-from cflib.utils.callbacks import Caller
-from cflib.crtp.crtpstack import CRTPPort
-
-__author__ = 'Bitcraze AB'
-__all__ = ['Console']
-
-
-class Console:
-    """
-    Crazyflie console is used to receive characters printed using printf
-    from the firmware.
-    """
-
-    receivedChar = Caller()
-
-    def __init__(self, crazyflie):
-        """
-        Initialize the console and register it to receive data from the copter.
-        """
-        self.cf = crazyflie
-        self.cf.add_port_callback(CRTPPort.CONSOLE, self.incoming)
-
-    def incoming(self, packet):
-        """
-        Callback for data received from the copter.
-        """
-        # This might be done prettier ;-)
-        console_text = packet.data.decode("UTF-8")
-
-        self.receivedChar.call(console_text)
diff --git a/src/cflib/cflib/crazyflie/log.py b/src/cflib/cflib/crazyflie/log.py
deleted file mode 100644
index 27a8c2e5acc69d3d623b78aedf65c77a31fef892..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crazyflie/log.py
+++ /dev/null
@@ -1,557 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-Enables logging of variables from the Crazyflie.
-
-When a Crazyflie is connected it's possible to download a TableOfContent of all
-the variables that can be logged. Using this it's possible to add logging
-configurations where selected variables are sent to the client at a
-specified period.
-
-Terminology:
-  Log configuration - A configuration with a period and a number of variables
-                      that are present in the TOC.
-  Stored as         - The size and type of the variable as declared in the
-                      Crazyflie firmware
-  Fetch as          - The size and type that a variable should be fetched as.
-                      This does not have to be the same as the size and type
-                      it's stored as.
-
-States of a configuration:
-  Created on host - When a configuration is created the contents is checked
-                    so that all the variables are present in the TOC. If not
-                    then the configuration cannot be created.
-  Created on CF   - When the configuration is deemed valid it is added to the
-                    Crazyflie. At this time the memory constraint is checked
-                    and the status returned.
-  Started on CF   - Any added block that is not started can be started. Once
-                    started the Crazyflie will send back logdata periodically
-                    according to the specified period when it's created.
-  Stopped on CF   - Any started configuration can be stopped. The memory taken
-                    by the configuration on the Crazyflie is NOT freed, the
-                    only effect is that the Crazyflie will stop sending
-                    logdata back to the host.
-  Deleted on CF   - Any block that is added can be deleted. When this is done
-                    the memory taken by the configuration is freed on the
-                    Crazyflie. The configuration will have to be re-added to
-                    be used again.
-"""
-
-import struct
-import errno
-import sys
-from cflib.crtp.crtpstack import CRTPPacket, CRTPPort
-from cflib.utils.callbacks import Caller
-from .toc import Toc, TocFetcher
-import logging
-
-__author__ = 'Bitcraze AB'
-__all__ = ['Log', 'LogTocElement']
-
-# Channels used for the logging port
-CHAN_TOC = 0
-CHAN_SETTINGS = 1
-CHAN_LOGDATA = 2
-
-# Commands used when accessing the Table of Contents
-CMD_TOC_ELEMENT = 0
-CMD_TOC_INFO = 1
-
-# Commands used when accessing the Log configurations
-CMD_CREATE_BLOCK = 0
-CMD_APPEND_BLOCK = 1
-CMD_DELETE_BLOCK = 2
-CMD_START_LOGGING = 3
-CMD_STOP_LOGGING = 4
-CMD_RESET_LOGGING = 5
-
-# Possible states when receiving TOC
-IDLE = "IDLE"
-GET_TOC_INF = "GET_TOC_INFO"
-GET_TOC_ELEMENT = "GET_TOC_ELEMENT"
-
-# The max size of a CRTP packet payload
-MAX_LOG_DATA_PACKET_SIZE = 30
-
-
-logger = logging.getLogger(__name__)
-
-
-class LogVariable():
-    """A logging variable"""
-
-    TOC_TYPE = 0
-    MEM_TYPE = 1
-
-    def __init__(self, name="", fetchAs="uint8_t", varType=TOC_TYPE,
-                 storedAs="", address=0):
-        self.name = name
-        self.fetch_as = LogTocElement.get_id_from_cstring(fetchAs)
-        if (len(storedAs) == 0):
-            self.stored_as = self.fetch_as
-        else:
-            self.stored_as = LogTocElement.get_id_from_cstring(storedAs)
-        self.address = address
-        self.type = varType
-        self.stored_as_string = storedAs
-        self.fetch_as_string = fetchAs
-
-    def is_toc_variable(self):
-        """
-        Return true if the variable should be in the TOC, false if raw memory
-        variable
-        """
-        return self.type == LogVariable.TOC_TYPE
-
-    def get_storage_and_fetch_byte(self):
-        """Return what the variable is stored as and fetched as"""
-        return (self.fetch_as | (self.stored_as << 4))
-
-    def __str__(self):
-        return ("LogVariable: name=%s, store=%s, fetch=%s" %
-                (self.name, LogTocElement.get_cstring_from_id(self.stored_as),
-                 LogTocElement.get_cstring_from_id(self.fetch_as)))
-
-
-class LogConfig(object):
-    """Representation of one log configuration that enables logging
-    from the Crazyflie"""
-    _config_id_counter = 1
-
-    def __init__(self, name, period_in_ms):
-        """Initialize the entry"""
-        self.data_received_cb = Caller()
-        self.error_cb = Caller()
-        self.started_cb = Caller()
-        self.added_cb = Caller()
-        self.err_no = 0
-
-        self.id = LogConfig._config_id_counter
-        LogConfig._config_id_counter = (LogConfig._config_id_counter + 1) % 255
-        self.cf = None
-        self.period = int(period_in_ms / 10)
-        self.period_in_ms = period_in_ms
-        self._added = False
-        self._started = False
-        self.valid = False
-        self.variables = []
-        self.default_fetch_as = []
-        self.name = name
-
-    def add_variable(self, name, fetch_as=None):
-        """Add a new variable to the configuration.
-
-        name - Complete name of the variable in the form group.name
-        fetch_as - String representation of the type the variable should be
-                   fetched as (i.e uint8_t, float, FP16, etc)
-
-        If no fetch_as type is supplied, then the stored as type will be used
-        (i.e the type of the fetched variable is the same as it's stored in the
-        Crazyflie)."""
-        if fetch_as:
-            self.variables.append(LogVariable(name, fetch_as))
-        else:
-            # We cannot determine the default type until we have connected. So
-            # save the name and we will add these once we are connected.
-            self.default_fetch_as.append(name)
-
-    def add_memory(self, name, fetch_as, stored_as, address):
-        """Add a raw memory position to log.
-
-        name - Arbitrary name of the variable
-        fetch_as - String representation of the type of the data the memory
-                   should be fetch as (i.e uint8_t, float, FP16)
-        stored_as - String representation of the type the data is stored as
-                    in the Crazyflie
-        address - The address of the data
-        """
-        self.variables.append(LogVariable(name, fetch_as, LogVariable.MEM_TYPE,
-                                          stored_as, address))
-
-    def _set_added(self, added):
-        if added != self._added:
-            self.added_cb.call(self, added)
-        self._added = added
-
-    def _get_added(self):
-        return self._added
-
-    def _set_started(self, started):
-        if started != self._started:
-            self.started_cb.call(self, started)
-        self._started = started
-
-    def _get_started(self):
-        return self._started
-
-    added = property(_get_added, _set_added)
-    started = property(_get_started, _set_started)
-
-    def create(self):
-        """Save the log configuration in the Crazyflie"""
-        pk = CRTPPacket()
-        pk.set_header(5, CHAN_SETTINGS)
-        pk.data = (CMD_CREATE_BLOCK, self.id)
-        for var in self.variables:
-            if (var.is_toc_variable() is False):  # Memory location
-                logger.debug("Logging to raw memory %d, 0x%04X",
-                             var.get_storage_and_fetch_byte(), var.address)
-                pk.data.append(struct.pack('<B',
-                                           var.get_storage_and_fetch_byte()))
-                pk.data.append(struct.pack('<I', var.address))
-            else:  # Item in TOC
-                logger.debug("Adding %s with id=%d and type=0x%02X",
-                             var.name,
-                             self.cf.log.toc.get_element_id(
-                                 var.name), var.get_storage_and_fetch_byte())
-                pk.data.append(var.get_storage_and_fetch_byte())
-                pk.data.append(self.cf.log.toc.get_element_id(var.name))
-        logger.debug("Adding log block id {}".format(self.id))
-        self.cf.send_packet(pk, expected_reply=(CMD_CREATE_BLOCK, self.id))
-
-    def start(self):
-        """Start the logging for this entry"""
-        if (self.cf.link is not None):
-            if (self._added is False):
-                self.create()
-                logger.debug("First time block is started, add block")
-            else:
-                logger.debug("Block already registered, starting logging"
-                             " for id=%d", self.id)
-                pk = CRTPPacket()
-                pk.set_header(5, CHAN_SETTINGS)
-                pk.data = (CMD_START_LOGGING, self.id, self.period)
-                self.cf.send_packet(pk, expected_reply=(
-                    CMD_START_LOGGING, self.id))
-
-    def stop(self):
-        """Stop the logging for this entry"""
-        if (self.cf.link is not None):
-            if (self.id is None):
-                logger.warning("Stopping block, but no block registered")
-            else:
-                logger.debug("Sending stop logging for block id=%d", self.id)
-                pk = CRTPPacket()
-                pk.set_header(5, CHAN_SETTINGS)
-                pk.data = (CMD_STOP_LOGGING, self.id)
-                self.cf.send_packet(
-                    pk, expected_reply=(CMD_STOP_LOGGING, self.id))
-
-    def delete(self):
-        """Delete this entry in the Crazyflie"""
-        if (self.cf.link is not None):
-            if (self.id is None):
-                logger.warning("Delete block, but no block registered")
-            else:
-                logger.debug("LogEntry: Sending delete logging for block id=%d"
-                             % self.id)
-                pk = CRTPPacket()
-                pk.set_header(5, CHAN_SETTINGS)
-                pk.data = (CMD_DELETE_BLOCK, self.id)
-                self.cf.send_packet(
-                    pk, expected_reply=(CMD_DELETE_BLOCK, self.id))
-
-    def unpack_log_data(self, log_data, timestamp):
-        """Unpack received logging data so it represent real values according
-        to the configuration in the entry"""
-        ret_data = {}
-        data_index = 0
-        for var in self.variables:
-            size = LogTocElement.get_size_from_id(var.fetch_as)
-            name = var.name
-            unpackstring = LogTocElement.get_unpack_string_from_id(
-                var.fetch_as)
-            value = struct.unpack(
-                unpackstring, log_data[data_index:data_index + size])[0]
-            data_index += size
-            ret_data[name] = value
-        self.data_received_cb.call(timestamp, ret_data, self)
-
-
-class LogTocElement:
-    """An element in the Log TOC."""
-    types = {0x01: ("uint8_t", '<B', 1),
-             0x02: ("uint16_t", '<H', 2),
-             0x03: ("uint32_t", '<L', 4),
-             0x04: ("int8_t", '<b', 1),
-             0x05: ("int16_t", '<h', 2),
-             0x06: ("int32_t", '<i', 4),
-             0x08: ("FP16", '<h', 2),
-             0x07: ("float", '<f', 4)}
-
-    @staticmethod
-    def get_id_from_cstring(name):
-        """Return variable type id given the C-storage name"""
-        for key in list(LogTocElement.types.keys()):
-            if (LogTocElement.types[key][0] == name):
-                return key
-        raise KeyError("Type [%s] not found in LogTocElement.types!" % name)
-
-    @staticmethod
-    def get_cstring_from_id(ident):
-        """Return the C-storage name given the variable type id"""
-        try:
-            return LogTocElement.types[ident][0]
-        except KeyError:
-            raise KeyError("Type [%d] not found in LogTocElement.types"
-                           "!" % ident)
-
-    @staticmethod
-    def get_size_from_id(ident):
-        """Return the size in bytes given the variable type id"""
-        try:
-            return LogTocElement.types[ident][2]
-        except KeyError:
-            raise KeyError("Type [%d] not found in LogTocElement.types"
-                           "!" % ident)
-
-    @staticmethod
-    def get_unpack_string_from_id(ident):
-        """Return the Python unpack string given the variable type id"""
-        try:
-            return LogTocElement.types[ident][1]
-        except KeyError:
-            raise KeyError(
-                "Type [%d] not found in LogTocElement.types!" % ident)
-
-    def __init__(self, data=None):
-        """TocElement creator. Data is the binary payload of the element."""
-
-        if (data):
-            naming = data[2:]
-            zt = bytearray((0, ))
-            self.group = naming[:naming.find(zt)].decode("ISO-8859-1")
-            self.name = naming[naming.find(zt) + 1:-1].decode("ISO-8859-1")
-
-            self.ident = data[0]
-
-            self.ctype = LogTocElement.get_cstring_from_id(data[1])
-            self.pytype = LogTocElement.get_unpack_string_from_id(data[1])
-
-            self.access = data[1] & 0x10
-
-
-class Log():
-    """Create log configuration"""
-
-    # These codes can be decoded using os.stderror, but
-    # some of the text messages will look very strange
-    # in the UI, so they are redefined here
-    _err_codes = {
-        errno.ENOMEM: "No more memory available",
-        errno.ENOEXEC: "Command not found",
-        errno.ENOENT: "No such block id",
-        errno.E2BIG: "Block too large",
-        errno.EEXIST: "Block already exists"
-    }
-
-    def __init__(self, crazyflie=None):
-        self.log_blocks = []
-        # Called with newly created blocks
-        self.block_added_cb = Caller()
-
-        self.cf = crazyflie
-        self.toc = None
-        self.cf.add_port_callback(CRTPPort.LOGGING, self._new_packet_cb)
-
-        self.toc_updated = Caller()
-        self.state = IDLE
-        self.fake_toc_crc = 0xDEADBEEF
-
-        self._refresh_callback = None
-        self._toc_cache = None
-
-    def add_config(self, logconf):
-        """Add a log configuration to the logging framework.
-
-        When doing this the contents of the log configuration will be validated
-        and listeners for new log configurations will be notified. When
-        validating the configuration the variables are checked against the TOC
-        to see that they actually exist. If they don't then the configuration
-        cannot be used. Since a valid TOC is required, a Crazyflie has to be
-        connected when calling this method, otherwise it will fail."""
-
-        if not self.cf.link:
-            logger.error("Cannot add configs without being connected to a "
-                         "Crazyflie!")
-            return
-
-        # If the log configuration contains variables that we added without
-        # type (i.e we want the stored as type for fetching as well) then
-        # resolve this now and add them to the block again.
-        for name in logconf.default_fetch_as:
-            var = self.toc.get_element_by_complete_name(name)
-            if not var:
-                logger.warning(
-                    "%s not in TOC, this block cannot be used!", name)
-                logconf.valid = False
-                raise KeyError("Variable {} not in TOC".format(name))
-            # Now that we know what type this variable has, add it to the log
-            # config again with the correct type
-            logconf.add_variable(name, var.ctype)
-
-        # Now check that all the added variables are in the TOC and that
-        # the total size constraint of a data packet with logging data is
-        # not
-        size = 0
-        for var in logconf.variables:
-            size += LogTocElement.get_size_from_id(var.fetch_as)
-            # Check that we are able to find the variable in the TOC so
-            # we can return error already now and not when the config is sent
-            if var.is_toc_variable():
-                if (self.toc.get_element_by_complete_name(var.name) is None):
-                    logger.warning(
-                        "Log: %s not in TOC, this block cannot be used!",
-                        var.name)
-                    logconf.valid = False
-                    raise KeyError("Variable {} not in TOC".format(var.name))
-
-        if (size <= MAX_LOG_DATA_PACKET_SIZE and
-                (logconf.period > 0 and logconf.period < 0xFF)):
-            logconf.valid = True
-            logconf.cf = self.cf
-            self.log_blocks.append(logconf)
-            self.block_added_cb.call(logconf)
-        else:
-            logconf.valid = False
-            raise AttributeError(
-                "The log configuration is too large or has an invalid "
-                "parameter")
-
-    def refresh_toc(self, refresh_done_callback, toc_cache):
-        """Start refreshing the table of loggale variables"""
-
-        self._toc_cache = toc_cache
-        self._refresh_callback = refresh_done_callback
-        self.toc = None
-
-        pk = CRTPPacket()
-        pk.set_header(CRTPPort.LOGGING, CHAN_SETTINGS)
-        pk.data = (CMD_RESET_LOGGING,)
-        self.cf.send_packet(pk, expected_reply=(CMD_RESET_LOGGING,))
-
-    def _find_block(self, id):
-        for block in self.log_blocks:
-            if block.id == id:
-                return block
-        return None
-
-    def _new_packet_cb(self, packet):
-        """Callback for newly arrived packets with TOC information"""
-        chan = packet.channel
-        cmd = packet.data[0]
-        payload = packet.data[1:]
-
-        if (chan == CHAN_SETTINGS):
-            id = payload[0]
-            error_status = payload[1]
-            block = self._find_block(id)
-            if (cmd == CMD_CREATE_BLOCK):
-                if (block is not None):
-                    if error_status == 0 or error_status == errno.EEXIST:
-                        if not block.added:
-                            logger.debug("Have successfully added id=%d", id)
-
-                            pk = CRTPPacket()
-                            pk.set_header(5, CHAN_SETTINGS)
-                            pk.data = (CMD_START_LOGGING, id, block.period)
-                            self.cf.send_packet(pk, expected_reply=(
-                                CMD_START_LOGGING, id))
-                            block.added = True
-                    else:
-                        msg = self._err_codes[error_status]
-                        logger.warning("Error %d when adding id=%d (%s)",
-                                       error_status, id, msg)
-                        block.err_no = error_status
-                        block.added_cb.call(False)
-                        block.error_cb.call(block, msg)
-
-                else:
-                    logger.warning("No LogEntry to assign block to !!!")
-            if (cmd == CMD_START_LOGGING):
-                if (error_status == 0x00):
-                    logger.info("Have successfully started logging for id=%d",
-                                id)
-                    if block:
-                        block.started = True
-
-                else:
-                    msg = self._err_codes[error_status]
-                    logger.warning("Error %d when starting id=%d (%s)",
-                                   error_status, id, msg)
-                    if block:
-                        block.err_no = error_status
-                        block.started_cb.call(self, False)
-                        # This is a temporary fix, we are adding a new issue
-                        # for this. For some reason we get an error back after
-                        # the block has been started and added. This will show
-                        # an error in the UI, but everything is still working.
-                        # block.error_cb.call(block, msg)
-
-            if (cmd == CMD_STOP_LOGGING):
-                if (error_status == 0x00):
-                    logger.info("Have successfully stopped logging for id=%d",
-                                id)
-                    if block:
-                        block.started = False
-
-            if (cmd == CMD_DELETE_BLOCK):
-                # Accept deletion of a block that isn't added. This could
-                # happen due to timing (i.e add/start/delete in fast sequence)
-                if error_status == 0x00 or error_status == errno.ENOENT:
-                    logger.info("Have successfully deleted id=%d", id)
-                    if block:
-                        block.started = False
-                        block.added = False
-
-            if (cmd == CMD_RESET_LOGGING):
-                # Guard against multiple responses due to re-sending
-                if not self.toc:
-                    logger.debug("Logging reset, continue with TOC download")
-                    self.log_blocks = []
-
-                    self.toc = Toc()
-                    toc_fetcher = TocFetcher(self.cf, LogTocElement,
-                                             CRTPPort.LOGGING,
-                                             self.toc, self._refresh_callback,
-                                             self._toc_cache)
-                    toc_fetcher.start()
-
-        if (chan == CHAN_LOGDATA):
-            chan = packet.channel
-            id = packet.data[0]
-            block = self._find_block(id)
-            timestamps = struct.unpack("<BBB", packet.data[1:4])
-            timestamp = (
-                timestamps[0] | timestamps[1] << 8 | timestamps[2] << 16)
-            logdata = packet.data[4:]
-            if (block is not None):
-                block.unpack_log_data(logdata, timestamp)
-            else:
-                logger.warning("Error no LogEntry to handle id=%d", id)
diff --git a/src/cflib/cflib/crazyflie/mem.py b/src/cflib/cflib/crazyflie/mem.py
deleted file mode 100644
index e6cdd906ac06527a3c1c084dee269fe1a2f635a4..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crazyflie/mem.py
+++ /dev/null
@@ -1,844 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2014 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-Enables flash access to the Crazyflie.
-
-"""
-
-import struct
-import errno
-import sys
-from threading import Lock
-from cflib.crtp.crtpstack import CRTPPacket, CRTPPort
-from cflib.utils.callbacks import Caller
-from binascii import crc32
-import binascii
-import logging
-from functools import reduce
-
-__author__ = 'Bitcraze AB'
-__all__ = ['Memory', 'MemoryElement']
-
-# Channels used for the logging port
-CHAN_INFO = 0
-CHAN_READ = 1
-CHAN_WRITE = 2
-
-# Commands used when accessing the Settings port
-CMD_INFO_VER = 0
-CMD_INFO_NBR = 1
-CMD_INFO_DETAILS = 2
-
-# The max size of a CRTP packet payload
-MAX_LOG_DATA_PACKET_SIZE = 30
-
-if sys.version_info < (3,):
-    EEPROM_TOKEN = "0xBC"
-else:
-    EEPROM_TOKEN = b"0xBC"
-
-logger = logging.getLogger(__name__)
-
-
-class MemoryElement(object):
-    """A memory """
-
-    TYPE_I2C = 0
-    TYPE_1W = 1
-    TYPE_DRIVER_LED = 0x10
-
-    def __init__(self, id, type, size, mem_handler):
-        """Initialize the element with default values"""
-        self.id = id
-        self.type = type
-        self.size = size
-        self.mem_handler = mem_handler
-
-    @staticmethod
-    def type_to_string(t):
-        """Get string representation of memory type"""
-        if t == MemoryElement.TYPE_I2C:
-            return "I2C"
-        if t == MemoryElement.TYPE_1W:
-            return "1-wire"
-        if t == MemoryElement.TYPE_DRIVER_LED:
-            return "LED driver"
-        return "Unknown"
-
-    def new_data(self, mem, addr, data):
-        logger.info("New data, but not OW mem")
-
-    def __str__(self):
-        """Generate debug string for memory"""
-        return ("Memory: id={}, type={}, size={}".format(
-            self.id, MemoryElement.type_to_string(self.type), self.size))
-
-
-class LED:
-    """Used to set color/intensity of one LED in the LED-ring"""
-
-    def __init__(self):
-        """Initialize to off"""
-        self.r = 0
-        self.g = 0
-        self.b = 0
-        self.intensity = 100
-
-    def set(self, r, g, b, intensity=None):
-        """Set the R/G/B and optionally intensity in one call"""
-        self.r = r
-        self.g = g
-        self.b = b
-        if intensity:
-            self.intensity = intensity
-
-
-class LEDDriverMemory(MemoryElement):
-    """Memory interface for using the LED-ring mapped memory for setting RGB
-       values for all the LEDs in the ring"""
-
-    def __init__(self, id, type, size, mem_handler):
-        """Initialize with 12 LEDs"""
-        super(LEDDriverMemory, self).__init__(id=id, type=type, size=size,
-                                              mem_handler=mem_handler)
-        self._update_finished_cb = None
-        self._write_finished_cb = None
-
-        self.leds = []
-        for i in range(12):
-            self.leds.append(LED())
-
-    def new_data(self, mem, addr, data):
-        """Callback for when new memory data has been fetched"""
-        if mem.id == self.id:
-            logger.info("Got new data from the LED driver, but we don't care.")
-
-    def write_data(self, write_finished_cb):
-        """Write the saved LED-ring data to the Crazyflie"""
-        self._write_finished_cb = write_finished_cb
-        data = bytearray()
-        for led in self.leds:
-            # In order to fit all the LEDs in one radio packet RGB565 is used
-            # to compress the colors. The calculations below converts 3 bytes
-            # RGB into 2 bytes RGB565. Then shifts the value of each color to
-            # LSB, applies the intensity and shifts them back for correct
-            # alignment on 2 bytes.
-            R5 = ((int)((((int(led.r) & 0xFF) * 249 + 1014) >> 11) & 0x1F) *
-                  led.intensity / 100)
-            G6 = ((int)((((int(led.g) & 0xFF) * 253 + 505) >> 10) & 0x3F) *
-                  led.intensity / 100)
-            B5 = ((int)((((int(led.b) & 0xFF) * 249 + 1014) >> 11) & 0x1F) *
-                  led.intensity / 100)
-            tmp = (int(R5) << 11) | (int(G6) << 5) | (int(B5) << 0)
-            data += bytearray((tmp >> 8, tmp & 0xFF))
-        self.mem_handler.write(self, 0x00, data, flush_queue=True)
-
-    def update(self, update_finished_cb):
-        """Request an update of the memory content"""
-        if not self._update_finished_cb:
-            self._update_finished_cb = update_finished_cb
-            self.valid = False
-            logger.info("Updating content of memory {}".format(self.id))
-            # Start reading the header
-            self.mem_handler.read(self, 0, 16)
-
-    def write_done(self, mem, addr):
-        if self._write_finished_cb and mem.id == self.id:
-            logger.info("Write to LED driver done")
-            self._write_finished_cb(self, addr)
-            self._write_finished_cb = None
-
-    def disconnect(self):
-        self._update_finished_cb = None
-        self._write_finished_cb = None
-
-
-class I2CElement(MemoryElement):
-
-    def __init__(self, id, type, size, mem_handler):
-        super(I2CElement, self).__init__(id=id, type=type, size=size,
-                                         mem_handler=mem_handler)
-        self._update_finished_cb = None
-        self._write_finished_cb = None
-        self.elements = {}
-        self.valid = False
-
-    def new_data(self, mem, addr, data):
-        """Callback for when new memory data has been fetched"""
-        if mem.id == self.id:
-            if addr == 0:
-                done = False
-                # Check for header
-                if data[0:4] == EEPROM_TOKEN:
-                    logger.info("Got new data: {}".format(data))
-                    [self.elements["version"],
-                     self.elements["radio_channel"],
-                     self.elements["radio_speed"],
-                     self.elements["pitch_trim"],
-                     self.elements["roll_trim"]] = struct.unpack("<BBBff",
-                                                                 data[4:15])
-                    if self.elements["version"] == 0:
-                        done = True
-                    elif self.elements["version"] == 1:
-                        self.datav0 = data
-                        self.mem_handler.read(self, 16, 5)
-                else:
-                    valid = False
-                    if self._update_finished_cb:
-                        self._update_finished_cb(self)
-                        self._update_finished_cb = None
-
-            if addr == 16:
-                [radio_address_upper, radio_address_lower] = struct.unpack(
-                    "<BI", self.datav0[15:16] + data[0:4])
-                self.elements["radio_address"] = int(
-                    radio_address_upper) << 32 | radio_address_lower
-
-                logger.info(self.elements)
-                data = self.datav0 + data
-                done = True
-
-            if done:
-                if self._checksum256(data[:len(data) - 1]) == \
-                        data[len(data) - 1]:
-                    self.valid = True
-                if self._update_finished_cb:
-                    self._update_finished_cb(self)
-                    self._update_finished_cb = None
-
-    def _checksum256(self, st):
-        return reduce(lambda x, y: x + y, list(st)) % 256
-
-    def write_data(self, write_finished_cb):
-        image = bytearray()
-        if self.elements["version"] == 0:
-            data = (
-                0x00, self.elements["radio_channel"],
-                self.elements["radio_speed"],
-                self.elements["pitch_trim"], self.elements["roll_trim"])
-            image += struct.pack("<BBBff", *data)
-        elif self.elements["version"] == 1:
-            data = (
-                0x01, self.elements["radio_channel"],
-                self.elements["radio_speed"],
-                self.elements["pitch_trim"], self.elements["roll_trim"],
-                self.elements["radio_address"] >> 32,
-                self.elements["radio_address"] & 0xFFFFFFFF)
-            image += struct.pack("<BBBffBI", *data)
-        # Adding some magic:
-        image = EEPROM_TOKEN + image
-        image += struct.pack("B", self._checksum256(image))
-
-        self._write_finished_cb = write_finished_cb
-
-        self.mem_handler.write(self, 0x00,
-                               struct.unpack("B" * len(image), image))
-
-    def update(self, update_finished_cb):
-        """Request an update of the memory content"""
-        if not self._update_finished_cb:
-            self._update_finished_cb = update_finished_cb
-            self.valid = False
-            logger.info("Updating content of memory {}".format(self.id))
-            # Start reading the header
-            self.mem_handler.read(self, 0, 16)
-
-    def write_done(self, mem, addr):
-        if self._write_finished_cb and mem.id == self.id:
-            self._write_finished_cb(self, addr)
-            self._write_finished_cb = None
-
-    def disconnect(self):
-        self._update_finished_cb = None
-        self._write_finished_cb = None
-
-
-class OWElement(MemoryElement):
-    """Memory class with extra functionality for 1-wire memories"""
-
-    element_mapping = {
-        1: "Board name",
-        2: "Board revision",
-        3: "Custom"
-    }
-
-    def __init__(self, id, type, size, addr, mem_handler):
-        """Initialize the memory with good defaults"""
-        super(OWElement, self).__init__(id=id, type=type, size=size,
-                                        mem_handler=mem_handler)
-        self.addr = addr
-
-        self.valid = False
-
-        self.vid = None
-        self.pid = None
-        self.name = None
-        self.pins = None
-        self.elements = {}
-
-        self._update_finished_cb = None
-        self._write_finished_cb = None
-
-        self._rev_element_mapping = {}
-        for key in list(OWElement.element_mapping.keys()):
-            self._rev_element_mapping[OWElement.element_mapping[key]] = key
-
-    def new_data(self, mem, addr, data):
-        """Callback for when new memory data has been fetched"""
-        if mem.id == self.id:
-            if addr == 0:
-                if self._parse_and_check_header(data[0:8]):
-                    if self._parse_and_check_elements(data[9:11]):
-                        self.valid = True
-                        self._update_finished_cb(self)
-                        self._update_finished_cb = None
-                    else:
-                        # We need to fetch the elements, find out the length
-                        (elem_ver, elem_len) = struct.unpack("BB", data[8:10])
-                        self.mem_handler.read(self, 8, elem_len + 3)
-                else:
-                    # Call the update if the CRC check of the header fails,
-                    # we're done here
-                    if self._update_finished_cb:
-                        self._update_finished_cb(self)
-                        self._update_finished_cb = None
-            elif addr == 0x08:
-                if self._parse_and_check_elements(data):
-                    self.valid = True
-                if self._update_finished_cb:
-                    self._update_finished_cb(self)
-                    self._update_finished_cb = None
-
-    def _parse_and_check_elements(self, data):
-        """
-        Parse and check the CRC and length of the elements part of the memory
-        """
-        (elem_ver, elem_len, crc) = (data[0], data[1], data[-1])
-        test_crc = crc32(data[:-1]) & 0x0ff
-        elem_data = data[2:-1]
-        if test_crc == crc:
-            while len(elem_data) > 0:
-                (eid, elen) = struct.unpack("BB", elem_data[:2])
-                self.elements[self.element_mapping[eid]] = \
-                    elem_data[2:2 + elen].decode("ISO-8859-1")
-                elem_data = elem_data[2 + elen:]
-            return True
-        return False
-
-    def write_done(self, mem, addr):
-        if self._write_finished_cb:
-            self._write_finished_cb(self, addr)
-            self._write_finished_cb = None
-
-    def write_data(self, write_finished_cb):
-        # First generate the header part
-        header_data = struct.pack("<BIBB", 0xEB, self.pins, self.vid, self.pid)
-        header_crc = crc32(header_data) & 0x0ff
-        header_data += struct.pack("B", header_crc)
-
-        # Now generate the elements part
-        elem = bytearray()
-        logger.info(list(self.elements.keys()))
-        for element in reversed(list(self.elements.keys())):
-            elem_string = self.elements[element]
-            # logger.info(">>>> {}".format(elem_string))
-            key_encoding = self._rev_element_mapping[element]
-            elem += struct.pack("BB", key_encoding, len(elem_string))
-            elem += bytearray(elem_string.encode("ISO-8859-1"))
-
-        elem_data = struct.pack("BB", 0x00, len(elem))
-        elem_data += elem
-        elem_crc = crc32(elem_data) & 0x0ff
-        elem_data += struct.pack("B", elem_crc)
-
-        data = header_data + elem_data
-
-        self.mem_handler.write(self, 0x00,
-                               struct.unpack("B" * len(data), data))
-
-        self._write_finished_cb = write_finished_cb
-
-    def update(self, update_finished_cb):
-        """Request an update of the memory content"""
-        if not self._update_finished_cb:
-            self._update_finished_cb = update_finished_cb
-            self.valid = False
-            logger.info("Updating content of memory {}".format(self.id))
-            # Start reading the header
-            self.mem_handler.read(self, 0, 11)
-
-    def _parse_and_check_header(self, data):
-        """Parse and check the CRC of the header part of the memory"""
-        # logger.info("Should parse header: {}".format(data))
-        (start, self.pins, self.vid, self.pid, crc) = struct.unpack("<BIBBB",
-                                                                    data)
-        test_crc = crc32(data[:-1]) & 0x0ff
-        if start == 0xEB and crc == test_crc:
-            return True
-        return False
-
-    def __str__(self):
-        """Generate debug string for memory"""
-        return ("OW {} ({:02X}:{:02X}): {}".format(
-            self.addr, self.vid, self.pid, self.elements))
-
-    def disconnect(self):
-        self._update_finished_cb = None
-        self._write_finished_cb = None
-
-
-class _ReadRequest:
-    """
-    Class used to handle memory reads that will split up the read in multiple
-    packets in necessary
-    """
-    MAX_DATA_LENGTH = 20
-
-    def __init__(self, mem, addr, length, cf):
-        """Initialize the object with good defaults"""
-        self.mem = mem
-        self.addr = addr
-        self._bytes_left = length
-        self.data = bytearray()
-        self.cf = cf
-
-        self._current_addr = addr
-
-    def start(self):
-        """Start the fetching of the data"""
-        self._request_new_chunk()
-
-    def resend(self):
-        logger.info("Sending write again...")
-        self._request_new_chunk()
-
-    def _request_new_chunk(self):
-        """
-        Called to request a new chunk of data to be read from the Crazyflie
-        """
-        # Figure out the length of the next request
-        new_len = self._bytes_left
-        if new_len > _ReadRequest.MAX_DATA_LENGTH:
-            new_len = _ReadRequest.MAX_DATA_LENGTH
-
-        logger.info("Requesting new chunk of {}bytes at 0x{:X}".format(
-            new_len, self._current_addr))
-
-        # Request the data for the next address
-        pk = CRTPPacket()
-        pk.set_header(CRTPPort.MEM, CHAN_READ)
-        pk.data = struct.pack("<BIB", self.mem.id, self._current_addr, new_len)
-        reply = struct.unpack("<BBBBB", pk.data[:-1])
-        self.cf.send_packet(pk, expected_reply=reply, timeout=1)
-
-    def add_data(self, addr, data):
-        """Callback when data is received from the Crazyflie"""
-        data_len = len(data)
-        if not addr == self._current_addr:
-            logger.warning(
-                "Address did not match when adding data to read request!")
-            return
-
-        # Add the data and calculate the next address to fetch
-        self.data += data
-        self._bytes_left -= data_len
-        self._current_addr += data_len
-
-        if self._bytes_left > 0:
-            self._request_new_chunk()
-            return False
-        else:
-            return True
-
-
-class _WriteRequest:
-    """
-    Class used to handle memory reads that will split up the read in multiple
-    packets in necessary
-    """
-    MAX_DATA_LENGTH = 25
-
-    def __init__(self, mem, addr, data, cf):
-        """Initialize the object with good defaults"""
-        self.mem = mem
-        self.addr = addr
-        self._bytes_left = len(data)
-        self._data = data
-        self.data = bytearray()
-        self.cf = cf
-
-        self._current_addr = addr
-
-        self._sent_packet = None
-        self._sent_reply = None
-
-        self._addr_add = 0
-
-    def start(self):
-        """Start the fetching of the data"""
-        self._write_new_chunk()
-
-    def resend(self):
-        logger.info("Sending write again...")
-        self.cf.send_packet(
-            self._sent_packet, expected_reply=self._sent_reply, timeout=1)
-
-    def _write_new_chunk(self):
-        """
-        Called to request a new chunk of data to be read from the Crazyflie
-        """
-        # Figure out the length of the next request
-        new_len = len(self._data)
-        if new_len > _WriteRequest.MAX_DATA_LENGTH:
-            new_len = _WriteRequest.MAX_DATA_LENGTH
-
-        logger.info("Writing new chunk of {}bytes at 0x{:X}".format(
-            new_len, self._current_addr))
-
-        data = self._data[:new_len]
-        self._data = self._data[new_len:]
-
-        pk = CRTPPacket()
-        pk.set_header(CRTPPort.MEM, CHAN_WRITE)
-        pk.data = struct.pack("<BI", self.mem.id, self._current_addr)
-        # Create a tuple used for matching the reply using id and address
-        reply = struct.unpack("<BBBBB", pk.data)
-        self._sent_reply = reply
-        # Add the data
-        pk.data += struct.pack("B" * len(data), *data)
-        self._sent_packet = pk
-        self.cf.send_packet(pk, expected_reply=reply, timeout=1)
-
-        self._addr_add = len(data)
-
-    def write_done(self, addr):
-        """Callback when data is received from the Crazyflie"""
-        if not addr == self._current_addr:
-            logger.warning(
-                "Address did not match when adding data to read request!")
-            return
-
-        if len(self._data) > 0:
-            self._current_addr += self._addr_add
-            self._write_new_chunk()
-            return False
-        else:
-            logger.info("This write request is done")
-            return True
-
-
-class Memory():
-    """Access memories on the Crazyflie"""
-
-    # These codes can be decoded using os.stderror, but
-    # some of the text messages will look very strange
-    # in the UI, so they are redefined here
-    _err_codes = {
-        errno.ENOMEM: "No more memory available",
-        errno.ENOEXEC: "Command not found",
-        errno.ENOENT: "No such block id",
-        errno.E2BIG: "Block too large",
-        errno.EEXIST: "Block already exists"
-    }
-
-    def __init__(self, crazyflie=None):
-        """Instantiate class and connect callbacks"""
-        self.mems = []
-        # Called when new memories have been added
-        self.mem_added_cb = Caller()
-        # Called when new data has been read
-        self.mem_read_cb = Caller()
-
-        self.mem_write_cb = Caller()
-
-        self.cf = crazyflie
-        self.cf.add_port_callback(CRTPPort.MEM, self._new_packet_cb)
-
-        self._refresh_callback = None
-        self._fetch_id = 0
-        self.nbr_of_mems = 0
-        self._ow_mem_fetch_index = 0
-        self._elem_data = ()
-        self._read_requests = {}
-        self._read_requests_lock = Lock()
-        self._write_requests = {}
-        self._write_requests_lock = Lock()
-        self._ow_mems_left_to_update = []
-
-        self._getting_count = False
-
-    def _mem_update_done(self, mem):
-        """
-        Callback from each individual memory (only 1-wire) when reading of
-        header/elements are done
-        """
-        if mem.id in self._ow_mems_left_to_update:
-            self._ow_mems_left_to_update.remove(mem.id)
-
-        logger.info(mem)
-
-        if len(self._ow_mems_left_to_update) == 0:
-            if self._refresh_callback:
-                self._refresh_callback()
-                self._refresh_callback = None
-
-    def get_mem(self, id):
-        """Fetch the memory with the supplied id"""
-        for m in self.mems:
-            if m.id == id:
-                return m
-
-        return None
-
-    def get_mems(self, type):
-        """Fetch all the memories of the supplied type"""
-        ret = ()
-        for m in self.mems:
-            if m.type == type:
-                ret += (m,)
-
-        return ret
-
-    def ow_search(self, vid=0xBC, pid=None, name=None):
-        """Search for specific memory id/name and return it"""
-        for m in self.get_mems(MemoryElement.TYPE_1W):
-            if pid and m.pid == pid or name and m.name == name:
-                return m
-
-        return None
-
-    def write(self, memory, addr, data, flush_queue=False):
-        """Write the specified data to the given memory at the given address"""
-        wreq = _WriteRequest(memory, addr, data, self.cf)
-        if memory.id not in self._write_requests:
-            self._write_requests[memory.id] = []
-
-        # Workaround until we secure the uplink and change messages for
-        # mems to non-blocking
-        self._write_requests_lock.acquire()
-        if flush_queue:
-            self._write_requests[memory.id] = self._write_requests[
-                memory.id][:1]
-        self._write_requests[memory.id].insert(len(self._write_requests), wreq)
-        if len(self._write_requests[memory.id]) == 1:
-            wreq.start()
-        self._write_requests_lock.release()
-
-        return True
-
-    def read(self, memory, addr, length):
-        """
-        Read the specified amount of bytes from the given memory at the given
-        address
-        """
-        if memory.id in self._read_requests:
-            logger.warning("There is already a read operation ongoing for "
-                           "memory id {}".format(memory.id))
-            return False
-
-        rreq = _ReadRequest(memory, addr, length, self.cf)
-        self._read_requests[memory.id] = rreq
-
-        rreq.start()
-
-        return True
-
-    def refresh(self, refresh_done_callback):
-        """Start fetching all the detected memories"""
-        self._refresh_callback = refresh_done_callback
-        self._fetch_id = 0
-        for m in self.mems:
-            try:
-                self.mem_read_cb.remove_callback(m.new_data)
-                m.disconnect()
-            except Exception as e:
-                logger.info(
-                    "Error when removing memory after update: {}".format(e))
-        self.mems = []
-
-        self.nbr_of_mems = 0
-        self._getting_count = False
-
-        logger.info("Requesting number of memories")
-        pk = CRTPPacket()
-        pk.set_header(CRTPPort.MEM, CHAN_INFO)
-        pk.data = (CMD_INFO_NBR,)
-        self.cf.send_packet(pk, expected_reply=(CMD_INFO_NBR,))
-
-    def _new_packet_cb(self, packet):
-        """Callback for newly arrived packets for the memory port"""
-        chan = packet.channel
-        cmd = packet.data[0]
-        payload = packet.data[1:]
-
-        if chan == CHAN_INFO:
-            if cmd == CMD_INFO_NBR:
-                self.nbr_of_mems = payload[0]
-                logger.info("{} memories found".format(self.nbr_of_mems))
-
-                # Start requesting information about the memories,
-                # if there are any...
-                if self.nbr_of_mems > 0:
-                    if not self._getting_count:
-                        self._getting_count = True
-                        logger.info("Requesting first id")
-                        pk = CRTPPacket()
-                        pk.set_header(CRTPPort.MEM, CHAN_INFO)
-                        pk.data = (CMD_INFO_DETAILS, 0)
-                        self.cf.send_packet(pk, expected_reply=(
-                            CMD_INFO_DETAILS, 0))
-                else:
-                    self._refresh_callback()
-
-            if cmd == CMD_INFO_DETAILS:
-
-                # Did we get a good reply, otherwise try again:
-                if len(payload) < 5:
-                    # Workaround for 1-wire bug when memory is detected
-                    # but updating the info crashes the communication with
-                    # the 1-wire. Fail by saying we only found 1 memory
-                    # (the I2C).
-                    logger.error(
-                        "-------->Got good count, but no info on mem!")
-                    self.nbr_of_mems = 1
-                    if self._refresh_callback:
-                        self._refresh_callback()
-                        self._refresh_callback = None
-                    return
-
-                # Create information about a new memory
-                # Id - 1 byte
-                mem_id = payload[0]
-                # Type - 1 byte
-                mem_type = payload[1]
-                # Size 4 bytes (as addr)
-                mem_size = struct.unpack("I", payload[2:6])[0]
-                # Addr (only valid for 1-wire?)
-                mem_addr_raw = struct.unpack("B" * 8, payload[6:14])
-                mem_addr = ""
-                for m in mem_addr_raw:
-                    mem_addr += "{:02X}".format(m)
-
-                if (not self.get_mem(mem_id)):
-                    if mem_type == MemoryElement.TYPE_1W:
-                        mem = OWElement(id=mem_id, type=mem_type,
-                                        size=mem_size,
-                                        addr=mem_addr, mem_handler=self)
-                        self.mem_read_cb.add_callback(mem.new_data)
-                        self.mem_write_cb.add_callback(mem.write_done)
-                        self._ow_mems_left_to_update.append(mem.id)
-                    elif mem_type == MemoryElement.TYPE_I2C:
-                        mem = I2CElement(id=mem_id, type=mem_type,
-                                         size=mem_size,
-                                         mem_handler=self)
-                        self.mem_read_cb.add_callback(mem.new_data)
-                        self.mem_write_cb.add_callback(mem.write_done)
-                    elif mem_type == MemoryElement.TYPE_DRIVER_LED:
-                        mem = LEDDriverMemory(id=mem_id, type=mem_type,
-                                              size=mem_size, mem_handler=self)
-                        logger.info(mem)
-                        self.mem_read_cb.add_callback(mem.new_data)
-                        self.mem_write_cb.add_callback(mem.write_done)
-                    else:
-                        mem = MemoryElement(id=mem_id, type=mem_type,
-                                            size=mem_size, mem_handler=self)
-                        logger.info(mem)
-                    self.mems.append(mem)
-                    self.mem_added_cb.call(mem)
-                    # logger.info(mem)
-
-                    self._fetch_id = mem_id + 1
-
-                if self.nbr_of_mems - 1 >= self._fetch_id:
-                    logger.info(
-                        "Requesting information about memory {}".format(
-                            self._fetch_id))
-                    pk = CRTPPacket()
-                    pk.set_header(CRTPPort.MEM, CHAN_INFO)
-                    pk.data = (CMD_INFO_DETAILS, self._fetch_id)
-                    self.cf.send_packet(pk, expected_reply=(
-                        CMD_INFO_DETAILS, self._fetch_id))
-                else:
-                    logger.info(
-                        "Done getting all the memories, start reading the OWs")
-                    ows = self.get_mems(MemoryElement.TYPE_1W)
-                    # If there are any OW mems start reading them, otherwise
-                    # we are done
-                    for ow_mem in self.get_mems(MemoryElement.TYPE_1W):
-                        ow_mem.update(self._mem_update_done)
-                    if len(self.get_mems(MemoryElement.TYPE_1W)) == 0:
-                        if self._refresh_callback:
-                            self._refresh_callback()
-                            self._refresh_callback = None
-
-        if chan == CHAN_WRITE:
-            id = cmd
-            (addr, status) = struct.unpack("<IB", payload[0:5])
-            logger.info(
-                "WRITE: Mem={}, addr=0x{:X}, status=0x{}".format(
-                    id, addr, status))
-            # Find the read request
-            if id in self._write_requests:
-                self._write_requests_lock.acquire()
-                wreq = self._write_requests[id][0]
-                if status == 0:
-                    if wreq.write_done(addr):
-                        # self._write_requests.pop(id, None)
-                        # Remove the first item
-                        self._write_requests[id].pop(0)
-                        self.mem_write_cb.call(wreq.mem, wreq.addr)
-
-                        # Get a new one to start (if there are any)
-                        if len(self._write_requests[id]) > 0:
-                            self._write_requests[id][0].start()
-
-                else:
-                    logger.info("Status {}: write resending...".format(status))
-                    wreq.resend()
-                self._write_requests_lock.release()
-
-        if chan == CHAN_READ:
-            id = cmd
-            (addr, status) = struct.unpack("<IB", payload[0:5])
-            data = struct.unpack("B" * len(payload[5:]), payload[5:])
-            logger.info("READ: Mem={}, addr=0x{:X}, status=0x{}, "
-                        "data={}".format(id, addr, status, data))
-            # Find the read request
-            if id in self._read_requests:
-                logger.info(
-                    "READING: We are still interested in request for "
-                    "mem {}".format(id))
-                rreq = self._read_requests[id]
-                if status == 0:
-                    if rreq.add_data(addr, payload[5:]):
-                        self._read_requests.pop(id, None)
-                        self.mem_read_cb.call(rreq.mem, rreq.addr, rreq.data)
-                else:
-                    logger.info("Status {}: resending...".format(status))
-                    rreq.resend()
diff --git a/src/cflib/cflib/crazyflie/param.py b/src/cflib/cflib/crazyflie/param.py
deleted file mode 100644
index ff828abefa247763c719d39ea294b2c9f67c7921..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crazyflie/param.py
+++ /dev/null
@@ -1,341 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-"""
-Enables reading/writing of parameter values to/from the Crazyflie.
-
-When a Crazyflie is connected it's possible to download a TableOfContent of all
-the parameters that can be written/read.
-
-"""
-import logging
-import struct
-import sys
-from threading import Lock
-from threading import Thread
-
-from cflib.crtp.crtpstack import CRTPPacket
-from cflib.crtp.crtpstack import CRTPPort
-from cflib.utils.callbacks import Caller
-
-from .toc import Toc
-from .toc import TocFetcher
-if sys.version_info < (3,):
-    from Queue import Queue
-else:
-    from queue import Queue
-
-
-__author__ = 'Bitcraze AB'
-__all__ = ['Param', 'ParamTocElement']
-
-logger = logging.getLogger(__name__)
-
-# Possible states
-IDLE = 0
-WAIT_TOC = 1
-WAIT_READ = 2
-WAIT_WRITE = 3
-
-TOC_CHANNEL = 0
-READ_CHANNEL = 1
-WRITE_CHANNEL = 2
-
-# TOC access command
-TOC_RESET = 0
-TOC_GETNEXT = 1
-TOC_GETCRC32 = 2
-
-
-# One element entry in the TOC
-class ParamTocElement:
-    """An element in the Log TOC."""
-
-    RW_ACCESS = 0
-    RO_ACCESS = 1
-
-    types = {0x08: ("uint8_t", '<B'),
-             0x09: ("uint16_t", '<H'),
-             0x0A: ("uint32_t", '<L'),
-             0x0B: ("uint64_t", '<Q'),
-             0x00: ("int8_t", '<b'),
-             0x01: ("int16_t", '<h'),
-             0x02: ("int32_t", '<i'),
-             0x03: ("int64_t", '<q'),
-             0x05: ("FP16", ''),
-             0x06: ("float", '<f'),
-             0x07: ("double", '<d')}
-
-    def __init__(self, data=None):
-        """TocElement creator. Data is the binary payload of the element."""
-        if (data):
-            strs = struct.unpack("s" * len(data[2:]), data[2:])
-            if sys.version_info < (3,):
-                strs = ("{}" * len(strs)).format(*strs).split("\0")
-            else:
-                s = ""
-                for ch in strs:
-                    s += ch.decode('ISO-8859-1')
-                strs = s.split("\x00")
-            self.group = strs[0]
-            self.name = strs[1]
-
-            if type(data[0]) == str:
-                self.ident = ord(data[0])
-            else:
-                self.ident = data[0]
-
-            metadata = data[1]
-            if type(metadata) == str:
-                metadata = ord(metadata)
-
-            self.ctype = self.types[metadata & 0x0F][0]
-            self.pytype = self.types[metadata & 0x0F][1]
-            if ((metadata & 0x40) != 0):
-                self.access = ParamTocElement.RO_ACCESS
-            else:
-                self.access = ParamTocElement.RW_ACCESS
-
-    def get_readable_access(self):
-        if (self.access == ParamTocElement.RO_ACCESS):
-            return "RO"
-        return "RW"
-
-
-class Param():
-    """
-    Used to read and write parameter values in the Crazyflie.
-    """
-
-    toc = Toc()
-
-    def __init__(self, crazyflie):
-        self.cf = crazyflie
-        self.param_update_callbacks = {}
-        self.group_update_callbacks = {}
-        self.all_update_callback = Caller()
-        self.param_updater = None
-
-        self.param_updater = _ParamUpdater(self.cf, self._param_updated)
-        self.param_updater.start()
-
-        self.cf.disconnected.add_callback(self._disconnected)
-
-        self.all_updated = Caller()
-        self.is_updated = False
-
-        self.values = {}
-
-    def request_update_of_all_params(self):
-        """Request an update of all the parameters in the TOC"""
-        for group in self.toc.toc:
-            for name in self.toc.toc[group]:
-                complete_name = "%s.%s" % (group, name)
-                self.request_param_update(complete_name)
-
-    def _check_if_all_updated(self):
-        """Check if all parameters from the TOC has at least been fetched
-        once"""
-        for g in self.toc.toc:
-            if g not in self.values:
-                return False
-            for n in self.toc.toc[g]:
-                if n not in self.values[g]:
-                    return False
-
-        return True
-
-    def _param_updated(self, pk):
-        """Callback with data for an updated parameter"""
-        var_id = pk.data[0]
-        element = self.toc.get_element_by_id(var_id)
-        if element:
-            s = struct.unpack(element.pytype, pk.data[1:])[0]
-            s = s.__str__()
-            complete_name = "%s.%s" % (element.group, element.name)
-
-            # Save the value for synchronous access
-            if element.group not in self.values:
-                self.values[element.group] = {}
-            self.values[element.group][element.name] = s
-
-            logger.debug("Updated parameter [%s]" % complete_name)
-            if complete_name in self.param_update_callbacks:
-                self.param_update_callbacks[complete_name].call(
-                    complete_name, s)
-            if element.group in self.group_update_callbacks:
-                self.group_update_callbacks[element.group].call(
-                    complete_name, s)
-            self.all_update_callback.call(complete_name, s)
-
-            # Once all the parameters are updated call the
-            # callback for "everything updated" (after all the param
-            # updated callbacks)
-            if self._check_if_all_updated() and not self.is_updated:
-                self.is_updated = True
-                self.all_updated.call()
-        else:
-            logger.debug("Variable id [%d] not found in TOC", var_id)
-
-    def remove_update_callback(self, group, name=None, cb=None):
-        """Remove the supplied callback for a group or a group.name"""
-        if not cb:
-            return
-
-        if not name:
-            if group in self.group_update_callbacks:
-                self.group_update_callbacks[group].remove_callback(cb)
-        else:
-            paramname = "{}.{}".format(group, name)
-            if paramname in self.param_update_callbacks:
-                self.param_update_callbacks[paramname].remove_callback(cb)
-
-    def add_update_callback(self, group=None, name=None, cb=None):
-        """
-        Add a callback for a specific parameter name. This callback will be
-        executed when a new value is read from the Crazyflie.
-        """
-        if not group and not name:
-            self.all_update_callback.add_callback(cb)
-        elif not name:
-            if group not in self.group_update_callbacks:
-                self.group_update_callbacks[group] = Caller()
-            self.group_update_callbacks[group].add_callback(cb)
-        else:
-            paramname = "{}.{}".format(group, name)
-            if paramname not in self.param_update_callbacks:
-                self.param_update_callbacks[paramname] = Caller()
-            self.param_update_callbacks[paramname].add_callback(cb)
-
-    def refresh_toc(self, refresh_done_callback, toc_cache):
-        """
-        Initiate a refresh of the parameter TOC.
-        """
-        toc_fetcher = TocFetcher(self.cf, ParamTocElement,
-                                 CRTPPort.PARAM, self.toc,
-                                 refresh_done_callback, toc_cache)
-        toc_fetcher.start()
-
-    def _disconnected(self, uri):
-        """Disconnected callback from Crazyflie API"""
-        self.param_updater.close()
-        self.is_updated = False
-        # Clear all values from the previous Crazyflie
-        self.toc = Toc()
-        self.values = {}
-
-    def request_param_update(self, complete_name):
-        """
-        Request an update of the value for the supplied parameter.
-        """
-        self.param_updater.request_param_update(
-            self.toc.get_element_id(complete_name))
-
-    def set_value(self, complete_name, value):
-        """
-        Set the value for the supplied parameter.
-        """
-        element = self.toc.get_element_by_complete_name(complete_name)
-
-        if not element:
-            logger.warning("Cannot set value for [%s], it's not in the TOC!",
-                           complete_name)
-            raise KeyError("{} not in param TOC".format(complete_name))
-        elif element.access == ParamTocElement.RO_ACCESS:
-            logger.debug("[%s] is read only, no trying to set value",
-                         complete_name)
-            raise AttributeError("{} is read-only!".format(complete_name))
-        else:
-            varid = element.ident
-            pk = CRTPPacket()
-            pk.set_header(CRTPPort.PARAM, WRITE_CHANNEL)
-            pk.data = struct.pack('<B', varid)
-            pk.data += struct.pack(element.pytype, eval(value))
-            self.param_updater.request_param_setvalue(pk)
-
-
-class _ParamUpdater(Thread):
-    """This thread will update params through a queue to make sure that we
-    get back values"""
-
-    def __init__(self, cf, updated_callback):
-        """Initialize the thread"""
-        Thread.__init__(self)
-        self.setDaemon(True)
-        self.wait_lock = Lock()
-        self.cf = cf
-        self.updated_callback = updated_callback
-        self.request_queue = Queue()
-        self.cf.add_port_callback(CRTPPort.PARAM, self._new_packet_cb)
-        self._should_close = False
-        self._req_param = -1
-
-    def close(self):
-        # First empty the queue from all packets
-        while not self.request_queue.empty():
-            self.request_queue.get()
-        # Then force an unlock of the mutex if we are waiting for a packet
-        # we didn't get back due to a disconnect for example.
-        try:
-            self.wait_lock.release()
-        except:
-            pass
-
-    def request_param_setvalue(self, pk):
-        """Place a param set value request on the queue. When this is sent to
-        the Crazyflie it will answer with the update param value. """
-        self.request_queue.put(pk)
-
-    def _new_packet_cb(self, pk):
-        """Callback for newly arrived packets"""
-        if pk.channel == READ_CHANNEL or pk.channel == WRITE_CHANNEL:
-            var_id = pk.data[0]
-            if (pk.channel != TOC_CHANNEL and self._req_param == var_id and
-                    pk is not None):
-                self.updated_callback(pk)
-                self._req_param = -1
-                try:
-                    self.wait_lock.release()
-                except:
-                    pass
-
-    def request_param_update(self, var_id):
-        """Place a param update request on the queue"""
-        pk = CRTPPacket()
-        pk.set_header(CRTPPort.PARAM, READ_CHANNEL)
-        pk.data = struct.pack('<B', var_id)
-        logger.debug("Requesting request to update param [%d]", var_id)
-        self.request_queue.put(pk)
-
-    def run(self):
-        while not self._should_close:
-            pk = self.request_queue.get()  # Wait for request update
-            self.wait_lock.acquire()
-            if self.cf.link:
-                self._req_param = pk.data[0]
-                self.cf.send_packet(pk, expected_reply=(tuple(pk.data[0:2])))
-            else:
-                self.wait_lock.release()
diff --git a/src/cflib/cflib/crazyflie/platformservice.py b/src/cflib/cflib/crazyflie/platformservice.py
deleted file mode 100644
index 385f9ae892e145e189c8d14ae9a2eff90b01a23c..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crazyflie/platformservice.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-"""
-Used for sending control setpoints to the Crazyflie
-"""
-import struct
-
-from cflib.crtp.crtpstack import CRTPPacket
-from cflib.crtp.crtpstack import CRTPPort
-
-__author__ = 'Bitcraze AB'
-__all__ = ['PlatformService']
-
-
-class PlatformService():
-    """
-    Used for sending control setpoints to the Crazyflie
-    """
-
-    def __init__(self, crazyflie=None):
-        """
-        Initialize the platform object.
-        """
-        self._cf = crazyflie
-
-    def set_continous_wave(self, enabled):
-        """
-        Enable/disable the client side X-mode. When enabled this recalculates
-        the setpoints before sending them to the Crazyflie.
-        """
-        pk = CRTPPacket()
-        pk.set_header(CRTPPort.PLATFORM, 0)
-        pk.data = (0, enabled)
-        self._cf.send_packet(pk)
diff --git a/src/cflib/cflib/crazyflie/toc.py b/src/cflib/cflib/crazyflie/toc.py
deleted file mode 100644
index 984e93ebaaf5d528ee4f1f102ad8c68b17fa434f..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crazyflie/toc.py
+++ /dev/null
@@ -1,205 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-A generic TableOfContents module that is used to fetch, store and minipulate
-a TOC for logging or parameters.
-"""
-
-from cflib.crtp.crtpstack import CRTPPacket
-import struct
-
-import logging
-
-__author__ = 'Bitcraze AB'
-__all__ = ['TocElement', 'Toc', 'TocFetcher']
-
-logger = logging.getLogger(__name__)
-
-TOC_CHANNEL = 0
-
-# Commands used when accessing the Table of Contents
-CMD_TOC_ELEMENT = 0
-CMD_TOC_INFO = 1
-
-# Possible states when receiving TOC
-IDLE = "IDLE"
-GET_TOC_INFO = "GET_TOC_INFO"
-GET_TOC_ELEMENT = "GET_TOC_ELEMENT"
-
-
-class TocElement:
-    """An element in the TOC."""
-    RW_ACCESS = 0
-    RO_ACCESS = 1
-
-    ident = 0
-    group = ""
-    name = ""
-    ctype = ""
-    pytype = ""
-    access = RO_ACCESS
-
-
-class Toc:
-    """Container for TocElements."""
-
-    def __init__(self):
-        self.toc = {}
-
-    def clear(self):
-        """Clear the TOC"""
-        self.toc = {}
-
-    def add_element(self, element):
-        """Add a new TocElement to the TOC container."""
-        try:
-            self.toc[element.group][element.name] = element
-        except KeyError:
-            self.toc[element.group] = {}
-            self.toc[element.group][element.name] = element
-
-    def get_element_by_complete_name(self, complete_name):
-        """Get a TocElement element identified by complete name from the
-        container."""
-        try:
-            return self.get_element_by_id(self.get_element_id(complete_name))
-        except ValueError:
-            # Item not found
-            return None
-
-    def get_element_id(self, complete_name):
-        """Get the TocElement element id-number of the element with the
-        supplied name."""
-        [group, name] = complete_name.split(".")
-        element = self.get_element(group, name)
-        if element:
-            return element.ident
-        else:
-            logger.warning("Unable to find variable [%s]", complete_name)
-            return None
-
-    def get_element(self, group, name):
-        """Get a TocElement element identified by name and group from the
-        container."""
-        try:
-            return self.toc[group][name]
-        except KeyError:
-            return None
-
-    def get_element_by_id(self, ident):
-        """Get a TocElement element identified by index number from the
-        container."""
-        for group in list(self.toc.keys()):
-            for name in list(self.toc[group].keys()):
-                if self.toc[group][name].ident == ident:
-                    return self.toc[group][name]
-        return None
-
-
-class TocFetcher:
-    """Fetches TOC entries from the Crazyflie"""
-
-    def __init__(self, crazyflie, element_class, port, toc_holder,
-                 finished_callback, toc_cache):
-        self.cf = crazyflie
-        self.port = port
-        self._crc = 0
-        self.requested_index = None
-        self.nbr_of_items = None
-        self.state = None
-        self.toc = toc_holder
-        self._toc_cache = toc_cache
-        self.finished_callback = finished_callback
-        self.element_class = element_class
-
-    def start(self):
-        """Initiate fetching of the TOC."""
-        logger.debug("[%d]: Start fetching...", self.port)
-        # Register callback in this class for the port
-        self.cf.add_port_callback(self.port, self._new_packet_cb)
-
-        # Request the TOC CRC
-        self.state = GET_TOC_INFO
-        pk = CRTPPacket()
-        pk.set_header(self.port, TOC_CHANNEL)
-        pk.data = (CMD_TOC_INFO,)
-        self.cf.send_packet(pk, expected_reply=(CMD_TOC_INFO,))
-
-    def _toc_fetch_finished(self):
-        """Callback for when the TOC fetching is finished"""
-        self.cf.remove_port_callback(self.port, self._new_packet_cb)
-        logger.debug("[%d]: Done!", self.port)
-        self.finished_callback()
-
-    def _new_packet_cb(self, packet):
-        """Handle a newly arrived packet"""
-        chan = packet.channel
-        if (chan != 0):
-            return
-        payload = packet.data[1:]
-
-        if (self.state == GET_TOC_INFO):
-            [self.nbr_of_items, self._crc] = struct.unpack("<BI", payload[:5])
-            logger.debug("[%d]: Got TOC CRC, %d items and crc=0x%08X",
-                         self.port, self.nbr_of_items, self._crc)
-
-            cache_data = self._toc_cache.fetch(self._crc)
-            if (cache_data):
-                self.toc.toc = cache_data
-                logger.info("TOC for port [%s] found in cache" % self.port)
-                self._toc_fetch_finished()
-            else:
-                self.state = GET_TOC_ELEMENT
-                self.requested_index = 0
-                self._request_toc_element(self.requested_index)
-
-        elif (self.state == GET_TOC_ELEMENT):
-            # Always add new element, but only request new if it's not the
-            # last one.
-            if self.requested_index != payload[0]:
-                return
-            self.toc.add_element(self.element_class(payload))
-            logger.debug("Added element [%s]",
-                         self.element_class(payload).ident)
-            if (self.requested_index < (self.nbr_of_items - 1)):
-                logger.debug("[%d]: More variables, requesting index %d",
-                             self.port, self.requested_index + 1)
-                self.requested_index = self.requested_index + 1
-                self._request_toc_element(self.requested_index)
-            else:  # No more variables in TOC
-                self._toc_cache.insert(self._crc, self.toc.toc)
-                self._toc_fetch_finished()
-
-    def _request_toc_element(self, index):
-        """Request information about a specific item in the TOC"""
-        logger.debug("Requesting index %d on port %d", index, self.port)
-        pk = CRTPPacket()
-        pk.set_header(self.port, TOC_CHANNEL)
-        pk.data = (CMD_TOC_ELEMENT, index)
-        self.cf.send_packet(pk, expected_reply=(CMD_TOC_ELEMENT, index))
diff --git a/src/cflib/cflib/crazyflie/toccache.py b/src/cflib/cflib/crazyflie/toccache.py
deleted file mode 100644
index 22add3c8ea979e3e9352badd2ca5f77b5026cda7..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crazyflie/toccache.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-Access the TOC cache for reading/writing. It supports both user
-cache and dist cache.
-"""
-
-import os
-import json
-from glob import glob
-
-import logging
-
-from .log import LogTocElement  # pylint: disable=W0611
-from .param import ParamTocElement  # pylint: disable=W0611
-
-__author__ = 'Bitcraze AB'
-__all__ = ['TocCache']
-
-logger = logging.getLogger(__name__)
-
-
-class TocCache():
-    """
-    Access to TOC cache. To turn of the cache functionality
-    don't supply any directories.
-    """
-
-    def __init__(self, ro_cache=None, rw_cache=None):
-        self._cache_files = []
-        if (ro_cache):
-            self._cache_files += glob(ro_cache + "/*.json")
-        if (rw_cache):
-            self._cache_files += glob(rw_cache + "/*.json")
-            if not os.path.exists(rw_cache):
-                os.makedirs(rw_cache)
-
-        self._rw_cache = rw_cache
-
-    def fetch(self, crc):
-        """ Try to get a hit in the cache, return None otherwise """
-        cache_data = None
-        pattern = "%08X.json" % crc
-        hit = None
-
-        for name in self._cache_files:
-            if (name.endswith(pattern)):
-                hit = name
-
-        if (hit):
-            try:
-                cache = open(hit)
-                cache_data = json.load(cache,
-                                       object_hook=self._decoder)
-                cache.close()
-            except Exception as exp:
-                logger.warning("Error while parsing cache file [%s]:%s",
-                               hit, str(exp))
-
-        return cache_data
-
-    def insert(self, crc, toc):
-        """ Save a new cache to file """
-        if self._rw_cache:
-            try:
-                filename = "%s/%08X.json" % (self._rw_cache, crc)
-                cache = open(filename, 'w')
-                cache.write(json.dumps(toc, indent=2,
-                                       default=self._encoder))
-                cache.close()
-                logger.info("Saved cache to [%s]", filename)
-                self._cache_files += [filename]
-            except Exception as exp:
-                logger.warning("Could not save cache to file [%s]: %s",
-                               filename, str(exp))
-        else:
-            logger.warning("Could not save cache, no writable directory")
-
-    def _encoder(self, obj):
-        """ Encode a toc element leaf-node """
-        return {'__class__': obj.__class__.__name__,
-                'ident': obj.ident,
-                'group': obj.group,
-                'name': obj.name,
-                'ctype': obj.ctype,
-                'pytype': obj.pytype,
-                'access': obj.access}
-        raise TypeError(repr(obj) + ' is not JSON serializable')
-
-    def _decoder(self, obj):
-        """ Decode a toc element leaf-node """
-        if '__class__' in obj:
-            elem = eval(obj['__class__'])()
-            elem.ident = obj['ident']
-            elem.group = str(obj['group'])
-            elem.name = str(obj['name'])
-            elem.ctype = str(obj['ctype'])
-            elem.pytype = str(obj['pytype'])
-            elem.access = obj['access']
-            return elem
-        return obj
diff --git a/src/cflib/cflib/crtp/__init__.py b/src/cflib/cflib/crtp/__init__.py
deleted file mode 100644
index 687faaa7b0a26c61ef4321dab6f1454cc27889b6..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crtp/__init__.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-"""Scans and creates communication interfaces."""
-import logging
-
-from .debugdriver import DebugDriver
-from .exceptions import WrongUriType
-from .radiodriver import RadioDriver
-from .serialdriver import SerialDriver
-from .udpdriver import UdpDriver
-from .usbdriver import UsbDriver
-
-__author__ = 'Bitcraze AB'
-__all__ = []
-
-logger = logging.getLogger(__name__)
-
-
-DRIVERS = [RadioDriver, SerialDriver, UdpDriver, DebugDriver, UsbDriver]
-INSTANCES = []
-
-
-def init_drivers(enable_debug_driver=False):
-    """Initialize all the drivers."""
-    for driver in DRIVERS:
-        try:
-            if driver != DebugDriver or enable_debug_driver:
-                INSTANCES.append(driver())
-        except Exception:  # pylint: disable=W0703
-            continue
-
-
-def scan_interfaces(address=None):
-    """ Scan all the interfaces for available Crazyflies """
-    available = []
-    found = []
-    for instance in INSTANCES:
-        logger.debug("Scanning: %s", instance)
-        try:
-            found = instance.scan_interface(address)
-            available += found
-        except Exception:
-            raise
-    return available
-
-
-def get_interfaces_status():
-    """Get the status of all the interfaces"""
-    status = {}
-    for instance in INSTANCES:
-        try:
-            status[instance.get_name()] = instance.get_status()
-        except Exception:
-            raise
-    return status
-
-
-def get_link_driver(uri, link_quality_callback=None, link_error_callback=None):
-    """Return the link driver for the given URI. Returns None if no driver
-    was found for the URI or the URI was not well formatted for the matching
-    driver."""
-    for instance in INSTANCES:
-        try:
-            instance.connect(uri, link_quality_callback, link_error_callback)
-            return instance
-        except WrongUriType:
-            continue
-
-    return None
diff --git a/src/cflib/cflib/crtp/crtpdriver.py b/src/cflib/cflib/crtp/crtpdriver.py
deleted file mode 100644
index 7d9f7d8cb966a40bba79a984af67e2f3736c3aa8..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crtp/crtpdriver.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-"""
-CRTP Driver main class.
-"""
-
-__author__ = 'Bitcraze AB'
-__all__ = ['CRTPDriver']
-
-
-class CRTPDriver:
-    """ CTRP Driver main class
-
-    This class in inherited by all the CRTP link drivers.
-    """
-
-    def __init__(self):
-        """Driver constructor. Throw an exception if the driver is unable to
-        open the URI
-        """
-        self.needs_resending = True
-
-    def connect(self, uri, link_quality_callback, link_error_callback):
-        """Connect the driver to a specified URI
-
-        @param uri Uri of the link to open
-        @param link_quality_callback Callback to report link quality in percent
-        @param link_error_callback Callback to report errors (will result in
-               disconnection)
-        """
-
-    def send_packet(self, pk):
-        """Send a CRTP packet"""
-
-    def receive_packet(self, wait=0):
-        """Receive a CRTP packet.
-
-        @param wait The time to wait for a packet in second. -1 means forever
-
-        @return One CRTP packet or None if no packet has been received.
-        """
-
-    def get_status(self):
-        """
-        Return a status string from the interface.
-        """
-
-    def get_name(self):
-        """
-        Return a human readable name of the interface.
-        """
-
-    def scan_interface(self, address=None):
-        """
-        Scan interface for available Crazyflie quadcopters and return a list
-        with them.
-        """
-
-    def enum(self):
-        """Enumerate, and return a list, of the available link URI on this
-        system
-        """
-
-    def get_help(self):
-        """return the help message on how to form the URI for this driver
-        None means no help
-        """
-
-    def close(self):
-        """Close the link"""
diff --git a/src/cflib/cflib/crtp/crtpstack.py b/src/cflib/cflib/crtp/crtpstack.py
deleted file mode 100644
index 3d3898ab4daf0eedb8c7c471d55c682d99342acc..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crtp/crtpstack.py
+++ /dev/null
@@ -1,149 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-"""
-CRTP packet and ports.
-"""
-import logging
-import sys
-
-__author__ = 'Bitcraze AB'
-__all__ = ['CRTPPort', 'CRTPPacket']
-
-logger = logging.getLogger(__name__)
-
-
-class CRTPPort:
-    """
-    Lists the available ports for the CRTP.
-    """
-    CONSOLE = 0x00
-    PARAM = 0x02
-    COMMANDER = 0x03
-    MEM = 0x04
-    LOGGING = 0x05
-    DEBUGDRIVER = 0x0E
-    LINKCTRL = 0x0F
-    ALL = 0xFF
-
-
-class CRTPPacket(object):
-    """
-    A packet that can be sent via the CRTP.
-    """
-
-    def __init__(self, header=0, data=None):
-        """
-        Create an empty packet with default values.
-        """
-        self.size = 0
-        self._data = bytearray()
-        # The two bits in position 3 and 4 needs to be set for legacy
-        # support of the bootloader
-        self.header = header | 0x3 << 2
-        self._port = (header & 0xF0) >> 4
-        self._channel = header & 0x03
-        if data:
-            self._set_data(data)
-
-    def _get_channel(self):
-        """Get the packet channel"""
-        return self._channel
-
-    def _set_channel(self, channel):
-        """Set the packet channel"""
-        self._channel = channel
-        self._update_header()
-
-    def _get_port(self):
-        """Get the packet port"""
-        return self._port
-
-    def _set_port(self, port):
-        """Set the packet port"""
-        self._port = port
-        self._update_header()
-
-    def get_header(self):
-        """Get the header"""
-        self._update_header()
-        return self.header
-
-    def set_header(self, port, channel):
-        """
-        Set the port and channel for this packet.
-        """
-        self._port = port
-        self.channel = channel
-        self._update_header()
-
-    def _update_header(self):
-        """Update the header with the port/channel values"""
-        # The two bits in position 3 and 4 needs to be set for legacy
-        # support of the bootloader
-        self.header = ((self._port & 0x0f) << 4 | 3 << 2 |
-                       (self.channel & 0x03))
-
-    # Some python madness to access different format of the data
-    def _get_data(self):
-        """Get the packet data"""
-        return self._data
-
-    def _set_data(self, data):
-        """Set the packet data"""
-        if type(data) == bytearray:
-            self._data = data
-        elif type(data) == str:
-            if sys.version_info < (3,):
-                self._data = bytearray(data)
-            else:
-                self._data = bytearray(data.encode('ISO-8859-1'))
-        elif type(data) == list or type(data) == tuple:
-            self._data = bytearray(data)
-        elif sys.version_info >= (3,) and type(data) == bytes:
-            self._data = bytearray(data)
-        else:
-            raise Exception("Data must be bytearray, string, list or tuple,"
-                            " not {}".format(type(data)))
-
-    def _get_data_l(self):
-        """Get the data in the packet as a list"""
-        return list(self._get_data_t())
-
-    def _get_data_t(self):
-        """Get the data in the packet as a tuple"""
-        return tuple(self._data)
-
-    def __str__(self):
-        """Get a string representation of the packet"""
-        return "{}:{} {}".format(self._port, self.channel, self.datat)
-
-    data = property(_get_data, _set_data)
-    datal = property(_get_data_l, _set_data)
-    datat = property(_get_data_t, _set_data)
-    datas = property(_get_data, _set_data)
-    port = property(_get_port, _set_port)
-    channel = property(_get_channel, _set_channel)
diff --git a/src/cflib/cflib/crtp/debugdriver.py b/src/cflib/cflib/crtp/debugdriver.py
deleted file mode 100644
index 98b554eff60c630aac5fc6ecb7655845306202e0..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crtp/debugdriver.py
+++ /dev/null
@@ -1,897 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-"""
-Fake link driver used to debug the UI without using the Crazyflie.
-
-The operation of this driver can be controlled in two ways, either by
-connecting to different URIs or by sending messages to the DebugDriver port
-though CRTP once connected.
-
-For normal connections a console thread is also started that will send
-generated console output via CRTP.
-"""
-import errno
-import logging
-import random
-import re
-import string
-import struct
-import sys
-import time
-from datetime import datetime
-from threading import Thread
-
-from cflib.crazyflie.log import LogTocElement
-from cflib.crazyflie.param import ParamTocElement
-
-from .crtpdriver import CRTPDriver
-from .crtpstack import CRTPPacket
-from .crtpstack import CRTPPort
-from .exceptions import WrongUriType
-if sys.version_info < (3,):
-    import Queue as queue
-else:
-    import queue
-
-__author__ = 'Bitcraze AB'
-__all__ = ['DebugDriver']
-
-logger = logging.getLogger(__name__)
-
-# This setup is used to debug raw memory logging
-memlogging = {0x01: {"min": 0, "max": 255, "mod": 1, "vartype": 1},
-              0x02: {"min": 0, "max": 65000, "mod": 100, "vartype": 2},
-              0x03: {"min": 0, "max": 100000, "mod": 1000, "vartype": 3},
-              0x04: {"min": -100, "max": 100, "mod": 1, "vartype": 4},
-              0x05: {"min": -10000, "max": 10000, "mod": 2000, "vartype": 5},
-              0x06: {"min": -50000, "max": 50000, "mod": 1000, "vartype": 6},
-              0x07: {"min": 0, "max": 255, "mod": 1, "vartype": 1}}
-
-
-class FakeMemory:
-    TYPE_I2C = 0
-    TYPE_1W = 1
-
-    def __init__(self, type, size, addr, data=None):
-        self.type = type
-        self.size = size
-        self.addr = addr
-        self.data = [0] * size
-        if data:
-            for i in range(len(data)):
-                self.data[i] = data[i]
-
-    def erase(self):
-        self.data = [0] * self.size
-
-
-class DebugDriver(CRTPDriver):
-    """ Debug driver used for debugging UI/communication without using a
-    Crazyflie"""
-
-    def __init__(self):
-        self.fakeLoggingThreads = []
-        self._fake_mems = []
-        self.needs_resending = False
-        # Fill up the fake logging TOC with values and data
-        self.fakeLogToc = []
-        self.fakeLogToc.append({"varid": 0, "vartype": 5, "vargroup": "imu",
-                                "varname": "gyro_x", "min": -10000,
-                                "max": 10000, "mod": 1000})
-        self.fakeLogToc.append({"varid": 1, "vartype": 5, "vargroup": "imu",
-                                "varname": "gyro_y", "min": -10000,
-                                "max": 10000, "mod": 150})
-        self.fakeLogToc.append({"varid": 2, "vartype": 5, "vargroup": "imu",
-                                "varname": "gyro_z", "min": -10000,
-                                "max": 10000, "mod": 200})
-        self.fakeLogToc.append({"varid": 3, "vartype": 5, "vargroup": "imu",
-                                "varname": "acc_x", "min": -1000,
-                                "max": 1000, "mod": 15})
-        self.fakeLogToc.append({"varid": 4, "vartype": 5, "vargroup": "imu",
-                                "varname": "acc_y", "min": -1000,
-                                "max": 1000, "mod": 10})
-        self.fakeLogToc.append({"varid": 5, "vartype": 5, "vargroup": "imu",
-                                "varname": "acc_z", "min": -1000,
-                                "max": 1000, "mod": 20})
-        self.fakeLogToc.append({"varid": 6, "vartype": 7,
-                                "vargroup": "stabilizer", "varname": "roll",
-                                "min": -90, "max": 90, "mod": 2})
-        self.fakeLogToc.append({"varid": 7, "vartype": 7,
-                                "vargroup": "stabilizer", "varname": "pitch",
-                                "min": -90, "max": 90, "mod": 1.5})
-        self.fakeLogToc.append({"varid": 8, "vartype": 7,
-                                "vargroup": "stabilizer", "varname": "yaw",
-                                "min": -90, "max": 90, "mod": 2.5})
-        self.fakeLogToc.append({"varid": 9, "vartype": 7, "vargroup": "pm",
-                                "varname": "vbat", "min": 3.0,
-                                "max": 4.2, "mod": 0.1})
-        self.fakeLogToc.append({"varid": 10, "vartype": 6, "vargroup": "motor",
-                                "varname": "m1", "min": 0, "max": 65000,
-                                "mod": 1000})
-        self.fakeLogToc.append({"varid": 11, "vartype": 6, "vargroup": "motor",
-                                "varname": "m2", "min": 0, "max": 65000,
-                                "mod": 1000})
-        self.fakeLogToc.append({"varid": 12, "vartype": 6, "vargroup": "motor",
-                                "varname": "m3", "min": 0, "max": 65000,
-                                "mod": 1000})
-        self.fakeLogToc.append({"varid": 13, "vartype": 6, "vargroup": "motor",
-                                "varname": "m4", "min": 0, "max": 65000,
-                                "mod": 1000})
-        self.fakeLogToc.append({"varid": 14, "vartype": 2,
-                                "vargroup": "stabilizer", "varname": "thrust",
-                                "min": 0, "max": 65000, "mod": 1000})
-        self.fakeLogToc.append({"varid": 15, "vartype": 7,
-                                "vargroup": "baro", "varname": "asl",
-                                "min": 540, "max": 545, "mod": 0.5})
-        self.fakeLogToc.append({"varid": 16, "vartype": 7,
-                                "vargroup": "baro", "varname": "aslRaw",
-                                "min": 540, "max": 545, "mod": 1.0})
-        self.fakeLogToc.append({"varid": 17, "vartype": 7,
-                                "vargroup": "baro", "varname": "aslLong",
-                                "min": 540, "max": 545, "mod": 0.5})
-        self.fakeLogToc.append({"varid": 18, "vartype": 7,
-                                "vargroup": "baro", "varname": "temp",
-                                "min": 26, "max": 38, "mod": 1.0})
-        self.fakeLogToc.append({"varid": 19, "vartype": 7,
-                                "vargroup": "altHold", "varname": "target",
-                                "min": 542, "max": 543, "mod": 0.1})
-        self.fakeLogToc.append({"varid": 20, "vartype": 6,
-                                "vargroup": "gps", "varname": "lat",
-                                "min": 556112190, "max": 556112790,
-                                "mod": 10})
-        self.fakeLogToc.append({"varid": 21, "vartype": 6,
-                                "vargroup": "gps", "varname": "lon",
-                                "min": 129945110, "max": 129945710,
-                                "mod": 10})
-        self.fakeLogToc.append({"varid": 22, "vartype": 6,
-                                "vargroup": "gps", "varname": "hMSL",
-                                "min": 0, "max": 100000,
-                                "mod": 1000})
-        self.fakeLogToc.append({"varid": 23, "vartype": 6,
-                                "vargroup": "gps", "varname": "heading",
-                                "min": -10000000, "max": 10000000,
-                                "mod": 100000})
-        self.fakeLogToc.append({"varid": 24, "vartype": 6,
-                                "vargroup": "gps", "varname": "gSpeed",
-                                "min": 0, "max": 1000,
-                                "mod": 100})
-        self.fakeLogToc.append({"varid": 25, "vartype": 3,
-                                "vargroup": "gps", "varname": "hAcc",
-                                "min": 0, "max": 5000,
-                                "mod": 100})
-        self.fakeLogToc.append({"varid": 26, "vartype": 1,
-                                "vargroup": "gps", "varname": "fixType",
-                                "min": 0, "max": 5,
-                                "mod": 1})
-
-        # Fill up the fake logging TOC with values and data
-        self.fakeParamToc = []
-        self.fakeParamToc.append({"varid": 0, "vartype": 0x08,
-                                  "vargroup": "blah", "varname": "p",
-                                  "writable": True, "value": 100})
-        self.fakeParamToc.append({"varid": 1, "vartype": 0x0A,
-                                  "vargroup": "info", "varname": "cid",
-                                  "writable": False, "value": 1234})
-        self.fakeParamToc.append({"varid": 2, "vartype": 0x06,
-                                  "vargroup": "rpid", "varname": "prp",
-                                  "writable": True, "value": 1.5})
-        self.fakeParamToc.append({"varid": 3, "vartype": 0x06,
-                                  "vargroup": "rpid", "varname": "pyaw",
-                                  "writable": True, "value": 2.5})
-        self.fakeParamToc.append({"varid": 4, "vartype": 0x06,
-                                  "vargroup": "rpid", "varname": "irp",
-                                  "writable": True, "value": 3.5})
-        self.fakeParamToc.append({"varid": 5, "vartype": 0x06,
-                                  "vargroup": "rpid", "varname": "iyaw",
-                                  "writable": True, "value": 4.5})
-        self.fakeParamToc.append({"varid": 6, "vartype": 0x06,
-                                  "vargroup": "pid_attitude",
-                                  "varname": "pitch_kd", "writable": True,
-                                  "value": 5.5})
-        self.fakeParamToc.append({"varid": 7, "vartype": 0x06,
-                                  "vargroup": "rpid", "varname": "dyaw",
-                                  "writable": True, "value": 6.5})
-        self.fakeParamToc.append({"varid": 8, "vartype": 0x06,
-                                  "vargroup": "apid", "varname": "prp",
-                                  "writable": True, "value": 7.5})
-        self.fakeParamToc.append({"varid": 9, "vartype": 0x06,
-                                  "vargroup": "apid", "varname": "pyaw",
-                                  "writable": True, "value": 8.5})
-        self.fakeParamToc.append({"varid": 10, "vartype": 0x06,
-                                  "vargroup": "apid", "varname": "irp",
-                                  "writable": True, "value": 9.5})
-        self.fakeParamToc.append({"varid": 11, "vartype": 0x06,
-                                  "vargroup": "apid", "varname": "iyaw",
-                                  "writable": True, "value": 10.5})
-        self.fakeParamToc.append({"varid": 12, "vartype": 0x06,
-                                  "vargroup": "apid", "varname": "drp",
-                                  "writable": True, "value": 11.5})
-        self.fakeParamToc.append({"varid": 13, "vartype": 0x06,
-                                  "vargroup": "apid", "varname": "dyaw",
-                                  "writable": True, "value": 12.5})
-        self.fakeParamToc.append({"varid": 14, "vartype": 0x08,
-                                  "vargroup": "flightctrl",
-                                  "varname": "xmode", "writable": True,
-                                  "value": 1})
-        self.fakeParamToc.append({"varid": 15, "vartype": 0x08,
-                                  "vargroup": "flightctrl",
-                                  "varname": "ratepid", "writable": True,
-                                  "value": 1})
-        self.fakeParamToc.append({"varid": 16, "vartype": 0x08,
-                                  "vargroup": "imu_sensors",
-                                  "varname": "HMC5883L", "writable": False,
-                                  "value": 1})
-        self.fakeParamToc.append({"varid": 17, "vartype": 0x08,
-                                  "vargroup": "imu_sensors",
-                                  "varname": "MS5611", "writable": False,
-                                  "value": 1})
-        self.fakeParamToc.append({"varid": 18, "vartype": 0x0A,
-                                  "vargroup": "firmware",
-                                  "varname": "revision0", "writable": False,
-                                  "value": 0xdeb})
-        self.fakeParamToc.append({"varid": 19, "vartype": 0x09,
-                                  "vargroup": "firmware",
-                                  "varname": "revision1", "writable": False,
-                                  "value": 0x99})
-        self.fakeParamToc.append({"varid": 20, "vartype": 0x08,
-                                  "vargroup": "firmware",
-                                  "varname": "modified", "writable": False,
-                                  "value": 1})
-        self.fakeParamToc.append({"varid": 21, "vartype": 0x08,
-                                  "vargroup": "imu_tests",
-                                  "varname": "MPU6050", "writable": False,
-                                  "value": 1})
-        self.fakeParamToc.append({"varid": 22, "vartype": 0x08,
-                                  "vargroup": "imu_tests",
-                                  "varname": "HMC5883L", "writable": False,
-                                  "value": 1})
-        self.fakeParamToc.append({"varid": 23, "vartype": 0x08,
-                                  "vargroup": "imu_tests",
-                                  "varname": "MS5611", "writable": False,
-                                  "value": 1})
-
-        self.fakeflash = {}
-        self._random_answer_delay = True
-        self.queue = queue.Queue()
-        self._packet_handler = _PacketHandlingThread(self.queue,
-                                                     self.fakeLogToc,
-                                                     self.fakeParamToc,
-                                                     self._fake_mems)
-        self._packet_handler.start()
-
-    def scan_interface(self, address):
-        return [["debug://0/0", "Normal connection"],
-                ["debug://0/1", "Fail to connect"],
-                ["debug://0/2", "Incomplete log TOC download"],
-                ["debug://0/3", "Insert random delays on replies"],
-                ["debug://0/4",
-                 "Insert random delays on replies and random TOC CRCs"],
-                ["debug://0/5", "Normal but random TOC CRCs"],
-                ["debug://0/6", "Normal but empty I2C and OW mems"]]
-
-    def get_status(self):
-        return "Ok"
-
-    def get_name(self):
-        return "debug"
-
-    def connect(self, uri, linkQualityCallback, linkErrorCallback):
-
-        if not re.search("^debug://", uri):
-            raise WrongUriType("Not a debug URI")
-
-        self._packet_handler.linkErrorCallback = linkErrorCallback
-        self._packet_handler.linkQualityCallback = linkQualityCallback
-
-        # Debug-options for this driver that
-        # is set by using different connection URIs
-        self._packet_handler.inhibitAnswers = False
-        self._packet_handler.doIncompleteLogTOC = False
-        self._packet_handler.bootloader = False
-        self._packet_handler._random_answer_delay = False
-        self._packet_handler._random_toc_crcs = False
-
-        if (re.search("^debug://.*/1\Z", uri)):
-            self._packet_handler.inhibitAnswers = True
-        if (re.search("^debug://.*/110\Z", uri)):
-            self._packet_handler.bootloader = True
-        if (re.search("^debug://.*/2\Z", uri)):
-            self._packet_handler.doIncompleteLogTOC = True
-        if (re.search("^debug://.*/3\Z", uri)):
-            self._packet_handler._random_answer_delay = True
-        if (re.search("^debug://.*/4\Z", uri)):
-            self._packet_handler._random_answer_delay = True
-            self._packet_handler._random_toc_crcs = True
-        if (re.search("^debug://.*/5\Z", uri)):
-            self._packet_handler._random_toc_crcs = True
-
-        if len(self._fake_mems) == 0:
-            # Add empty EEPROM
-            self._fake_mems.append(FakeMemory(type=0, size=100, addr=0))
-            # Add EEPROM with settings
-            self._fake_mems.append(
-                FakeMemory(type=0, size=100, addr=0,
-                           data=[48, 120, 66, 67, 1, 8, 0, 0, 0, 0,
-                                 0, 0, 0, 0, 0, 231, 8, 231, 231, 231, 218]))
-            # Add 1-wire memory with settings for LED-ring
-            self._fake_mems.append(
-                FakeMemory(type=1, size=112, addr=0x1234567890ABCDEF,
-                           data=[0xeb, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-                                 0x44, 0x00, 0x0e,
-                                 0x01, 0x09, 0x62, 0x63, 0x4c, 0x65, 0x64,
-                                 0x52, 0x69, 0x6e,
-                                 0x67, 0x02, 0x01, 0x62, 0x55]))
-            # Add 1-wire memory with settings for LED-ring but bad CRC
-            self._fake_mems.append(
-                FakeMemory(type=1, size=112, addr=0x1234567890ABCDEF,
-                           data=[0xeb, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-                                 0x44, 0x00, 0x0e,
-                                 0x01, 0x09, 0x62, 0x63, 0x4c, 0x65, 0x64,
-                                 0x52, 0x69, 0x6e,
-                                 0x67, 0x02, 0x01, 0x62, 0x56]))
-            # Add empty 1-wire memory
-            self._fake_mems.append(
-                FakeMemory(type=1, size=112, addr=0x1234567890ABCDEE,
-                           data=[0x00 for a in range(112)]))
-
-        if (re.search("^debug://.*/6\Z", uri)):
-            logger.info("------------->Erasing memories on connect")
-            for m in self._fake_mems:
-                m.erase()
-
-        self.fakeConsoleThread = None
-
-        if (not self._packet_handler.inhibitAnswers and
-                not self._packet_handler.bootloader):
-            self.fakeConsoleThread = FakeConsoleThread(self.queue)
-            self.fakeConsoleThread.start()
-
-        if (self._packet_handler.linkQualityCallback is not None):
-            self._packet_handler.linkQualityCallback(0)
-
-    def receive_packet(self, time=0):
-        if time == 0:
-            try:
-                return self.queue.get(False)
-            except queue.Empty:
-                return None
-        elif time < 0:
-            try:
-                return self.queue.get(True)
-            except queue.Empty:
-                return None
-        else:
-            try:
-                return self.queue.get(True, time)
-            except queue.Empty:
-                return None
-
-    def send_packet(self, pk):
-        self._packet_handler.handle_packet(pk)
-
-    def close(self):
-        logger.info("Closing debugdriver")
-        for f in self._packet_handler.fakeLoggingThreads:
-            f.stop()
-        if self.fakeConsoleThread:
-            self.fakeConsoleThread.stop()
-
-
-class _PacketHandlingThread(Thread):
-    """Thread for handling packets asynchronously"""
-
-    def __init__(self, out_queue, fake_log_toc, fake_param_toc, fake_mems):
-        Thread.__init__(self)
-        self.setDaemon(True)
-        self.queue = out_queue
-        self.fakeLogToc = fake_log_toc
-        self.fakeParamToc = fake_param_toc
-        self._fake_mems = fake_mems
-        self._in_queue = queue.Queue()
-
-        self.inhibitAnswers = False
-        self.doIncompleteLogTOC = False
-        self.bootloader = False
-        self._random_answer_delay = False
-        self._random_toc_crcs = False
-
-        self.linkErrorCallback = None
-        self.linkQualityCallback = None
-        random.seed(None)
-        self.fakeLoggingThreads = []
-
-        self._added_blocks = []
-
-        self.nowAnswerCounter = 4
-
-    def handle_packet(self, pk):
-        self._in_queue.put(pk)
-
-    def run(self):
-        while (True):
-            pk = self._in_queue.get(True)
-            if (self.inhibitAnswers):
-                self.nowAnswerCounter = self.nowAnswerCounter - 1
-                logger.debug(
-                    "Not answering with any data, will send link errori"
-                    " in %d retries", self.nowAnswerCounter)
-                if (self.nowAnswerCounter == 0):
-                    self.linkErrorCallback("Nothing is answering, and it"
-                                           " shouldn't")
-            else:
-                if (pk.port == 0xFF):
-                    self._handle_bootloader(pk)
-                elif (pk.port == CRTPPort.DEBUGDRIVER):
-                    self._handle_debugmessage(pk)
-                elif (pk.port == CRTPPort.COMMANDER):
-                    pass
-                elif (pk.port == CRTPPort.LOGGING):
-                    self._handle_logging(pk)
-                elif (pk.port == CRTPPort.PARAM):
-                    self.handleParam(pk)
-                elif (pk.port == CRTPPort.MEM):
-                    self._handle_mem_access(pk)
-                else:
-                    logger.warning(
-                        "Not handling incoming packets on port [%d]",
-                        pk.port)
-
-    def _handle_mem_access(self, pk):
-        chan = pk.channel
-        cmd = pk.data[0]
-        payload = pk.data[1:]
-
-        if chan == 0:  # Info channel
-            p_out = CRTPPacket()
-            p_out.set_header(CRTPPort.MEM, 0)
-            if cmd == 1:  # Request number of memories
-                p_out.data = (1, len(self._fake_mems))
-            if cmd == 2:
-                id = payload[0]
-                logger.info("Getting mem {}".format(id))
-                m = self._fake_mems[id]
-                p_out.data = struct.pack(
-                    '<BBBIQ', 2, id, m.type, m.size, m.addr)
-            self._send_packet(p_out)
-
-        if chan == 1:  # Read channel
-            id = cmd
-            addr = struct.unpack("I", payload[0:4])[0]
-            length = payload[4]
-            status = 0
-            logger.info("MEM: Read {}bytes at 0x{:X} from memory {}".format(
-                length, addr, id))
-            m = self._fake_mems[id]
-            p_out = CRTPPacket()
-            p_out.set_header(CRTPPort.MEM, 1)
-            p_out.data = struct.pack("<BIB", id, addr, status)
-            p_out.data += struct.pack("B" * length,
-                                      *m.data[addr:addr + length])
-            self._send_packet(p_out)
-
-        if chan == 2:  # Write channel
-            id = cmd
-            addr = struct.unpack("I", payload[0:4])[0]
-            data = payload[4:]
-            logger.info("MEM: Write {}bytes at 0x{:X} to memory {}".format(
-                len(data), addr, id))
-            m = self._fake_mems[id]
-
-            for i in range(len(data)):
-                m.data[addr + i] = data[i]
-
-            status = 0
-
-            p_out = CRTPPacket()
-            p_out.set_header(CRTPPort.MEM, 2)
-            p_out.data = struct.pack("<BIB", id, addr, status)
-            self._send_packet(p_out)
-
-    def _handle_bootloader(self, pk):
-        cmd = pk.data[1]
-        if (cmd == 0x10):  # Request info about copter
-            p = CRTPPacket()
-            p.set_header(0xFF, 0xFF)
-            pageSize = 1024
-            buffPages = 10
-            flashPages = 100
-            flashStart = 1
-            p.data = struct.pack('<BBHHHH', 0xFF, 0x10, pageSize, buffPages,
-                                 flashPages, flashStart)
-            p.data += struct.pack('B' * 12, 0xA0A1A2A3A4A5)
-            self._send_packet(p)
-            logging.info("Bootloader: Sending info back info")
-        elif (cmd == 0x14):  # Upload buffer
-            [page, addr] = struct.unpack('<HH', p.data[0:4])
-        elif (cmd == 0x18):  # Flash page
-            p = CRTPPacket()
-            p.set_header(0xFF, 0xFF)
-            p.data = struct.pack('<BBH', 0xFF, 0x18, 1)
-            self._send_packet(p)
-        elif (cmd == 0xFF):  # Reset to firmware
-            logger.info("Bootloader: Got reset command")
-        else:
-            logger.warning("Bootloader: Unknown command 0x%02X", cmd)
-
-    def _handle_debugmessage(self, pk):
-        if (pk.channel == 0):
-            cmd = struct.unpack("B", pk.data[0])[0]
-            if (cmd == 0):  # Fake link quality
-                newLinkQuality = struct.unpack("B", pk.data[1])[0]
-                self.linkQualityCallback(newLinkQuality)
-            elif (cmd == 1):
-                self.linkErrorCallback("DebugDriver was forced to disconnect!")
-            else:
-                logger.warning("Debug port: Not handling cmd=%d on channel 0",
-                               cmd)
-        else:
-            logger.warning("Debug port: Not handling channel=%d",
-                           pk.channel)
-
-    def _handle_toc_access(self, pk):
-        chan = pk.channel
-        cmd = pk.data[0]
-        logger.info("TOC access on port %d", pk.port)
-        if (chan == 0):  # TOC Access
-            cmd = pk.data[0]
-            if (cmd == 0):  # Reqest variable info
-                p = CRTPPacket()
-                p.set_header(pk.port, 0)
-                varIndex = 0
-                if (len(pk.data) > 1):
-                    varIndex = pk.data[1]
-                    logger.debug("TOC[%d]: Requesting ID=%d", pk.port,
-                                 varIndex)
-                else:
-                    logger.debug("TOC[%d]: Requesting first index..surprise,"
-                                 " it 0 !", pk.port)
-
-                if (pk.port == CRTPPort.LOGGING):
-                    l = self.fakeLogToc[varIndex]
-                if (pk.port == CRTPPort.PARAM):
-                    l = self.fakeParamToc[varIndex]
-
-                vartype = l["vartype"]
-                if (pk.port == CRTPPort.PARAM and l["writable"] is True):
-                    vartype = vartype | (0x10)
-
-                p.data = struct.pack("<BBB", cmd, l["varid"], vartype)
-                for ch in l["vargroup"]:
-                    p.data.append(ord(ch))
-                p.data.append(0)
-                for ch in l["varname"]:
-                    p.data.append(ord(ch))
-                p.data.append(0)
-                if (self.doIncompleteLogTOC is False):
-                    self._send_packet(p)
-                elif (varIndex < 5):
-                    self._send_packet(p)
-                else:
-                    logger.info("TOC: Doing incomplete TOC, stopping after"
-                                " varIndex => 5")
-
-            if (cmd == 1):  # TOC CRC32 request
-                fakecrc = 0
-                if (pk.port == CRTPPort.LOGGING):
-                    tocLen = len(self.fakeLogToc)
-                    fakecrc = 0xAAAAAAAA
-                if (pk.port == CRTPPort.PARAM):
-                    tocLen = len(self.fakeParamToc)
-                    fakecrc = 0xBBBBBBBB
-
-                if self._random_toc_crcs:
-                    fakecrc = int(''.join(
-                        random.choice("ABCDEF" + string.digits) for x in
-                        range(8)), 16)
-                    logger.debug("Generated random TOC CRC: 0x%x", fakecrc)
-                logger.info("TOC[%d]: Requesting TOC CRC, sending back fake"
-                            " stuff: %d", pk.port, len(self.fakeLogToc))
-                p = CRTPPacket()
-                p.set_header(pk.port, 0)
-                p.data = struct.pack('<BBIBB', 1, tocLen, fakecrc, 16, 24)
-                self._send_packet(p)
-
-    def handleParam(self, pk):
-        chan = pk.channel
-        cmd = pk.data[0]
-        logger.debug("PARAM: Port=%d, Chan=%d, cmd=%d", pk.port,
-                     chan, cmd)
-        if (chan == 0):  # TOC Access
-            self._handle_toc_access(pk)
-        elif (chan == 2):  # Settings access
-            varId = pk.data[0]
-            formatStr = ParamTocElement.types[
-                self.fakeParamToc[varId]["vartype"]][1]
-            newvalue = struct.unpack(formatStr, pk.data[1:])[0]
-            self.fakeParamToc[varId]["value"] = newvalue
-            logger.info("PARAM: New value [%s] for param [%d]", newvalue,
-                        varId)
-            # Send back the new value
-            p = CRTPPacket()
-            p.set_header(pk.port, 2)
-            p.data += struct.pack("<B", varId)
-            p.data += struct.pack(formatStr, self.fakeParamToc[varId]["value"])
-            self._send_packet(p)
-        elif (chan == 1):
-            p = CRTPPacket()
-            p.set_header(pk.port, 1)
-            varId = cmd
-            p.data.append(varId)
-            formatStr = ParamTocElement.types[
-                self.fakeParamToc[varId]["vartype"]][1]
-            p.data += struct.pack(formatStr, self.fakeParamToc[varId]["value"])
-            logger.info("PARAM: Getting value for %d", varId)
-            self._send_packet(p)
-
-    def _handle_logging(self, pk):
-        chan = pk.channel
-        cmd = pk.data[0]
-        logger.debug("LOG: Chan=%d, cmd=%d", chan, cmd)
-        if (chan == 0):  # TOC Access
-            self._handle_toc_access(pk)
-        elif (chan == 1):  # Settings access
-            if (cmd == 0):
-                blockId = pk.data[1]
-                if blockId not in self._added_blocks:
-                    self._added_blocks.append(blockId)
-                    logger.info("LOG:Adding block id=%d", blockId)
-                    listofvars = pk.data[3:]
-                    fakeThread = _FakeLoggingDataThread(self.queue, blockId,
-                                                        listofvars,
-                                                        self.fakeLogToc)
-                    self.fakeLoggingThreads.append(fakeThread)
-                    fakeThread.start()
-                    # Anser that everything is ok
-                    p = CRTPPacket()
-                    p.set_header(5, 1)
-                    p.data = struct.pack('<BBB', 0, blockId, 0x00)
-                    self._send_packet(p)
-                else:
-                    p = CRTPPacket()
-                    p.set_header(5, 1)
-                    p.data = struct.pack('<BBB', 0, blockId, errno.EEXIST)
-                    self._send_packet(p)
-            if (cmd == 1):
-                logger.warning("LOG: Appending block not implemented!")
-            if (cmd == 2):
-                blockId = pk.data[1]
-                logger.info("LOG: Should delete block %d", blockId)
-                success = False
-                for fb in self.fakeLoggingThreads:
-                    if (fb.blockId == blockId):
-                        fb._disable_logging()
-                        fb.stop()
-
-                        p = CRTPPacket()
-                        p.set_header(5, 1)
-                        p.data = struct.pack('<BBB', cmd, blockId, 0x00)
-                        self._send_packet(p)
-                        logger.info("LOG: Deleted block=%d", blockId)
-                        success = True
-                if (success is False):
-                    logger.warning("LOG: Could not delete block=%d, not found",
-                                   blockId)
-                    # TODO: Send back error code
-
-            if (cmd == 3):
-                blockId = pk.data[1]
-                period = pk.data[2] * 10  # Sent as multiple of 10 ms
-                logger.info("LOG:Starting block %d", blockId)
-                success = False
-                for fb in self.fakeLoggingThreads:
-                    if (fb.blockId == blockId):
-                        fb._enable_logging()
-                        fb.period = period
-                        p = CRTPPacket()
-                        p.set_header(5, 1)
-                        p.data = struct.pack('<BBB', cmd, blockId, 0x00)
-                        self._send_packet(p)
-                        logger.info("LOG:Started block=%d", blockId)
-                        success = True
-                if (success is False):
-                    logger.info("LOG:Could not start block=%d, not found",
-                                blockId)
-                    # TODO: Send back error code
-            if (cmd == 4):
-                blockId = pk.data[1]
-                logger.info("LOG:Pausing block %d", blockId)
-                success = False
-                for fb in self.fakeLoggingThreads:
-                    if (fb.blockId == blockId):
-                        fb._disable_logging()
-                        p = CRTPPacket()
-                        p.set_header(5, 1)
-                        p.data = struct.pack('<BBB', cmd, blockId, 0x00)
-                        self._send_packet(p)
-                        logger.info("LOG:Pause block=%d", blockId)
-                        success = True
-                if (success is False):
-                    logger.warning("LOG:Could not pause block=%d, not found",
-                                   blockId)
-                    # TODO: Send back error code
-            if (cmd == 5):
-                logger.info("LOG: Reset logging, but doing nothing")
-                p = CRTPPacket()
-                p.set_header(5, 1)
-                p.data = struct.pack('<BBB', cmd, 0x00, 0x00)
-                self._send_packet(p)
-
-        elif (chan > 1):
-            logger.warning("LOG: Uplink packets with channels > 1 not"
-                           " supported!")
-
-    def _send_packet(self, pk):
-        # Do not delay log data
-        if (self._random_answer_delay and pk.port != 0x05 and
-                pk.channel != 0x02):
-            # Calculate a delay between 0ms and 250ms
-            delay = random.randint(0, 250) / 1000.0
-            logger.debug("Delaying answer %.2fms", delay * 1000)
-            time.sleep(delay)
-        self.queue.put(pk)
-
-
-class _FakeLoggingDataThread(Thread):
-    """Thread that will send back fake logging data via CRTP"""
-
-    def __init__(self, outQueue, blockId, listofvars, fakeLogToc):
-        Thread.__init__(self)
-        self.starttime = datetime.now()
-        self.outQueue = outQueue
-        self.setDaemon(True)
-        self.mod = 0
-        self.blockId = blockId
-        self.period = 0
-        self.listofvars = listofvars
-        self.shouldLog = False
-        self.fakeLogToc = fakeLogToc
-        self.fakeLoggingData = []
-        self.setName("Fakelog block=%d" % blockId)
-        self.shouldQuit = False
-
-        logging.info("FakeDataLoggingThread created for blockid=%d", blockId)
-        i = 0
-        while (i < len(listofvars)):
-            varType = listofvars[i]
-            var_stored_as = (varType >> 8)
-            var_fetch_as = (varType & 0xFF)
-            if (var_stored_as > 0):
-                addr = struct.unpack("<I", listofvars[i + 1:i + 5])
-                logger.debug("FakeLoggingThread: We should log a memory addr"
-                             " 0x%04X", addr)
-                self.fakeLoggingData.append([memlogging[var_fetch_as],
-                                             memlogging[var_fetch_as]["min"],
-                                             1])
-                i = i + 5
-            else:
-                varId = listofvars[i]
-                logger.debug("FakeLoggingThread: We should log variable from"
-                             " TOC: id=%d, type=0x%02X", varId, varType)
-                for t in self.fakeLogToc:
-                    if (varId == t["varid"]):
-                        # Each touple will have var data and current fake value
-                        self.fakeLoggingData.append([t, t["min"], 1])
-                i = i + 2
-
-    def _enable_logging(self):
-        self.shouldLog = True
-        logging.info("_FakeLoggingDataThread: Enable thread [%s] at period %d",
-                     self.getName(), self.period)
-
-    def _disable_logging(self):
-        self.shouldLog = False
-        logging.info("_FakeLoggingDataThread: Disable thread [%s]",
-                     self.getName())
-
-    def stop(self):
-        self.shouldQuit = True
-
-    def run(self):
-        while (self.shouldQuit is False):
-            if (self.shouldLog is True):
-
-                p = CRTPPacket()
-                p.set_header(5, 2)
-                p.data = struct.pack('<B', self.blockId)
-                timestamp = int(
-                    (datetime.now() - self.starttime).total_seconds() * 1000)
-                p.data += struct.pack('BBB', timestamp & 0xff,
-                                      (timestamp >> 8) & 0x0ff,
-                                      (timestamp >> 16) & 0x0ff)  # Timestamp
-
-                for d in self.fakeLoggingData:
-                    # Set new value
-                    d[1] = d[1] + d[0]["mod"] * d[2]
-                    # Obej the limitations
-                    if (d[1] > d[0]["max"]):
-                        d[1] = d[0]["max"]  # Limit value
-                        d[2] = -1  # Switch direction
-                    if (d[1] < d[0]["min"]):
-                        d[1] = d[0]["min"]  # Limit value
-                        d[2] = 1  # Switch direction
-                    # Pack value
-                    formatStr = LogTocElement.types[d[0]["vartype"]][1]
-                    p.data += struct.pack(formatStr, d[1])
-                self.outQueue.put(p)
-            time.sleep(self.period / 1000.0)  # Period in ms here
-
-
-class FakeConsoleThread(Thread):
-    """Thread that will send back fake console data via CRTP"""
-
-    def __init__(self, outQueue):
-        Thread.__init__(self)
-        self.outQueue = outQueue
-        self.setDaemon(True)
-        self._should_run = True
-
-    def stop(self):
-        self._shoud_run = False
-
-    def run(self):
-        # Temporary hack to test GPS from firmware by sending NMEA string
-        # on console
-        long_val = 0
-        lat_val = 0
-        alt_val = 0
-
-        while (self._should_run):
-            long_val += 1
-            lat_val += 1
-            alt_val += 1.0
-
-            long_string = "5536.677%d" % (long_val % 99)
-            lat_string = "01259.645%d" % (lat_val % 99)
-            alt_string = "%.1f" % (alt_val % 100.0)
-
-            # Copy of what is sent from the module, but note that only
-            # the GPGGA message is being simulated, the others are fixed...
-            self._send_text("Time is now %s\n" % datetime.now())
-            self._send_text("$GPVTG,,T,,M,0.386,N,0.716,K,A*2E\n")
-            self._send_text("$GPGGA,135544.0")
-            self._send_text("0,%s,N,%s,E,1,04,2.62,3.6,M,%s,M,,*58\n" % (
-                long_string, lat_string, alt_string))
-            self._send_text(
-                "$GPGSA,A,3,31,20,23,07,,,,,,,,,3.02,2.62,1.52*05\n")
-            self._send_text("$GPGSV,2,1,07,07,09,181,15,13,63,219,26,16,02,"
-                            "097,,17,05,233,20*7E\n")
-            self._send_text(
-                "$GPGSV,2,2,07,20,42,119,35,23,77,097,27,31,12,032,19*47\n")
-            self._send_text(
-                "$GPGLL,5536.67734,N,01259.64578,E,135544.00,A,A*68\n")
-
-            time.sleep(2)
-
-    def _send_text(self, message):
-        p = CRTPPacket()
-        p.set_header(0, 0)
-
-        us = "%is" % len(message)
-        # This might be done prettier ;-)
-        p.data = message
-
-        self.outQueue.put(p)
diff --git a/src/cflib/cflib/crtp/exceptions.py b/src/cflib/cflib/crtp/exceptions.py
deleted file mode 100644
index 876f9ee000e4e96560291cd0956899c7611ef9f5..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crtp/exceptions.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-Exception used when the URI is not for the current driver
-(ie. radio:// for the serial driver ...)
-It basically means that an other driver could do the job
-It does NOT means that the URI is good or bad
-"""
-
-__author__ = 'Bitcraze AB'
-__all__ = ['WrongUriType', 'CommunicationException']
-
-
-class WrongUriType(Exception):
-    """ Wrong type of URI for this interface """
-    pass
-
-
-class CommunicationException(Exception):
-    """ Communication problem when communicating with a Crazyflie """
-    pass
diff --git a/src/cflib/cflib/crtp/radiodriver.py b/src/cflib/cflib/crtp/radiodriver.py
deleted file mode 100644
index 019d67cbcf2416ad60ef17e1c002c23219ec7d2a..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crtp/radiodriver.py
+++ /dev/null
@@ -1,482 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-"""
-Crazyradio CRTP link driver.
-
-This driver is used to communicate with the Crazyflie using the Crazyradio
-USB dongle.
-"""
-import array
-import binascii
-import collections
-import logging
-import re
-import struct
-import sys
-import threading
-
-from cflib.crtp.crtpdriver import CRTPDriver
-from cflib.drivers.crazyradio import Crazyradio
-from usb import USBError
-
-from .crtpstack import CRTPPacket
-from .exceptions import WrongUriType
-
-if sys.version_info < (3,):
-    import Queue as queue
-else:
-    import queue
-
-
-__author__ = 'Bitcraze AB'
-__all__ = ['RadioDriver']
-
-logger = logging.getLogger(__name__)
-
-
-class RadioDriver(CRTPDriver):
-    """ Crazyradio link driver """
-
-    def __init__(self):
-        """ Create the link driver """
-        CRTPDriver.__init__(self)
-        self.cradio = None
-        self.uri = ""
-        self.link_error_callback = None
-        self.link_quality_callback = None
-        self.in_queue = None
-        self.out_queue = None
-        self._thread = None
-        self.needs_resending = True
-
-    def connect(self, uri, link_quality_callback, link_error_callback):
-        """
-        Connect the link driver to a specified URI of the format:
-        radio://<dongle nbr>/<radio channel>/[250K,1M,2M]
-
-        The callback for linkQuality can be called at any moment from the
-        driver to report back the link quality in percentage. The
-        callback from linkError will be called when a error occurs with
-        an error message.
-        """
-
-        # check if the URI is a radio URI
-        if not re.search("^radio://", uri):
-            raise WrongUriType("Not a radio URI")
-
-        # Open the USB dongle
-        if not re.search("^radio://([0-9]+)((/([0-9]+))"
-                         "((/(250K|1M|2M))?(/([A-F0-9]+))?)?)?$", uri):
-            raise WrongUriType('Wrong radio URI format!')
-
-        uri_data = re.search("^radio://([0-9]+)((/([0-9]+))"
-                             "((/(250K|1M|2M))?(/([A-F0-9]+))?)?)?$", uri)
-
-        self.uri = uri
-
-        channel = 2
-        if uri_data.group(4):
-            channel = int(uri_data.group(4))
-
-        datarate = Crazyradio.DR_2MPS
-        if uri_data.group(7) == "250K":
-            datarate = Crazyradio.DR_250KPS
-        if uri_data.group(7) == "1M":
-            datarate = Crazyradio.DR_1MPS
-        if uri_data.group(7) == "2M":
-            datarate = Crazyradio.DR_2MPS
-
-        if self.cradio is None:
-            self.cradio = Crazyradio(devid=int(uri_data.group(1)))
-        else:
-            raise Exception("Link already open!")
-
-        if self.cradio.version >= 0.4:
-            self.cradio.set_arc(10)
-        else:
-            logger.warning("Radio version <0.4 will be obsoleted soon!")
-
-        self.cradio.set_channel(channel)
-
-        self.cradio.set_data_rate(datarate)
-
-        if uri_data.group(9):
-            addr = str(uri_data.group(9))
-            new_addr = struct.unpack("<BBBBB", binascii.unhexlify(addr))
-            self.cradio.set_address(new_addr)
-
-        # Prepare the inter-thread communication queue
-        self.in_queue = queue.Queue()
-        # Limited size out queue to avoid "ReadBack" effect
-        self.out_queue = queue.Queue(1)
-
-        # Launch the comm thread
-        self._thread = _RadioDriverThread(self.cradio, self.in_queue,
-                                          self.out_queue,
-                                          link_quality_callback,
-                                          link_error_callback,
-                                          self)
-        self._thread.start()
-
-        self.link_error_callback = link_error_callback
-
-    def receive_packet(self, time=0):
-        """
-        Receive a packet though the link. This call is blocking but will
-        timeout and return None if a timeout is supplied.
-        """
-        if time == 0:
-            try:
-                return self.in_queue.get(False)
-            except queue.Empty:
-                return None
-        elif time < 0:
-            try:
-                return self.in_queue.get(True)
-            except queue.Empty:
-                return None
-        else:
-            try:
-                return self.in_queue.get(True, time)
-            except queue.Empty:
-                return None
-
-    def send_packet(self, pk):
-        """ Send the packet pk though the link """
-        # if self.out_queue.full():
-        #    self.out_queue.get()
-        if (self.cradio is None):
-            return
-
-        try:
-            self.out_queue.put(pk, True, 2)
-        except queue.Full:
-            if self.link_error_callback:
-                self.link_error_callback("RadioDriver: Could not send packet"
-                                         " to copter")
-
-    def pause(self):
-        self._thread.stop()
-        self._thread = None
-
-    def restart(self):
-        if self._thread:
-            return
-
-        self._thread = _RadioDriverThread(self.cradio, self.in_queue,
-                                          self.out_queue,
-                                          self.link_quality_callback,
-                                          self.link_error_callback,
-                                          self)
-        self._thread.start()
-
-    def close(self):
-        """ Close the link. """
-        # Stop the comm thread
-        self._thread.stop()
-
-        # Close the USB dongle
-        try:
-            if self.cradio:
-                self.cradio.close()
-        except:
-            # If we pull out the dongle we will not make this call
-            pass
-        self.cradio = None
-
-        while not self.out_queue.empty():
-            self.out_queue.get()
-
-        # Clear callbacks
-        self.link_error_callback = None
-        self.link_quality_callback = None
-
-    def _scan_radio_channels(self, start=0, stop=125):
-        """ Scan for Crazyflies between the supplied channels. """
-        return list(self.cradio.scan_channels(start, stop, (0xff,)))
-
-    def scan_selected(self, links):
-        to_scan = ()
-        for l in links:
-            one_to_scan = {}
-            uri_data = re.search("^radio://([0-9]+)((/([0-9]+))"
-                                 "(/(250K|1M|2M))?)?$",
-                                 l)
-
-            one_to_scan["channel"] = int(uri_data.group(4))
-
-            datarate = Crazyradio.DR_2MPS
-            if uri_data.group(6) == "250K":
-                datarate = Crazyradio.DR_250KPS
-            if uri_data.group(6) == "1M":
-                datarate = Crazyradio.DR_1MPS
-            if uri_data.group(6) == "2M":
-                datarate = Crazyradio.DR_2MPS
-
-            one_to_scan["datarate"] = datarate
-
-            to_scan += (one_to_scan,)
-
-        found = self.cradio.scan_selected(to_scan, (0xFF, 0xFF, 0xFF))
-
-        ret = ()
-        for f in found:
-            dr_string = ""
-            if f["datarate"] == Crazyradio.DR_2MPS:
-                dr_string = "2M"
-            if f["datarate"] == Crazyradio.DR_250KPS:
-                dr_string = "250K"
-            if f["datarate"] == Crazyradio.DR_1MPS:
-                dr_string = "1M"
-
-            ret += ("radio://0/{}/{}".format(f["channel"], dr_string),)
-
-        return ret
-
-    def scan_interface(self, address):
-        """ Scan interface for Crazyflies """
-        if self.cradio is None:
-            try:
-                self.cradio = Crazyradio()
-            except Exception:
-                return []
-        else:
-            raise Exception("Cannot scann for links while the link is open!")
-
-        # FIXME: implements serial number in the Crazyradio driver!
-        serial = "N/A"
-
-        logger.info("v%s dongle with serial %s found", self.cradio.version,
-                    serial)
-        found = []
-
-        if address is not None:
-            addr = "{:X}".format(address)
-            new_addr = struct.unpack("<BBBBB", binascii.unhexlify(addr))
-            self.cradio.set_address(new_addr)
-
-        self.cradio.set_arc(1)
-
-        self.cradio.set_data_rate(self.cradio.DR_250KPS)
-
-        if address is None or address == 0xE7E7E7E7E7:
-            found += [["radio://0/{}/250K".format(c), ""]
-                      for c in self._scan_radio_channels()]
-            self.cradio.set_data_rate(self.cradio.DR_1MPS)
-            found += [["radio://0/{}/1M".format(c), ""]
-                      for c in self._scan_radio_channels()]
-            self.cradio.set_data_rate(self.cradio.DR_2MPS)
-            found += [["radio://0/{}/2M".format(c), ""]
-                      for c in self._scan_radio_channels()]
-        else:
-            found += [["radio://0/{}/250K/{:X}".format(c, address), ""]
-                      for c in self._scan_radio_channels()]
-            self.cradio.set_data_rate(self.cradio.DR_1MPS)
-            found += [["radio://0/{}/1M/{:X}".format(c, address), ""]
-                      for c in self._scan_radio_channels()]
-            self.cradio.set_data_rate(self.cradio.DR_2MPS)
-            found += [["radio://0/{}/2M/{:X}".format(c, address), ""]
-                      for c in self._scan_radio_channels()]
-
-        self.cradio.close()
-        self.cradio = None
-
-        return found
-
-    def get_status(self):
-        if self.cradio is None:
-            try:
-                self.cradio = Crazyradio()
-            except USBError as e:
-                return "Cannot open Crazyradio. Permission problem?" \
-                       " ({})".format(str(e))
-            except Exception as e:
-                return str(e)
-
-        ver = self.cradio.version
-        self.cradio.close()
-        self.cradio = None
-
-        return "Crazyradio version {}".format(ver)
-
-    def get_name(self):
-        return "radio"
-
-
-# Transmit/receive radio thread
-class _RadioDriverThread(threading.Thread):
-    """
-    Radio link receiver thread used to read data from the
-    Crazyradio USB driver. """
-
-    RETRYCOUNT_BEFORE_DISCONNECT = 10
-
-    def __init__(self, cradio, inQueue, outQueue, link_quality_callback,
-                 link_error_callback, link):
-        """ Create the object """
-        threading.Thread.__init__(self)
-        self.cradio = cradio
-        self.in_queue = inQueue
-        self.out_queue = outQueue
-        self.sp = False
-        self.link_error_callback = link_error_callback
-        self.link_quality_callback = link_quality_callback
-        self.retryBeforeDisconnect = self.RETRYCOUNT_BEFORE_DISCONNECT
-        self.retries = collections.deque()
-        self.retry_sum = 0
-
-        self.curr_up = 0
-        self.curr_down = 1
-
-        self.has_safelink = False
-        self._link = link
-
-    def stop(self):
-        """ Stop the thread """
-        self.sp = True
-        try:
-            self.join()
-        except Exception:
-            pass
-
-    def _send_packet_safe(self, cr, packet):
-        """
-        Adds 1bit counter to CRTP header to guarantee that no ack (downlink)
-        payload are lost and no uplink packet are duplicated.
-        The caller should resend packet if not acked (ie. same as with a
-        direct call to crazyradio.send_packet)
-        """
-        packet = bytearray(packet)
-        packet[0] &= 0xF3
-        packet[0] |= self.curr_up << 3 | self.curr_down << 2
-        resp = cr.send_packet(packet)
-        if resp and resp.ack and len(resp.data) and \
-           (resp.data[0] & 0x04) == (self.curr_down << 2):
-            self.curr_down = 1 - self.curr_down
-        if resp and resp.ack:
-            self.curr_up = 1 - self.curr_up
-
-        return resp
-
-    def run(self):
-        """ Run the receiver thread """
-        dataOut = array.array('B', [0xFF])
-        waitTime = 0
-        emptyCtr = 0
-
-        # Try up to 10 times to enable the safelink mode
-        for _ in range(10):
-            resp = self.cradio.send_packet((0xff, 0x05, 0x01))
-            if resp and resp.data and tuple(resp.data) == (0xff, 0x05, 0x01):
-                self.has_safelink = True
-                self.curr_up = 0
-                self.curr_down = 0
-                break
-        logging.info("Has safelink: {}".format(self.has_safelink))
-        self._link.needs_resending = not self.has_safelink
-
-        while (True):
-            if (self.sp):
-                break
-
-            try:
-                if self.has_safelink:
-                    ackStatus = self._send_packet_safe(self.cradio, dataOut)
-                else:
-                    ackStatus = self.cradio.send_packet(dataOut)
-            except Exception as e:
-                import traceback
-
-                self.link_error_callback(
-                    "Error communicating with crazy radio ,it has probably "
-                    "been unplugged!\nException:%s\n\n%s" % (
-                        e, traceback.format_exc()))
-
-            # Analise the in data packet ...
-            if ackStatus is None:
-                if (self.link_error_callback is not None):
-                    self.link_error_callback("Dongle communication error"
-                                             " (ackStatus==None)")
-                continue
-
-            if (self.link_quality_callback is not None):
-                # track the mean of a sliding window of the last N packets
-                retry = 10 - ackStatus.retry
-                self.retries.append(retry)
-                self.retry_sum += retry
-                if len(self.retries) > 100:
-                    self.retry_sum -= self.retries.popleft()
-                link_quality = float(self.retry_sum) / len(self.retries) * 10
-                self.link_quality_callback(link_quality)
-
-            # If no copter, retry
-            if ackStatus.ack is False:
-                self.retryBeforeDisconnect = self.retryBeforeDisconnect - 1
-                if (self.retryBeforeDisconnect == 0 and
-                        self.link_error_callback is not None):
-                    self.link_error_callback("Too many packets lost")
-                continue
-            self.retryBeforeDisconnect = self.RETRYCOUNT_BEFORE_DISCONNECT
-
-            data = ackStatus.data
-
-            # If there is a copter in range, the packet is analysed and the
-            # next packet to send is prepared
-            if (len(data) > 0):
-                inPacket = CRTPPacket(data[0], list(data[1:]))
-                # print "<- " + inPacket.__str__()
-                self.in_queue.put(inPacket)
-                waitTime = 0
-                emptyCtr = 0
-            else:
-                emptyCtr += 1
-                if (emptyCtr > 10):
-                    emptyCtr = 10
-                    # Relaxation time if the last 10 packet where empty
-                    waitTime = 0.01
-                else:
-                    waitTime = 0
-
-            # get the next packet to send of relaxation (wait 10ms)
-            outPacket = None
-            try:
-                outPacket = self.out_queue.get(True, waitTime)
-            except queue.Empty:
-                outPacket = None
-
-            dataOut = array.array('B')
-
-            if outPacket:
-                # print "-> " + outPacket.__str__()
-                dataOut.append(outPacket.header)
-                for X in outPacket.data:
-                    if type(X) == int:
-                        dataOut.append(X)
-                    else:
-                        dataOut.append(ord(X))
-            else:
-                dataOut.append(0xFF)
diff --git a/src/cflib/cflib/crtp/serialdriver.py b/src/cflib/cflib/crtp/serialdriver.py
deleted file mode 100644
index 29d5262774a7b12202adedc203e98e062ef7ec59..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crtp/serialdriver.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-"""
-An early serial link driver. This could still be used (after some fixing) to
-run high-speed CRTP with the Crazyflie. The UART can be run at 2Mbit.
-"""
-import re
-
-from .crtpdriver import CRTPDriver
-from .exceptions import WrongUriType
-
-__author__ = 'Bitcraze AB'
-__all__ = ['SerialDriver']
-
-
-class SerialDriver(CRTPDriver):
-
-    def __init__(self):
-        None
-
-    def connect(self, uri, linkQualityCallback, linkErrorCallback):
-        # check if the URI is a serial URI
-        if not re.search("^serial://", uri):
-            raise WrongUriType("Not a serial URI")
-
-        # Check if it is a valid serial URI
-        uriRe = re.search("^serial://([a-z A-Z 0-9]+)/?([0-9]+)?$", uri)
-        if not uriRe:
-            raise Exception("Invalid serial URI")
-
-    def get_name(self):
-        return "serial"
-
-    def scan_interface(self, address):
-        return []
diff --git a/src/cflib/cflib/crtp/udpdriver.py b/src/cflib/cflib/crtp/udpdriver.py
deleted file mode 100644
index 8f1fb82d0eba9d67c5c5b1e2d65aa7cbdc84e058..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crtp/udpdriver.py
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-""" CRTP UDP Driver. Work either with the UDP server or with an UDP device
-See udpserver.py for the protocol"""
-import re
-import struct
-import sys
-from socket import socket
-
-from .crtpdriver import CRTPDriver
-from .crtpstack import CRTPPacket
-from .exceptions import WrongUriType
-if sys.version_info < (3,):
-    import Queue as queue
-else:
-    import queue
-
-__author__ = 'Bitcraze AB'
-__all__ = ['UdpDriver']
-
-
-class UdpDriver(CRTPDriver):
-
-    def __init__(self):
-        None
-
-    def connect(self, uri, linkQualityCallback, linkErrorCallback):
-        # check if the URI is a radio URI
-        if not re.search("^udp://", uri):
-            raise WrongUriType("Not an UDP URI")
-
-        self.queue = queue.Queue()
-        self.socket = socket(socket.AF_INET, socket.SOCK_DGRAM)
-        self.addr = ("localhost", 7777)
-        self.socket.connect(self.addr)
-
-        # Add this to the server clients list
-        self.socket.sendto("\xFF\x01\x01\x01", self.addr)
-
-    def receive_packet(self, time=0):
-        data, addr = self.socket.recvfrom(1024)
-
-        if data:
-            data = struct.unpack('b' * (len(data) - 1), data[0:len(data) - 1])
-            pk = CRTPPacket()
-            pk.port = data[0]
-            pk.data = data[1:]
-            return pk
-
-        try:
-            if time == 0:
-                return self.rxqueue.get(False)
-            elif time < 0:
-                while True:
-                    return self.rxqueue.get(True, 10)
-            else:
-                return self.rxqueue.get(True, time)
-        except queue.Empty:
-            return None
-
-    def send_packet(self, pk):
-        raw = (pk.port,) + struct.unpack("B" * len(pk.data), pk.data)
-
-        cksum = 0
-        for i in raw:
-            cksum += i
-
-        cksum %= 256
-
-        data = ''.join(chr(v) for v in (raw + (cksum,)))
-
-        # print tuple(data)
-        self.socket.sendto(data, self.addr)
-
-    def close(self):
-        # Remove this from the server clients list
-        self.socket.sendto("\xFF\x01\x02\x02", self.addr)
-
-    def get_name(self):
-        return "udp"
-
-    def scan_interface(self, address):
-        return []
diff --git a/src/cflib/cflib/crtp/usbdriver.py b/src/cflib/cflib/crtp/usbdriver.py
deleted file mode 100644
index 083d9fad8e5f97c42c6ab1971f353cbdd4b0292c..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/crtp/usbdriver.py
+++ /dev/null
@@ -1,263 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-Crazyflie USB driver.
-
-This driver is used to communicate with the Crazyflie using the USB connection.
-"""
-
-import logging
-
-from cflib.crtp.crtpdriver import CRTPDriver
-from .crtpstack import CRTPPacket
-from .exceptions import WrongUriType
-import threading
-import sys
-import re
-import time
-
-from cflib.drivers.cfusb import CfUsb
-from usb import USBError
-if sys.version_info < (3,):
-    import Queue as queue
-else:
-    import queue
-
-__author__ = 'Bitcraze AB'
-__all__ = ['UsbDriver']
-
-logger = logging.getLogger(__name__)
-
-
-class UsbDriver(CRTPDriver):
-    """ Crazyradio link driver """
-
-    def __init__(self):
-        """ Create the link driver """
-        CRTPDriver.__init__(self)
-        self.cfusb = None
-        self.uri = ""
-        self.link_error_callback = None
-        self.link_quality_callback = None
-        self.in_queue = None
-        self.out_queue = None
-        self._thread = None
-        self.needs_resending = False
-
-    def connect(self, uri, link_quality_callback, link_error_callback):
-        """
-        Connect the link driver to a specified URI of the format:
-        radio://<dongle nbr>/<radio channel>/[250K,1M,2M]
-
-        The callback for linkQuality can be called at any moment from the
-        driver to report back the link quality in percentage. The
-        callback from linkError will be called when a error occues with
-        an error message.
-        """
-
-        # check if the URI is a radio URI
-        if not re.search("^usb://", uri):
-            raise WrongUriType("Not a radio URI")
-
-        # Open the USB dongle
-        if not re.search("^usb://([0-9]+)$",
-                         uri):
-            raise WrongUriType('Wrong radio URI format!')
-
-        uri_data = re.search("^usb://([0-9]+)$",
-                             uri)
-
-        self.uri = uri
-
-        if self.cfusb is None:
-            self.cfusb = CfUsb(devid=int(uri_data.group(1)))
-            if self.cfusb.dev:
-                self.cfusb.set_crtp_to_usb(True)
-            else:
-                self.cfusb = None
-                raise Exception("Could not open {}".format(self.uri))
-
-        else:
-            raise Exception("Link already open!")
-
-        # Prepare the inter-thread communication queue
-        self.in_queue = queue.Queue()
-        # Limited size out queue to avoid "ReadBack" effect
-        self.out_queue = queue.Queue(50)
-
-        # Launch the comm thread
-        self._thread = _UsbReceiveThread(self.cfusb, self.in_queue,
-                                         link_quality_callback,
-                                         link_error_callback)
-        self._thread.start()
-
-        self.link_error_callback = link_error_callback
-
-    def receive_packet(self, time=0):
-        """
-        Receive a packet though the link. This call is blocking but will
-        timeout and return None if a timeout is supplied.
-        """
-        if time == 0:
-            try:
-                return self.in_queue.get(False)
-            except queue.Empty:
-                return None
-        elif time < 0:
-            try:
-                return self.in_queue.get(True)
-            except queue.Empty:
-                return None
-        else:
-            try:
-                return self.in_queue.get(True, time)
-            except queue.Empty:
-                return None
-
-    def send_packet(self, pk):
-        """ Send the packet pk though the link """
-        # if self.out_queue.full():
-        #    self.out_queue.get()
-        if (self.cfusb is None):
-            return
-
-        try:
-            dataOut = (pk.header,)
-            dataOut += pk.datat
-            self.cfusb.send_packet(dataOut)
-        except queue.Full:
-            if self.link_error_callback:
-                self.link_error_callback(
-                    "UsbDriver: Could not send packet to Crazyflie")
-
-    def pause(self):
-        self._thread.stop()
-        self._thread = None
-
-    def restart(self):
-        if self._thread:
-            return
-
-        self._thread = _UsbReceiveThread(self.cfusb, self.in_queue,
-                                         self.link_quality_callback,
-                                         self.link_error_callback)
-        self._thread.start()
-
-    def close(self):
-        """ Close the link. """
-        # Stop the comm thread
-        self._thread.stop()
-
-        # Close the USB dongle
-        try:
-            if self.cfusb:
-                self.cfusb.set_crtp_to_usb(False)
-                self.cfusb.close()
-        except Exception as e:
-            # If we pull out the dongle we will not make this call
-            logger.info("Could not close {}".format(e))
-            pass
-        self.cfusb = None
-
-    def scan_interface(self, address):
-        """ Scan interface for Crazyflies """
-        if self.cfusb is None:
-            try:
-                self.cfusb = CfUsb()
-            except Exception as e:
-                logger.warn(
-                    "Exception while scanning for Crazyflie USB: {}".format(
-                        str(e)))
-                return []
-        else:
-            raise Exception("Cannot scan for links while the link is open!")
-
-        # FIXME: implements serial number in the Crazyradio driver!
-        # serial = "N/A"
-
-        found = self.cfusb.scan()
-
-        self.cfusb.close()
-        self.cfusb = None
-
-        return found
-
-    def get_status(self):
-        return "No information available"
-
-    def get_name(self):
-        return "UsbCdc"
-
-
-# Transmit/receive radio thread
-class _UsbReceiveThread(threading.Thread):
-    """
-    Radio link receiver thread used to read data from the
-    Crazyradio USB driver. """
-
-    # RETRYCOUNT_BEFORE_DISCONNECT = 10
-
-    def __init__(self, cfusb, inQueue, link_quality_callback,
-                 link_error_callback):
-        """ Create the object """
-        threading.Thread.__init__(self)
-        self.cfusb = cfusb
-        self.in_queue = inQueue
-        self.sp = False
-        self.link_error_callback = link_error_callback
-        self.link_quality_callback = link_quality_callback
-
-    def stop(self):
-        """ Stop the thread """
-        self.sp = True
-        try:
-            self.join()
-        except Exception:
-            pass
-
-    def run(self):
-        """ Run the receiver thread """
-
-        while (True):
-            if (self.sp):
-                break
-            try:
-                # Blocking until USB data available
-                data = self.cfusb.receive_packet()
-                if len(data) > 0:
-                    pk = CRTPPacket(data[0], list(data[1:]))
-                    self.in_queue.put(pk)
-            except Exception as e:
-                import traceback
-
-                self.link_error_callback(
-                    "Error communicating with the Crazyflie"
-                    " ,it has probably been unplugged!\n"
-                    "Exception:%s\n\n%s" % (e,
-                                            traceback.format_exc()))
diff --git a/src/cflib/cflib/drivers/__init__.py b/src/cflib/cflib/drivers/__init__.py
deleted file mode 100644
index f074d797a973bcba4f86ae9ed1bcd86112840a72..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/drivers/__init__.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-Drivers for the link interfaces that can be used by CRTP.
-"""
diff --git a/src/cflib/cflib/drivers/cfusb.py b/src/cflib/cflib/drivers/cfusb.py
deleted file mode 100644
index 8e620abf1900ae56e809db4ce89c728831fdb6e5..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/drivers/cfusb.py
+++ /dev/null
@@ -1,196 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-USB driver for the Crazyflie.
-"""
-
-import os
-import usb
-import logging
-import sys
-import time
-import array
-import binascii
-
-__author__ = 'Bitcraze AB'
-__all__ = ['CfUsb']
-
-logger = logging.getLogger(__name__)
-
-USB_VID = 0x0483
-USB_PID = 0x5740
-
-try:
-    import usb.core
-
-    pyusb_backend = None
-    if os.name == "nt":
-        import usb.backend.libusb0 as libusb0
-
-        pyusb_backend = libusb0.get_backend()
-    pyusb1 = True
-except:
-    pyusb1 = False
-
-
-def _find_devices():
-    """
-    Returns a list of CrazyRadio devices currently connected to the computer
-    """
-    ret = []
-
-    logger.info("Looking for devices....")
-
-    if pyusb1:
-        for d in usb.core.find(idVendor=USB_VID, idProduct=USB_PID, find_all=1,
-                               backend=pyusb_backend):
-            ret.append(d)
-    else:
-        busses = usb.busses()
-        for bus in busses:
-            for device in bus.devices:
-                if device.idVendor == USB_VID:
-                    if device.idProduct == USB_PID:
-                        ret += [device, ]
-
-    return ret
-
-
-class CfUsb:
-    """ Used for communication with the Crazyradio USB dongle """
-
-    def __init__(self, device=None, devid=0):
-        """ Create object and scan for USB dongle if no device is supplied """
-        self.dev = None
-        self.handle = None
-        self._last_write = 0
-        self._last_read = 0
-
-        if device is None:
-            devices = _find_devices()
-            try:
-                self.dev = devices[devid]
-            except Exception:
-                self.dev = None
-
-        if self.dev:
-            if (pyusb1 is True):
-                self.dev.set_configuration(1)
-                self.handle = self.dev
-                self.version = float(
-                    "{0:x}.{1:x}".format(self.dev.bcdDevice >> 8,
-                                         self.dev.bcdDevice & 0x0FF))
-            else:
-                self.handle = self.dev.open()
-                self.handle.setConfiguration(1)
-                self.handle.claimInterface(0)
-                self.version = float(self.dev.deviceVersion)
-
-    def get_serial(self):
-        return usb.util.get_string(self.dev, 255, self.dev.iSerialNumber)
-
-    def close(self):
-        if (pyusb1 is False):
-            if self.handle:
-                self.handle.releaseInterface()
-                self.handle.reset()
-        else:
-            if self.dev:
-                self.dev.reset()
-
-        self.handle = None
-        self.dev = None
-
-    def scan(self):
-        # TODO: Currently only supports one device
-        if self.dev:
-            return [("usb://0", "")]
-        return []
-
-    def set_crtp_to_usb(self, crtp_to_usb):
-        if crtp_to_usb:
-            _send_vendor_setup(self.handle, 0x01, 0x01, 1, ())
-        else:
-            _send_vendor_setup(self.handle, 0x01, 0x01, 0, ())
-
-    # Data transfers
-    def send_packet(self, dataOut):
-        """ Send a packet and receive the ack from the radio dongle
-            The ack contains information about the packet transmition
-            and a data payload if the ack packet contained any """
-        try:
-            if (pyusb1 is False):
-                count = self.handle.bulkWrite(1, dataOut, 20)
-            else:
-                count = self.handle.write(endpoint=1, data=dataOut, timeout=20)
-        except usb.USBError as e:
-            pass
-
-    def receive_packet(self):
-        dataIn = ()
-        try:
-            if (pyusb1 is False):
-                dataIn = self.handle.bulkRead(0x81, 64, 20)
-            else:
-                dataIn = self.handle.read(0x81, 64, timeout=20)
-        except usb.USBError as e:
-            try:
-                if e.backend_error_code == -7 or e.backend_error_code == -116:
-                    # Normal, the read was empty
-                    pass
-                else:
-                    raise IOError("Crazyflie disconnected")
-            except AttributeError as e:
-                # pyusb < 1.0 doesn't implement getting the underlying error
-                # number and it seems as if it's not possible to detect
-                # if the cable is disconnected. So this detection is not
-                # supported, but the "normal" case will work.
-                pass
-
-        return dataIn
-
-
-# Private utility functions
-def _send_vendor_setup(handle, request, value, index, data):
-    if pyusb1:
-        handle.ctrl_transfer(usb.TYPE_VENDOR, request, wValue=value,
-                             wIndex=index, timeout=1000, data_or_wLength=data)
-    else:
-        handle.controlMsg(usb.TYPE_VENDOR, request, data, value=value,
-                          index=index, timeout=1000)
-
-
-def _get_vendor_setup(handle, request, value, index, length):
-    if pyusb1:
-        return handle.ctrl_transfer(usb.TYPE_VENDOR | 0x80, request,
-                                    wValue=value, wIndex=index, timeout=1000,
-                                    data_or_wLength=length)
-    else:
-        return handle.controlMsg(usb.TYPE_VENDOR | 0x80, request, length,
-                                 value=value, index=index, timeout=1000)
diff --git a/src/cflib/cflib/drivers/crazyradio.py b/src/cflib/cflib/drivers/crazyradio.py
deleted file mode 100644
index 9641fa23a0014bcc1c3b143e604a137684225402..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/drivers/crazyradio.py
+++ /dev/null
@@ -1,292 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-USB driver for the Crazyradio USB dongle.
-"""
-
-import os
-import usb
-import logging
-
-__author__ = 'Bitcraze AB'
-__all__ = ['Crazyradio']
-
-logger = logging.getLogger(__name__)
-
-# USB parameters
-CRADIO_VID = 0x1915
-CRADIO_PID = 0x7777
-
-# Dongle configuration requests
-# See http://wiki.bitcraze.se/projects:crazyradio:protocol for documentation
-SET_RADIO_CHANNEL = 0x01
-SET_RADIO_ADDRESS = 0x02
-SET_DATA_RATE = 0x03
-SET_RADIO_POWER = 0x04
-SET_RADIO_ARD = 0x05
-SET_RADIO_ARC = 0x06
-ACK_ENABLE = 0x10
-SET_CONT_CARRIER = 0x20
-SCANN_CHANNELS = 0x21
-LAUNCH_BOOTLOADER = 0xFF
-
-try:
-    import usb.core
-
-    pyusb_backend = None
-    if os.name == "nt":
-        import usb.backend.libusb0 as libusb0
-
-        pyusb_backend = libusb0.get_backend()
-    pyusb1 = True
-except:
-    pyusb1 = False
-
-
-def _find_devices():
-    """
-    Returns a list of CrazyRadio devices currently connected to the computer
-    """
-    ret = []
-
-    if pyusb1:
-        for d in usb.core.find(idVendor=0x1915, idProduct=0x7777, find_all=1,
-                               backend=pyusb_backend):
-            ret.append(d)
-    else:
-        busses = usb.busses()
-        for bus in busses:
-            for device in bus.devices:
-                if device.idVendor == CRADIO_VID:
-                    if device.idProduct == CRADIO_PID:
-                        ret += [device, ]
-
-    return ret
-
-
-class _radio_ack:
-    ack = False
-    powerDet = False
-    retry = 0
-    data = ()
-
-
-class Crazyradio:
-    """ Used for communication with the Crazyradio USB dongle """
-    # configuration constants
-    DR_250KPS = 0
-    DR_1MPS = 1
-    DR_2MPS = 2
-
-    P_M18DBM = 0
-    P_M12DBM = 1
-    P_M6DBM = 2
-    P_0DBM = 3
-
-    def __init__(self, device=None, devid=0):
-        """ Create object and scan for USB dongle if no device is supplied """
-        if device is None:
-            try:
-                device = _find_devices()[devid]
-            except Exception:
-                raise Exception("Cannot find a Crazyradio Dongle")
-
-        self.dev = device
-
-        if (pyusb1 is True):
-            self.dev.set_configuration(1)
-            self.handle = self.dev
-            self.version = float("{0:x}.{1:x}".format(
-                self.dev.bcdDevice >> 8, self.dev.bcdDevice & 0x0FF))
-        else:
-            self.handle = self.dev.open()
-            self.handle.setConfiguration(1)
-            self.handle.claimInterface(0)
-            self.version = float(self.dev.deviceVersion)
-
-        if self.version < 0.3:
-            raise "This driver requires Crazyradio firmware V0.3+"
-
-        if self.version < 0.4:
-            logger.warning("You should update to Crazyradio firmware V0.4+")
-
-        # Reset the dongle to power up settings
-        self.set_data_rate(self.DR_2MPS)
-        self.set_channel(2)
-        self.arc = -1
-        if self.version >= 0.4:
-            self.set_cont_carrier(False)
-            self.set_address((0xE7,) * 5)
-            self.set_power(self.P_0DBM)
-            self.set_arc(3)
-            self.set_ard_bytes(32)
-
-    def close(self):
-        if (pyusb1 is False):
-            if self.handle:
-                self.handle.releaseInterface()
-                self.handle.reset()
-        else:
-            if self.dev:
-                self.dev.reset()
-
-        self.handle = None
-        self.dev = None
-
-    # Dongle configuration
-    def set_channel(self, channel):
-        """ Set the radio channel to be used """
-        _send_vendor_setup(self.handle, SET_RADIO_CHANNEL, channel, 0, ())
-
-    def set_address(self, address):
-        """ Set the radio address to be used"""
-        if len(address) != 5:
-            raise Exception("Crazyradio: the radio address shall be 5"
-                            " bytes long")
-
-        _send_vendor_setup(self.handle, SET_RADIO_ADDRESS, 0, 0, address)
-
-    def set_data_rate(self, datarate):
-        """ Set the radio datarate to be used """
-        _send_vendor_setup(self.handle, SET_DATA_RATE, datarate, 0, ())
-
-    def set_power(self, power):
-        """ Set the radio power to be used """
-        _send_vendor_setup(self.handle, SET_RADIO_POWER, power, 0, ())
-
-    def set_arc(self, arc):
-        """ Set the ACK retry count for radio communication """
-        _send_vendor_setup(self.handle, SET_RADIO_ARC, arc, 0, ())
-        self.arc = arc
-
-    def set_ard_time(self, us):
-        """ Set the ACK retry delay for radio communication """
-        # Auto Retransmit Delay:
-        # 0000 - Wait 250uS
-        # 0001 - Wait 500uS
-        # 0010 - Wait 750uS
-        # ........
-        # 1111 - Wait 4000uS
-
-        # Round down, to value representing a multiple of 250uS
-        t = int((us / 250) - 1)
-        if (t < 0):
-            t = 0
-        if (t > 0xF):
-            t = 0xF
-        _send_vendor_setup(self.handle, SET_RADIO_ARD, t, 0, ())
-
-    def set_ard_bytes(self, nbytes):
-        _send_vendor_setup(self.handle, SET_RADIO_ARD, 0x80 | nbytes, 0, ())
-
-    def set_cont_carrier(self, active):
-        if active:
-            _send_vendor_setup(self.handle, SET_CONT_CARRIER, 1, 0, ())
-        else:
-            _send_vendor_setup(self.handle, SET_CONT_CARRIER, 0, 0, ())
-
-    def _has_fw_scan(self):
-        # return self.version >= 0.5
-        # FIXME: Mitigation for Crazyradio firmware bug #9
-        return False
-
-    def scan_selected(self, selected, packet):
-        result = ()
-        for s in selected:
-            self.set_channel(s["channel"])
-            self.set_data_rate(s["datarate"])
-            status = self.send_packet(packet)
-            if status and status.ack:
-                result = result + (s,)
-
-        return result
-
-    def scan_channels(self, start, stop, packet):
-        if self._has_fw_scan():  # Fast firmware-driven scan
-            _send_vendor_setup(self.handle, SCANN_CHANNELS, start, stop,
-                               packet)
-            return tuple(_get_vendor_setup(self.handle, SCANN_CHANNELS,
-                                           0, 0, 64))
-        else:  # Slow PC-driven scan
-            result = tuple()
-            for i in range(start, stop + 1):
-                self.set_channel(i)
-                status = self.send_packet(packet)
-                if status and status.ack:
-                    result = result + (i,)
-            return result
-
-    # Data transferts
-    def send_packet(self, dataOut):
-        """ Send a packet and receive the ack from the radio dongle
-            The ack contains information about the packet transmition
-            and a data payload if the ack packet contained any """
-        ackIn = None
-        data = None
-        try:
-            if (pyusb1 is False):
-                self.handle.bulkWrite(1, dataOut, 1000)
-                data = self.handle.bulkRead(0x81, 64, 1000)
-            else:
-                self.handle.write(endpoint=1, data=dataOut, timeout=1000)
-                data = self.handle.read(0x81, 64, timeout=1000)
-        except usb.USBError:
-            pass
-
-        if data is not None:
-            ackIn = _radio_ack()
-            if data[0] != 0:
-                ackIn.ack = (data[0] & 0x01) != 0
-                ackIn.powerDet = (data[0] & 0x02) != 0
-                ackIn.retry = data[0] >> 4
-                ackIn.data = data[1:]
-            else:
-                ackIn.retry = self.arc
-
-        return ackIn
-
-
-# Private utility functions
-def _send_vendor_setup(handle, request, value, index, data):
-    if pyusb1:
-        handle.ctrl_transfer(usb.TYPE_VENDOR, request, wValue=value,
-                             wIndex=index, timeout=1000, data_or_wLength=data)
-    else:
-        handle.controlMsg(usb.TYPE_VENDOR, request, data, value=value,
-                          index=index, timeout=1000)
-
-
-def _get_vendor_setup(handle, request, value, index, length):
-    if pyusb1:
-        return handle.ctrl_transfer(usb.TYPE_VENDOR | 0x80, request,
-                                    wValue=value, wIndex=index, timeout=1000,
-                                    data_or_wLength=length)
-    else:
-        return handle.controlMsg(usb.TYPE_VENDOR | 0x80, request, length,
-                                 value=value, index=index, timeout=1000)
diff --git a/src/cflib/cflib/utils/__init__.py b/src/cflib/cflib/utils/__init__.py
deleted file mode 100644
index dd277b671ca49039c8196b9338e923d4dcd3b06e..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/utils/__init__.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-"""
-Various utilities that is needed by the cflib.
-"""
diff --git a/src/cflib/cflib/utils/callbacks.py b/src/cflib/cflib/utils/callbacks.py
deleted file mode 100644
index 3102bc630f0d0a5403e5a92134eb193b36391391..0000000000000000000000000000000000000000
--- a/src/cflib/cflib/utils/callbacks.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2011-2013 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-"""
-Callback objects used in the Crazyflie library
-"""
-
-__author__ = 'Bitcraze AB'
-__all__ = ['Caller']
-
-
-class Caller():
-    """ An object were callbacks can be registered and called """
-
-    def __init__(self):
-        """ Create the object """
-        self.callbacks = []
-
-    def add_callback(self, cb):
-        """ Register cb as a new callback. Will not register duplicates. """
-        if ((cb in self.callbacks) is False):
-            self.callbacks.append(cb)
-
-    def remove_callback(self, cb):
-        """ Un-register cb from the callbacks """
-        self.callbacks.remove(cb)
-
-    def call(self, *args):
-        """ Call the callbacks registered with the arguments args """
-        for cb in self.callbacks:
-            cb(*args)
diff --git a/src/cflib/test/__init__.py b/src/cflib/test/__init__.py
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/cflib/test/crtp/__init__.py b/src/cflib/test/crtp/__init__.py
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/cflib/test/crtp/test_crtpstack.py b/src/cflib/test/crtp/test_crtpstack.py
deleted file mode 100644
index 1c45422e5bf1ceef8b546a915b59c12592c195a4..0000000000000000000000000000000000000000
--- a/src/cflib/test/crtp/test_crtpstack.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-
-import unittest
-
-from cflib.crtp.crtpstack import CRTPPacket
-
-
-class CRTPPacketTest(unittest.TestCase):
-
-    def setUp(self):
-        self.callback_count = 0
-        self.sut = CRTPPacket()
-
-    def test_that_port_and_channle_is_encoded_in_header(self):
-        # Fixture
-        self.sut.set_header(2, 1)
-
-        # Test
-        actual = self.sut.get_header()
-
-        # Assert
-        expected = 0x2d
-        self.assertEqual(expected, actual)
-
-    def test_that_port_is_truncated_in_header(self):
-        # Fixture
-        port = 0xff
-        self.sut.set_header(port, 0)
-
-        # Test
-        actual = self.sut.get_header()
-
-        # Assert
-        expected = 0xfc
-        self.assertEqual(expected, actual)
-
-    def test_that_channel_is_truncated_in_header(self):
-        # Fixture
-        channel = 0xff
-        self.sut.set_header(0, channel)
-
-        # Test
-        actual = self.sut.get_header()
-
-        # Assert
-        expected = 0x0f
-        self.assertEqual(expected, actual)
-
-    def test_that_port_and_channel_is_encoded_in_header_when_set_separat(self):
-        # Fixture
-        self.sut.port = 2
-        self.sut.channel = 1
-
-        # Test
-        actual = self.sut.get_header()
-
-        # Assert
-        expected = 0x2d
-        self.assertEqual(expected, actual)
-
-    def test_that_default_header_is_set_when_constructed(self):
-        # Fixture
-
-        # Test
-        actual = self.sut.get_header()
-
-        # Assert
-        expected = 0x0c
-        self.assertEqual(expected, actual)
-
-    def test_that_header_is_set_when_constructed(self):
-        # Fixture
-        sut = CRTPPacket(header=0x21)
-
-        # Test
-        actual = sut.get_header()
-
-        # Assert
-        self.assertEqual(0x2d, actual)
-        self.assertEqual(2, sut.port)
-        self.assertEqual(1, sut.channel)
diff --git a/src/cflib/test/utils/__init__.py b/src/cflib/test/utils/__init__.py
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/cflib/test/utils/test_callbacks.py b/src/cflib/test/utils/test_callbacks.py
deleted file mode 100644
index bd00a0800bc85edfc48725df8543850470e10994..0000000000000000000000000000000000000000
--- a/src/cflib/test/utils/test_callbacks.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-#  You should have received a copy of the GNU General Public License
-#  along with this program; if not, write to the Free Software
-#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-#  MA  02110-1301, USA.
-import unittest
-
-from cflib.utils.callbacks import Caller
-
-
-class CallerTest(unittest.TestCase):
-
-    def setUp(self):
-        self.callback_count = 0
-        self.sut = Caller()
-
-    def test_that_callback_is_added(self):
-        # Fixture
-
-        # Test
-        self.sut.add_callback(self._callback)
-
-        # Assert
-        self.sut.call()
-        self.assertEqual(1, self.callback_count)
-
-    def test_that_callback_is_added_only_one_time(self):
-        # Fixture
-
-        # Test
-        self.sut.add_callback(self._callback)
-        self.sut.add_callback(self._callback)
-
-        # Assert
-        self.sut.call()
-        self.assertEqual(1, self.callback_count)
-
-    def test_that_multiple_callbacks_are_added(self):
-        # Fixture
-
-        # Test
-        self.sut.add_callback(self._callback)
-        self.sut.add_callback(self._callback2)
-
-        # Assert
-        self.sut.call()
-        self.assertEqual(2, self.callback_count)
-
-    def test_that_callback_is_removed(self):
-        # Fixture
-        self.sut.add_callback(self._callback)
-
-        # Test
-        self.sut.remove_callback(self._callback)
-
-        # Assert
-        self.sut.call()
-        self.assertEqual(0, self.callback_count)
-
-    def test_that_callback_is_called_with_arguments(self):
-        # Fixture
-        self.sut.add_callback(self._callback_with_args)
-
-        # Test
-        self.sut.call('The token')
-
-        # Assert
-        self.assertEqual('The token', self.callback_token)
-
-    def _callback(self):
-        self.callback_count += 1
-
-    def _callback2(self):
-        self.callback_count += 1
-
-    def _callback_with_args(self, token):
-        self.callback_token = token
diff --git a/src/cfloader/__init__.py b/src/cfloader/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..7113904b9cd24313e56b13cbbbdfd1f562aae028
--- /dev/null
+++ b/src/cfloader/__init__.py
@@ -0,0 +1,203 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+#     ||          ____  _ __
+#  +------+      / __ )(_) /_______________ _____  ___
+#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
+#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
+#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
+#
+#  Copyright (C) 2011-2013 Bitcraze AB
+#
+#  Crazyflie Nano Quadcopter Client
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+#  MA  02110-1301, USA.
+
+# Crazy Loader bootloader utility
+# Can reset bootload and reset back the bootloader
+
+import sys
+import os
+
+import cflib.crtp
+from cflib.bootloader import Bootloader
+from cflib.bootloader.boottypes import BootVersion, TargetTypes, Target
+
+
+def main():
+    # Initialise the CRTP link driver
+    link = None
+    try:
+        cflib.crtp.init_drivers()
+        link = cflib.crtp.get_link_driver("radio://")
+    except Exception as e:
+        print("Error: {}".format(str(e)))
+        if link:
+            link.close()
+        sys.exit(-1)
+
+    # Set the default parameters
+    # Default to Arnaud's copter
+    cpu_id = "32:00:6e:06:58:37:35:32:60:58:01:43"
+    clink = None
+    action = "info"
+    boot = "cold"
+
+    if len(sys.argv) < 2:
+        print()
+        print("==============================")
+        print(" CrazyLoader Flash Utility")
+        print("==============================")
+        print()
+        print(" Usage:", sys.argv[0], "[CRTP options] <action> [parameters]")
+        print()
+        print("The CRTP options are described above")
+        print()
+        print("Crazyload option:")
+        print("   info                    : Print the info of the bootloader "
+              "and quit.")
+        print("                             Will let the target in bootloader "
+              "mode")
+        print("   reset                   : Reset the device in firmware mode")
+        print("   flash <file> [targets]  : flash the <img> binary file from "
+              "the first")
+        print("                             possible  page in flash and reset "
+              "to firmware")
+        print("                             mode.")
+        if link:
+            link.close()
+        sys.exit(0)
+
+    # Analyse the command line parameters
+    sys.argv = sys.argv[1:]
+    argv = []
+
+    warm_uri = None
+
+    i = 0
+    while i < len(sys.argv):
+        if sys.argv[i] == "-i":
+            i += 1
+            cpu_id = sys.argv[i]
+        elif sys.argv[i] == "--cold-boot" or sys.argv[i] == "-c":
+            boot = "cold"
+        elif sys.argv[i] == "--warm-boot" or sys.argv[i] == "-w":
+            boot = "reset"
+            i += 1
+            clink = sys.argv[i]
+        else:
+            argv += [sys.argv[i]]
+        i += 1
+    sys.argv = argv
+
+    # Analyse the command
+    if len(sys.argv) < 1:
+        action = "info"
+    elif sys.argv[0] == "info":
+        action = "info"
+    elif sys.argv[0] == "reset":
+        action = "reset"
+    elif sys.argv[0] == "flash":
+        # print len(sys.argv)
+        if len(sys.argv) < 2:
+            print("The flash action require a file name.")
+            link.close()
+            sys.exit(-1)
+        action = "flash"
+        filename = sys.argv[1]
+        targetnames = {}
+        for t in sys.argv[2:]:
+            [target, type] = t.split("-")
+            if target in targetnames:
+                targetnames[target] += (type,)
+            else:
+                targetnames[target] = (type,)
+    else:
+        print("Action", sys.argv[0], "unknown!")
+        link.close()
+        sys.exit(-1)
+
+    # Currently there's two different targets available
+    targets = ()
+
+    try:
+        # Initialise the bootloader lib
+        bl = Bootloader(clink)
+
+        #########################################
+        # Get the connection with the bootloader
+        #########################################
+        # The connection is done by reseting to the bootloader (default)
+        if boot == "reset":
+            print("Reset to bootloader mode ..."),
+            sys.stdout.flush()
+            if bl.start_bootloader(warm_boot=True):
+                print(" done!")
+            else:
+                print("Failed to warmboot")
+                bl.close()
+                sys.exit(-1)
+        else:  # The connection is done by a cold boot ...
+            print("Restart the Crazyflie you want to bootload in the next"),
+            print(" 10 seconds ..."),
+
+            sys.stdout.flush()
+            if bl.start_bootloader(warm_boot=False):
+                print(" done!")
+            else:
+                print("Cannot connect the bootloader!")
+                bl.close()
+                sys.exit(-1)
+
+        print("Connected to bootloader on {} (version=0x{:X})".format(
+            BootVersion.to_ver_string(bl.protocol_version),
+            bl.protocol_version))
+
+        if bl.protocol_version == BootVersion.CF2_PROTO_VER:
+            targets += (bl.get_target(TargetTypes.NRF51),)
+        targets += (bl.get_target(TargetTypes.STM32),)
+
+        ######################################
+        # Doing something (hopefully) useful
+        ######################################
+
+        # Print information about the targets
+        for target in targets:
+            print(target)
+        if action == "info":
+            None  # Already done ...
+        elif action == "reset":
+            print
+            print("Reset in firmware mode ...")
+            bl.reset_to_firmware()
+        elif action == "flash":
+            bl.flash(filename, targetnames)
+            print("Reset in firmware mode ...")
+            bl.reset_to_firmware()
+        else:
+            None
+    except Exception as e:
+        import traceback
+
+        traceback.print_exc(file=sys.stdout)
+        print(e)
+
+    finally:
+        #########################
+        # Closing the connection
+        #########################
+        if bl:
+            bl.close()
diff --git a/src/cfloader/__main__.py b/src/cfloader/__main__.py
new file mode 100644
index 0000000000000000000000000000000000000000..b48e88c16bd98d4344f120ef78ca50605a006e1d
--- /dev/null
+++ b/src/cfloader/__main__.py
@@ -0,0 +1,4 @@
+from cfloader import main
+
+if __name__ == "__main__":
+    main()
diff --git a/src/cfzmq.py b/src/cfzmq/__init__.py
similarity index 98%
rename from src/cfzmq.py
rename to src/cfzmq/__init__.py
index aa7bd0f19d0a22d3f7520acdd96b8702b67a6f34..c336f6604a02dc6022ae5a9f2282cb07ca1098c1 100644
--- a/src/cfzmq.py
+++ b/src/cfzmq/__init__.py
@@ -40,6 +40,8 @@ import cflib.crtp
 from cflib.crazyflie import Crazyflie
 from cflib.crazyflie.log import LogConfig
 
+import cfclient
+
 if os.name == 'posix':
     print('Disabling standard output for libraries!')
     stdout = os.dup(1)
@@ -318,8 +320,8 @@ class ZMQServer():
     def __init__(self, base_url):
         """Start threads and bind ports"""
         cflib.crtp.init_drivers(enable_debug_driver=True)
-        self._cf = Crazyflie(ro_cache=sys.path[0] + "/cflib/cache",
-                             rw_cache=sys.path[1] + "/cache")
+        self._cf = Crazyflie(ro_cache=None,
+                             rw_cache=cfclient.config_path + "/cache")
 
         signal.signal(signal.SIGINT, signal.SIG_DFL)
 
@@ -368,3 +370,6 @@ def main():
     ZMQServer(args.url)
 
     # CRTL-C to exit
+
+if __name__ == "__main__":
+    main()
diff --git a/src/cfzmq/__main__.py b/src/cfzmq/__main__.py
new file mode 100644
index 0000000000000000000000000000000000000000..6ba7f561c929f5e5fc86d6ae3af0429152bdf91a
--- /dev/null
+++ b/src/cfzmq/__main__.py
@@ -0,0 +1,4 @@
+from cfzmq import main
+
+if __name__ == "__main__":
+    main()
diff --git a/src/leapsdk/__init__.py b/src/leapsdk/__init__.py
deleted file mode 100644
index c8c34c858acc3dda7dcfff26944fa8f1ee86ba22..0000000000000000000000000000000000000000
--- a/src/leapsdk/__init__.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-#     ||          ____  _ __
-#  +------+      / __ )(_) /_______________ _____  ___
-#  | 0xBC |     / __  / / __/ ___/ ___/ __ `/_  / / _ \
-#  +------+    / /_/ / / /_/ /__/ /  / /_/ / / /_/  __/
-#   ||  ||    /_____/_/\__/\___/_/   \__,_/ /___/\___/
-#
-#  Copyright (C) 2014 Bitcraze AB
-#
-#  Crazyflie Nano Quadcopter Client
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU General Public License
-#  as published by the Free Software Foundation; either version 2
-#  of the License, or (at your option) any later version.
-#
-#  This program is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#  GNU General Public License for more details.
-
-#  You should have received a copy of the GNU General Public License along with
-#  this program; if not, write to the Free Software Foundation, Inc., 51
-#  Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-"""
-In order to use the Leap Motion as an input device reader the libraries from
-the Leap Motion SDK has to be placed in this directory. This can be done by
-downloading the SDK from the http://developer.leapmotion.com website, unpacking
-it and copying the following files:
-
-  * LeapSDK\lib\Leap.py                     -> leapsdk\Leap.py
-  * LeapSDK\lib\<your_arch>\LeapPython.so   -> leapsdk\LeapPython.so
-  * LeapSDK\lib\<your_arch>\libLeap.so      -> leapsdk\libLeap.so
-"""
diff --git a/tools/build/bdist b/tools/build/bdist
new file mode 100755
index 0000000000000000000000000000000000000000..ed4f310909c5a426c0fedd507470fa8cfabd5eaa
--- /dev/null
+++ b/tools/build/bdist
@@ -0,0 +1,17 @@
+#!/usr/bin/env python
+import os
+import subprocess
+import os.path as _path
+
+__author__ = 'arnaud'
+
+try:
+    script_dir = os.path.dirname(os.path.realpath(__file__))
+    root = _path.normpath(_path.join(script_dir, '../..'))
+
+    subprocess.check_call(['python3', 'setup.py', 'bdist_wheel'], cwd=root)
+
+    print("Wheel built")
+except subprocess.CalledProcessError as e:
+    print("Error: Cannot build the wheel")
+    raise e
diff --git a/tools/build/build b/tools/build/build
index 393ccc3d2efd160003dc907b15b5baaed8c35810..752479831d2cbd12c640439d46cd0086af1b9395 100755
--- a/tools/build/build
+++ b/tools/build/build
@@ -5,4 +5,4 @@ import subprocess
 script_dir = os.path.dirname(os.path.realpath(__file__))
 
 subprocess.check_call([script_dir + "/pep8"])
-subprocess.check_call([script_dir + "/test"])
+subprocess.check_call([script_dir + "/bdist"])
diff --git a/tools/build/test b/tools/build/test
deleted file mode 100755
index facc77f7f6faf6c368ab95be20340b5ccf227f09..0000000000000000000000000000000000000000
--- a/tools/build/test
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/usr/bin/env python
-import os
-import subprocess
-import os.path as _path
-
-try:
-    script_dir = os.path.dirname(os.path.realpath(__file__))
-    cflib = _path.normpath(_path.join(script_dir, '../../src/cflib'))
-
-    subprocess.check_call(['python', '-m', 'unittest', 'discover', cflib])
-
-    print("Unit tests pass")
-except subprocess.CalledProcessError as e:
-    print("Error: Unit tests fail")
-    raise e