diff --git a/classes/asteroid-image.bbclass b/classes/asteroid-image.bbclass
index 383047f7..79a69d6f 100644
--- a/classes/asteroid-image.bbclass
+++ b/classes/asteroid-image.bbclass
@@ -5,7 +5,7 @@ LICENSE = "GPL-2.0"
 IMAGE_FEATURES += "splash package-management"
 
 IMAGE_INSTALL += " \
-base-files base-passwd systemd busybox iproute2 connman pam-plugin-loginuid bluez5 pulseaudio-server openssh-sshd openssh-sftp-server openssh-scp statefs dsme mce ngfd timed sensorfw android-init mapplauncherd-booster-qtcomponents usb-moded \
+base-files base-passwd systemd busybox iproute2 connman pam-plugin-loginuid bluez5 pulseaudio-server openssh-sshd openssh-sftp-server openssh-scp statefs dsme mce ngfd timed sensorfw android-init mapplauncherd-booster-qtcomponents asteroid-usbsetup mtp-server \
 supported-languages asteroid-launcher asteroid-calculator asteroid-calendar asteroid-stopwatch asteroid-settings asteroid-timer asteroid-alarmclock asteroid-weather asteroid-music asteroid-btsyncd"
 
 EXTRA_USERS_PARAMS = "groupadd system; \
diff --git a/recipes-android/android-tools/android-tools/android-tools-adbd.service b/recipes-android/android-tools/android-tools/android-tools-adbd.service
index 3481b844..3b631418 100644
--- a/recipes-android/android-tools/android-tools/android-tools-adbd.service
+++ b/recipes-android/android-tools/android-tools/android-tools-adbd.service
@@ -1,8 +1,13 @@
 [Unit]
 Description=Android Debug Bridge
+Requires=usb-setup.service
+After=usb-setup.service
 
 [Service]
 Type=simple
 Restart=on-failure
 ExecStart=/usr/bin/adbd
 StandardOutput=null
+
+[Install]
+WantedBy=multi-user.target
diff --git a/recipes-asteroid/asteroid-usbsetup/asteroid-usbsetup/asteroid-usbsetup.sh b/recipes-asteroid/asteroid-usbsetup/asteroid-usbsetup/asteroid-usbsetup.sh
new file mode 100755
index 00000000..bfd0c5e5
--- /dev/null
+++ b/recipes-asteroid/asteroid-usbsetup/asteroid-usbsetup/asteroid-usbsetup.sh
@@ -0,0 +1,38 @@
+#! /bin/sh
+
+set -e
+
+ANDROID_USB="/sys/class/android_usb/android0"
+
+log_info () {
+	echo "[INFO] $@"
+}
+
+start_usb () {
+	echo "0" > $ANDROID_USB/enable
+
+	log_info "Starting adb mode"
+
+	manufacturer="$(cat /system/build.prop | grep -o 'ro.product.manufacturer=.*' | cut -d'=' -f 2)"
+	model="$(cat /system/build.prop | grep -o 'ro.product.model=.*' | cut -d'=' -f 2)"
+	serial="$(cat /proc/cmdline | sed 's/.*androidboot.serialno=//' | sed 's/ .*//')"
+
+	echo $manufacturer > $ANDROID_USB/iManufacturer
+	echo $model        > $ANDROID_USB/iProduct
+	echo $serial       > $ANDROID_USB/iSerial
+
+	echo 18d1 > $ANDROID_USB/idVendor
+	echo 0a03 > $ANDROID_USB/idProduct
+
+	mkdir -p /dev/usb-ffs/adb
+	mount -t functionfs adb /dev/usb-ffs/adb
+
+	echo adb > $ANDROID_USB/f_ffs/aliases
+	echo ffs,ecm,mtp > $ANDROID_USB/functions
+
+	echo "1" > $ANDROID_USB/enable
+
+	log_info "Initialized android_usb with $manufacturer $model $serial"
+}
+
+start_usb
diff --git a/recipes-asteroid/asteroid-usbsetup/asteroid-usbsetup/usb-setup.service b/recipes-asteroid/asteroid-usbsetup/asteroid-usbsetup/usb-setup.service
new file mode 100644
index 00000000..aaf61cc0
--- /dev/null
+++ b/recipes-asteroid/asteroid-usbsetup/asteroid-usbsetup/usb-setup.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=Asteroid USB setup service
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart=/usr/sbin/asteroid-usbsetup.sh
+
+[Install]
+WantedBy=multi-user.target
diff --git a/recipes-asteroid/asteroid-usbsetup/asteroid-usbsetup_1.0.bb b/recipes-asteroid/asteroid-usbsetup/asteroid-usbsetup_1.0.bb
new file mode 100644
index 00000000..a4838cc8
--- /dev/null
+++ b/recipes-asteroid/asteroid-usbsetup/asteroid-usbsetup_1.0.bb
@@ -0,0 +1,18 @@
+DESCRIPTION = "This installs the usb-setup service Asteroid uses to initialize USB connection"
+PR = "r0"
+SRC_URI = "file://asteroid-usbsetup.sh \
+    file://usb-setup.service"
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10"
+
+do_install() {
+    install -d ${D}/usr/sbin/
+    install -m 0755 ${WORKDIR}/asteroid-usbsetup.sh ${D}/usr/sbin/asteroid-usbsetup.sh
+
+    install -d ${D}/lib/systemd/system/multi-user.target.wants/
+    install -m 0644 ${WORKDIR}/usb-setup.service ${D}/lib/systemd/system/usb-setup.service
+    ln -s ../usb-setup.service ${D}/lib/systemd/system/multi-user.target.wants/usb-setup.service
+}
+
+FILES_${PN} += " /lib/systemd/system/"
diff --git a/recipes-core/systemd/systemd/65-android.rules b/recipes-core/systemd/systemd/65-android.rules
index 3d7676b7..27588843 100644
--- a/recipes-core/systemd/systemd/65-android.rules
+++ b/recipes-core/systemd/systemd/65-android.rules
@@ -35,6 +35,7 @@ ACTION=="add", KERNEL=="event[0-9]*", GROUP="system", MODE="0660"
 # misc devices
 ACTION=="add", KERNEL=="alarm", GROUP="system", MODE="0664"
 ACTION=="add", KERNEL=="uhid", GROUP="system", MODE="0660"
+ACTION=="add", KERNEL=="mtp_usb", GROUP="mtp", MODE="0664"
 
 # memory
 ACTION=="add", KERNEL=="ashmem", GROUP="system", MODE="0666"
diff --git a/recipes-core/systemd/systemd/70-asteroid-ecm.network b/recipes-core/systemd/systemd/70-asteroid-ecm.network
new file mode 100644
index 00000000..1eddc6eb
--- /dev/null
+++ b/recipes-core/systemd/systemd/70-asteroid-ecm.network
@@ -0,0 +1,15 @@
+[Match]
+Name=ecm*
+
+[Network]
+Description=USB CDC ECM interface
+DHCPServer=yes
+Address=192.168.2.1/30
+Gateway=192.168.2.2
+
+[DHCPServer]
+PoolSize=2
+EmitDNS=no
+EmitNTP=no
+EmitRouter=no
+EmitTimezone=no
diff --git a/recipes-core/systemd/systemd_%.bbappend b/recipes-core/systemd/systemd_%.bbappend
index 61b39d45..c1fcc852 100644
--- a/recipes-core/systemd/systemd_%.bbappend
+++ b/recipes-core/systemd/systemd_%.bbappend
@@ -1,6 +1,7 @@
 FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
 SRC_URI_append = " file://50-video.rules \
                   file://65-android.rules \
+                  file://70-asteroid-ecm.network \
                   file://dbus.service \
                   file://dbus.socket \
                   file://dbus.conf "
@@ -9,6 +10,8 @@ do_install_append() {
     # Setup udev rules for the rights of Android and graphic cards specific devices
     install -m 0644 ${WORKDIR}/50-video.rules ${D}${sysconfdir}/udev/rules.d/50-video.rules
     install -m 0644 ${WORKDIR}/65-android.rules ${D}${sysconfdir}/udev/rules.d/65-android.rules
+    # Setup systemd-networkd rules
+    install -m 0644 ${WORKDIR}/70-asteroid-ecm.network ${D}/lib/systemd/network/70-asteroid-ecm.network
 
     # Enables auto-login for ceres
     install -d ${D}/var/lib/systemd/linger
@@ -30,7 +33,7 @@ do_install_append() {
 
 FILES_${PN} += "/home/ceres/.config/systemd/user/default.target.wants/"
 
-PACKAGECONFIG_append += "pam"
+PACKAGECONFIG_append += "pam networkd"
 
 RRECOMMENDS_${PN}_remove = "udev-hwdb"
 
diff --git a/recipes-nemomobile/usb-moded/usb-moded_git.bb b/recipes-nemomobile/usb-moded/usb-moded_git.bb
index 9cdb78e8..85f2d4ba 100644
--- a/recipes-nemomobile/usb-moded/usb-moded_git.bb
+++ b/recipes-nemomobile/usb-moded/usb-moded_git.bb
@@ -49,15 +49,6 @@ do_install_append() {
     touch ${D}/etc/modprobe.d/g_ether.conf
     touch ${D}/etc/udhcpd.conf
 
-    install -d ${D}/lib/systemd/system/multi-user.target.wants/
-    install -m 644 -D ../usb-moded.service ${D}/lib/systemd/system/usb-moded.service
-    ln -s ../usb-moded.service ${D}/lib/systemd/system/multi-user.target.wants/usb-moded.service
-    install -m 644 -D ../udhcp-daemon.service ${D}/lib/systemd/system/udhcp-daemon.service
-    install -m 644 -D ../buteo-session.service ${D}/lib/systemd/system/buteo-session.service
-
-    install -d ${D}/usr/share/dbus-1/services/
-    install -m 644 -D ../com.meego.usb_moded.service ${D}/usr/share/dbus-1/services/com.meego.usb_moded.service
-
     install -m 644 -D systemd/usb-moded.conf ${D}/etc/tmpfiles.d/usb-moded.conf
 
     install -m 755 -D systemd/adbd-functionfs.sh ${D}/usr/sbin/adbd-functionfs.sh
diff --git a/recipes-ubuntu/mtp-server/mtp-server/0001-Remove-dbus-dependency.patch b/recipes-ubuntu/mtp-server/mtp-server/0001-Remove-dbus-dependency.patch
new file mode 100644
index 00000000..a75cce56
--- /dev/null
+++ b/recipes-ubuntu/mtp-server/mtp-server/0001-Remove-dbus-dependency.patch
@@ -0,0 +1,252 @@
+From 9e16a5f8758a44adfd747e3d8be05f78adf70673 Mon Sep 17 00:00:00 2001
+From: Josef Gajdusek <atx@atx.name>
+Date: Mon, 29 May 2017 22:39:21 +0200
+Subject: [PATCH] Remove dbus dependency
+
+---
+ CMakeLists.txt    |   9 ++--
+ server/server.cpp | 145 +++++++-----------------------------------------------
+ 2 files changed, 23 insertions(+), 131 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 46bff47..2c2f1a2 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -14,7 +14,6 @@ set(MTP_VERSION_MINOR 0)
+ set(MTP_VERSION_PATCH 0)
+ 
+ find_package(Boost REQUIRED COMPONENTS thread system filesystem unit_test_framework)
+-pkg_check_modules(DBUSCPP REQUIRED dbus-cpp)
+ pkg_check_modules(GLOG REQUIRED libglog)
+ 
+ set(
+@@ -61,7 +60,6 @@ include_directories(
+     include/
+     libusbhost/include
+     ${Boost_INCLUDE_DIRS}
+-    ${DBUSCPP_INCLUDE_DIRS}
+ )
+ 
+ add_library(
+@@ -73,7 +71,6 @@ target_link_libraries(
+   mtpserver
+   android-properties
+   ${GLOG_LIBRARIES}
+-  ${DBUSCPP_LIBRARIES}
+ )
+ 
+ set_target_properties(
+@@ -102,3 +99,9 @@ add_subdirectory(libusbhost)
+ add_subdirectory(server)
+ add_subdirectory(tests)
+ add_subdirectory(po)
++
++target_link_libraries(mtpserver pthread)
++
++target_link_libraries(mtpserver pthread)
++
++target_link_libraries(mtpserver pthread)
+diff --git a/server/server.cpp b/server/server.cpp
+index 0a9a846..62af1bc 100644
+--- a/server/server.cpp
++++ b/server/server.cpp
+@@ -35,70 +35,9 @@
+ #include <hybris/properties/properties.h>
+ #include <glog/logging.h>
+ 
+-#include <core/dbus/bus.h>
+-#include <core/dbus/object.h>
+-#include <core/dbus/property.h>
+-#include <core/dbus/service.h>
+-#include <core/dbus/signal.h>
+ 
+-#include <core/dbus/asio/executor.h>
+-#include <core/dbus/types/stl/tuple.h>
+-#include <core/dbus/types/stl/vector.h>
+-#include <core/dbus/types/struct.h>
+-
+-
+-namespace dbus = core::dbus;
+ using namespace android;
+ 
+-namespace core
+-{
+-dbus::Bus::Ptr the_session_bus()
+-{
+-    static dbus::Bus::Ptr session_bus = std::make_shared<dbus::Bus>(dbus::WellKnownBus::session);
+-    return session_bus;
+-}
+-
+-struct UnityGreeter
+-{
+-    struct Properties
+-    {
+-        struct IsActive
+-        {
+-            inline static std::string name()
+-            {
+-                return "IsActive";
+-            };
+-            typedef UnityGreeter Interface;
+-            typedef bool ValueType;
+-            static const bool readable = true;
+-            static const bool writable = false;
+-        };
+-    };
+-};
+-}
+-
+-namespace core
+-{
+-namespace dbus
+-{
+-namespace traits
+-{
+-template<>
+-struct Service<core::UnityGreeter>
+-{
+-    inline static const std::string& interface_name()
+-    {
+-        static const std::string s
+-        {
+-            "com.canonical.UnityGreeter"
+-        };
+-        return s;
+-    }
+-};
+-}
+-}
+-}
+-
+ namespace
+ {
+ struct FileSystemConfig
+@@ -114,8 +53,6 @@ class MtpDaemon
+ 
+ private:
+     struct passwd *userdata;
+-    dbus::Bus::Ptr bus;
+-    boost::thread dbus_thread;
+ 
+     // Mtp stuff
+     MtpServer* server;
+@@ -124,8 +61,7 @@ private:
+     MtpDatabase* mtp_database;
+ 
+     // Security
+-    std::shared_ptr<core::dbus::Property<core::UnityGreeter::Properties::IsActive> > is_active;
+-    bool screen_locked = true;
++    bool screen_locked = false;
+ 
+     // inotify stuff
+     boost::thread notifier_thread;
+@@ -242,17 +178,6 @@ private:
+         read_more_notify();
+     }
+ 
+-    void drive_bus()
+-    {
+-        try {
+-            bus->run();
+-        }
+-        catch (...) {
+-            PLOG(ERROR) << "There was an unexpected error in DBus; terminating.";
+-            server->stop();
+-        }
+-    }
+-
+ public:
+ 
+     MtpDaemon(int fd):
+@@ -285,15 +210,6 @@ public:
+                 userdata->pw_gid,
+                 FileSystemConfig::file_perm,
+                 FileSystemConfig::directory_perm);
+-
+-        // security / screen locking
+-        bus = core::the_session_bus();
+-        bus->install_executor(core::dbus::asio::make_executor(bus));
+-        dbus_thread = boost::thread(&MtpDaemon::drive_bus, this);
+-        auto greeter_service = dbus::Service::use_service(bus, "com.canonical.UnityGreeter");
+-        dbus::Object::Ptr greeter = greeter_service->object_for_path(dbus::types::ObjectPath("/"));
+-
+-        is_active = greeter->get_property<core::UnityGreeter::Properties::IsActive>();
+     }
+ 
+     void initStorage()
+@@ -352,7 +268,6 @@ public:
+         // Cleanup
+         inotify_rm_watch(inotify_fd, watch_fd);
+         io_svc.stop();
+-        dbus_thread.detach();
+         notifier_thread.detach();
+         io_service_thread.join();
+         close(inotify_fd);
+@@ -360,48 +275,22 @@ public:
+ 
+     void run()
+     {
+-        if (is_active->get()) {
+-            is_active->changed().connect([this](bool active)
+-            {
+-                if (!active) {
+-                    screen_locked = active;
+-                    VLOG(2) << "device was unlocked, adding storage";
+-                    if (home_storage && !home_storage_added) {
+-                        server->addStorage(home_storage);
+-                        home_storage_added = true;
+-                    }
+-                    BOOST_FOREACH(std::string name, removables | boost::adaptors::map_keys) {
+-                        auto t = removables.at(name);
+-                        MtpStorage *storage = std::get<0>(t);
+-                        bool added = std::get<1>(t);
+-                        if (!added) {
+-                            mtp_database->addStoragePath(storage->getPath(),
+-                                                         std::string(),
+-                                                         storage->getStorageID(),
+-                                                         true);
+-                            server->addStorage(storage);
+-                        }
+-                    }
+-                }
+-            });
+-        } else {
+-            screen_locked = false;
+-            VLOG(2) << "device is not locked, adding storage";
+-            if (home_storage) {
+-                server->addStorage(home_storage);
+-                home_storage_added = true;
+-            }
+-            BOOST_FOREACH(std::string name, removables | boost::adaptors::map_keys) {
+-                auto t = removables.at(name);
+-                MtpStorage *storage = std::get<0>(t);
+-                bool added = std::get<1>(t);
+-                if (!added) {
+-                    mtp_database->addStoragePath(storage->getPath(),
+-                                                 std::string(),
+-                                                 storage->getStorageID(),
+-                                                 true);
+-                    server->addStorage(storage);
+-                }
++        screen_locked = false;
++        VLOG(2) << "device is not locked, adding storage";
++        if (home_storage) {
++            server->addStorage(home_storage);
++            home_storage_added = true;
++        }
++        BOOST_FOREACH(std::string name, removables | boost::adaptors::map_keys) {
++            auto t = removables.at(name);
++            MtpStorage *storage = std::get<0>(t);
++            bool added = std::get<1>(t);
++            if (!added) {
++                mtp_database->addStoragePath(storage->getPath(),
++                                             std::string(),
++                                             storage->getStorageID(),
++                                             true);
++                server->addStorage(storage);
+             }
+         }
+ 
+-- 
+2.13.0
+
diff --git a/recipes-ubuntu/mtp-server/mtp-server/mtp-server.service b/recipes-ubuntu/mtp-server/mtp-server/mtp-server.service
new file mode 100644
index 00000000..3b8abc45
--- /dev/null
+++ b/recipes-ubuntu/mtp-server/mtp-server/mtp-server.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=mtp-server service
+Requires=usb-setup.service dev-mtp_usb.device
+StartLimitIntervalSec=0
+
+[Service]
+Type=simple
+Environment=GLOG_logtostderr=1
+Restart=always
+ExecStart=/usr/bin/mtp-server
+User=ceres
+
+[Install]
+WantedBy=multi-user.target
diff --git a/recipes-ubuntu/mtp-server/mtp-server_bzr.bb b/recipes-ubuntu/mtp-server/mtp-server_bzr.bb
new file mode 100644
index 00000000..43d5f113
--- /dev/null
+++ b/recipes-ubuntu/mtp-server/mtp-server_bzr.bb
@@ -0,0 +1,31 @@
+SUMMARY = "A port of Android's mtp server implementation to Ubuntu."
+LICENSE = "GPL-3.0 & Apache-2.0"
+LIC_FILES_CHKSUM = " \
+    file://COPYING;md5=d32239bcb673463ab874e80d47fae504 \
+    file://MODULE_LICENSE_APACHE2;md5=d41d8cd98f00b204e9800998ecf8427e \
+    file://NOTICE;md5=9645f39e9db895a4aa6e02cb57294595 \
+"
+
+SRC_URI = " \
+    bzr://code.launchpad.net/~phablet-team/mtp/trunk \
+    file://0001-Remove-dbus-dependency.patch \
+    file://mtp-server.service \
+"
+S = "${WORKDIR}/trunk"
+SRCREV = "ci-train-bot@canonical.com-20160413060212-0qjv16umd0rhltw5"
+
+inherit cmake gettext
+
+DEPENDS += "boost libhybris glog"
+
+do_configure_prepend() {
+    echo -e "\ntarget_link_libraries(mtpserver pthread)" >> "${S}/CMakeLists.txt"
+}
+
+do_install_append() {
+    install -m 644 -D "../mtp-server.service" ${D}/lib/systemd/system/mtp-server.service
+    install -d ${D}/lib/systemd/system/multi-user.target.wants/
+    ln -s ../mtp-server.service ${D}/lib/systemd/system/multi-user.target.wants/mtp-server.service
+}
+
+FILES_${PN} += " /lib/systemd/system "