diff --git a/Makefile.tools b/Makefile.tools
index 8c79a528d..03264cff9 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -114,12 +114,12 @@ tools_mgmt_tester_LDADD = lib/libbluetooth-internal.la \
 				src/libshared-glib.la $(GLIB_LIBS)
 
 tools_l2cap_tester_SOURCES = tools/l2cap-tester.c monitor/bt.h \
-				emulator/hciemu.h emulator/hciemu.c \
+				emulator/hciemu.h emulator/hciemu-ell.c \
 				emulator/btdev.h emulator/btdev.c \
 				emulator/bthost.h emulator/bthost.c \
 				emulator/smp.c
 tools_l2cap_tester_LDADD = lib/libbluetooth-internal.la \
-				src/libshared-glib.la $(GLIB_LIBS)
+				src/libshared-ell.la $(ell_ldadd)
 
 tools_rfcomm_tester_SOURCES = tools/rfcomm-tester.c monitor/bt.h \
 				emulator/hciemu.h emulator/hciemu.c \
diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index ff641ba1d..6f55cf6f2 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -4,6 +4,7 @@
  *  BlueZ - Bluetooth protocol stack for Linux
  *
  *  Copyright (C) 2013  Intel Corporation. All rights reserved.
+
  *
  *
  */
@@ -17,7 +18,7 @@
 #include <errno.h>
 #include <stdbool.h>
 
-#include <glib.h>
+#include <ell/ell.h>
 
 #include "lib/bluetooth.h"
 #include "lib/l2cap.h"
@@ -35,8 +36,9 @@ struct test_data {
 	struct mgmt *mgmt;
 	uint16_t mgmt_index;
 	struct hciemu *hciemu;
+	struct l_io *io;
+	struct l_io *io2;
 	enum hciemu_type hciemu_type;
-	unsigned int io_id;
 	uint16_t handle;
 	uint16_t scid;
 	uint16_t dcid;
@@ -218,9 +220,14 @@ static void test_post_teardown(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
 
-	if (data->io_id > 0) {
-		g_source_remove(data->io_id);
-		data->io_id = 0;
+	if (data->io) {
+		l_io_destroy(data->io);
+		data->io = NULL;
+	}
+
+	if (data->io2) {
+		l_io_destroy(data->io2);
+		data->io2 = NULL;
 	}
 
 	hciemu_unref(data->hciemu);
@@ -230,18 +237,16 @@ static void test_post_teardown(const void *test_data)
 static void test_data_free(void *test_data)
 {
 	struct test_data *data = test_data;
-
-	free(data);
+	l_free(data);
 }
 
 #define test_l2cap_bredr(name, data, setup, func) \
 	do { \
 		struct test_data *user; \
-		user = malloc(sizeof(struct test_data)); \
+		user = l_new(struct test_data, 1);	\
 		if (!user) \
 			break; \
 		user->hciemu_type = HCIEMU_TYPE_BREDR; \
-		user->io_id = 0; \
 		user->test_data = data; \
 		tester_add_full(name, data, \
 				test_pre_setup, setup, func, NULL, \
@@ -251,11 +256,10 @@ static void test_data_free(void *test_data)
 #define test_l2cap_le(name, data, setup, func) \
 	do { \
 		struct test_data *user; \
-		user = malloc(sizeof(struct test_data)); \
+		user = l_new(struct test_data, 1);	\
 		if (!user) \
 			break; \
 		user->hciemu_type = HCIEMU_TYPE_LE; \
-		user->io_id = 0; \
 		user->test_data = data; \
 		tester_add_full(name, data, \
 				test_pre_setup, setup, func, NULL, \
@@ -886,19 +890,18 @@ static void test_basic(const void *test_data)
 	tester_test_passed();
 }
 
-static gboolean client_received_data(GIOChannel *io, GIOCondition cond,
-							gpointer user_data)
+static bool client_received_data(struct l_io *io, void *user_data)
 {
 	struct test_data *data = tester_get_data();
 	const struct l2cap_data *l2data = data->test_data;
 	char buf[1024];
 	int sk;
 
-	sk = g_io_channel_unix_get_fd(io);
+	sk = l_io_get_fd(io);
 	if (read(sk, buf, l2data->data_len) != l2data->data_len) {
 		tester_warn("Unable to read %u bytes", l2data->data_len);
 		tester_test_failed();
-		return FALSE;
+		return false;
 	}
 
 	if (memcmp(buf, l2data->read_data, l2data->data_len))
@@ -906,22 +909,22 @@ static gboolean client_received_data(GIOChannel *io, GIOCondition cond,
 	else
 		tester_test_passed();
 
-	return FALSE;
+	return true;
 }
 
-static gboolean server_received_data(GIOChannel *io, GIOCondition cond,
-							gpointer user_data)
+static bool server_received_data(struct l_io *io, void *user_data)
 {
 	struct test_data *data = tester_get_data();
 	const struct l2cap_data *l2data = data->test_data;
 	char buf[1024];
 	int sk;
 
-	sk = g_io_channel_unix_get_fd(io);
+	sk = l_io_get_fd(io);
 	if (read(sk, buf, l2data->data_len) != l2data->data_len) {
 		tester_warn("Unable to read %u bytes", l2data->data_len);
 		tester_test_failed();
-		return FALSE;
+		l_io_destroy(io);
+		return false;
 	}
 
 	if (memcmp(buf, l2data->read_data, l2data->data_len))
@@ -929,7 +932,9 @@ static gboolean server_received_data(GIOChannel *io, GIOCondition cond,
 	else
 		tester_test_passed();
 
-	return FALSE;
+	l_io_destroy(io);
+
+	return true;
 }
 
 static void bthost_received_data(const void *buf, uint16_t len,
@@ -966,27 +971,6 @@ static void server_bthost_received_data(const void *buf, uint16_t len,
 		tester_test_passed();
 }
 
-static gboolean socket_closed_cb(GIOChannel *io, GIOCondition cond,
-							gpointer user_data)
-{
-	struct test_data *data = tester_get_data();
-	const struct l2cap_data *l2data = data->test_data;
-
-	if (l2data->shut_sock_wr) {
-		/* if socket is closed using SHUT_WR, L2CAP disconnection
-		 * response must be received first before G_IO_HUP event.
-		 */
-		if (data->host_disconnected)
-			tester_test_passed();
-		else {
-			tester_warn("G_IO_HUP received before receiving L2CAP disconnection");
-			tester_test_failed();
-		}
-	}
-
-	return FALSE;
-}
-
 static bool check_mtu(struct test_data *data, int sk)
 {
 	const struct l2cap_data *l2data = data->test_data;
@@ -1029,17 +1013,52 @@ static bool check_mtu(struct test_data *data, int sk)
 	return true;
 }
 
-static gboolean l2cap_connect_cb(GIOChannel *io, GIOCondition cond,
-							gpointer user_data)
+static void l2cap_disconnect_cb(struct l_io *io, void *user_data)
 {
 	struct test_data *data = tester_get_data();
 	const struct l2cap_data *l2data = data->test_data;
 	int err, sk_err, sk;
 	socklen_t len = sizeof(sk_err);
 
-	data->io_id = 0;
+	tester_print("Disconnect callback");
+	if (l2data->shut_sock_wr) {
+		/* if socket is closed using SHUT_WR, L2CAP disconnection
+		 * response must be received first before EPOLLHUP event.
+		 */
+		if (data->host_disconnected)
+			tester_test_passed();
+		else {
+			tester_warn("HUP received before L2CAP disconnection");
+			tester_test_failed();
+		}
+
+		return;
+	}
+
+	sk = l_io_get_fd(io);
 
-	sk = g_io_channel_unix_get_fd(io);
+	if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &sk_err, &len) < 0)
+		err = -errno;
+	else
+		err = -sk_err;
+
+	if (l2data->expect_err) {
+
+		if (-err == l2data->expect_err)
+			tester_test_passed();
+		else
+			tester_test_failed();
+	}
+}
+
+static bool l2cap_connect_cb(struct l_io *io, void *user_data)
+{
+	struct test_data *data = tester_get_data();
+	const struct l2cap_data *l2data = data->test_data;
+	int err, sk_err, sk;
+	socklen_t len = sizeof(sk_err);
+
+	sk = l_io_get_fd(io);
 
 	if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &sk_err, &len) < 0)
 		err = -errno;
@@ -1055,19 +1074,19 @@ static gboolean l2cap_connect_cb(GIOChannel *io, GIOCondition cond,
 
 	if (!check_mtu(data, sk)) {
 		tester_test_failed();
-		return FALSE;
+		return false;
 	}
 
 	if (l2data->read_data) {
 		struct bthost *bthost;
 
 		bthost = hciemu_client_get_host(data->hciemu);
-		g_io_add_watch(io, G_IO_IN, client_received_data, NULL);
+		l_io_set_read_handler(io, client_received_data, NULL, NULL);
 
 		bthost_send_cid(bthost, data->handle, data->dcid,
 					l2data->read_data, l2data->data_len);
 
-		return FALSE;
+		return false;
 	} else if (l2data->write_data) {
 		struct bthost *bthost;
 		ssize_t ret;
@@ -1082,12 +1101,11 @@ static gboolean l2cap_connect_cb(GIOChannel *io, GIOCondition cond,
 			tester_test_failed();
 		}
 
-		return FALSE;
+		return false;
 	} else if (l2data->shut_sock_wr) {
-		g_io_add_watch(io, G_IO_HUP, socket_closed_cb, NULL);
 		shutdown(sk, SHUT_WR);
 
-		return FALSE;
+		return false;
 	}
 
 failed:
@@ -1096,7 +1114,7 @@ failed:
 	else
 		tester_test_passed();
 
-	return FALSE;
+	return false;
 }
 
 static int create_l2cap_sock(struct test_data *data, uint16_t psm,
@@ -1281,7 +1299,6 @@ static void test_connect(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
 	const struct l2cap_data *l2data = data->test_data;
-	GIOChannel *io;
 	int sk;
 
 	if (l2data->server_psm) {
@@ -1321,12 +1338,12 @@ static void test_connect(const void *test_data)
 		return;
 	}
 
-	io = g_io_channel_unix_new(sk);
-	g_io_channel_set_close_on_unref(io, TRUE);
+	data->io = l_io_new(sk);
 
-	data->io_id = g_io_add_watch(io, G_IO_OUT, l2cap_connect_cb, NULL);
+	l_io_set_close_on_destroy(data->io, true);
 
-	g_io_channel_unref(io);
+	l_io_set_disconnect_handler(data->io, l2cap_disconnect_cb, NULL, NULL);
+	l_io_set_write_handler(data->io, l2cap_connect_cb, NULL, NULL);
 
 	tester_print("Connect in progress");
 }
@@ -1353,12 +1370,12 @@ static void test_connect_reject(const void *test_data)
 	close(sk);
 }
 
-static int connect_socket(const uint8_t *client_bdaddr, GIOFunc connect_cb,
-								bool defer)
+static struct l_io *connect_socket(const uint8_t *client_bdaddr,
+					l_io_write_cb_t connect_cb, bool defer)
 {
 	struct test_data *data = tester_get_data();
 	const struct l2cap_data *l2data = data->test_data;
-	GIOChannel *io;
+	struct l_io *io;
 	int sk;
 
 	sk = create_l2cap_sock(data, 0, l2data->cid, l2data->sec_level,
@@ -1369,7 +1386,7 @@ static int connect_socket(const uint8_t *client_bdaddr, GIOFunc connect_cb,
 			tester_test_abort();
 		else
 			tester_test_failed();
-		return -1;
+		return NULL;
 	}
 
 	if (defer) {
@@ -1380,7 +1397,7 @@ static int connect_socket(const uint8_t *client_bdaddr, GIOFunc connect_cb,
 			tester_print("Can't enable deferred setup: %s (%d)",
 						strerror(errno), errno);
 			tester_test_failed();
-			return -1;
+			return NULL;
 		}
 	}
 
@@ -1389,25 +1406,20 @@ static int connect_socket(const uint8_t *client_bdaddr, GIOFunc connect_cb,
 		tester_print("Error in connect_l2cap_sock");
 		close(sk);
 		tester_test_failed();
-		return -1;
+		return NULL;
 	}
 
-	if (connect_cb) {
-		io = g_io_channel_unix_new(sk);
-		g_io_channel_set_close_on_unref(io, TRUE);
-
-		data->io_id = g_io_add_watch(io, G_IO_OUT, connect_cb, NULL);
-
-		g_io_channel_unref(io);
-	}
+	io = l_io_new(sk);
+	l_io_set_close_on_destroy(io, true);
+	l_io_set_write_handler(io, connect_cb, NULL, NULL);
 
 	tester_print("Connect in progress, sk = %d %s", sk,
 				defer ? "(deferred)" : "");
 
-	return sk;
+	return io;
 }
 
-static gboolean test_close_socket_1_part_3(gpointer arg)
+static void test_close_socket_1_part_3(void *arg)
 {
 	struct test_data *data = tester_get_data();
 
@@ -1416,20 +1428,19 @@ static gboolean test_close_socket_1_part_3(gpointer arg)
 	if (data->sk != -1) {
 		tester_print("Error - scan was not enabled yet");
 		tester_test_failed();
-		return FALSE;
+		return;
 	}
 
 	if (hciemu_get_master_le_scan_enable(data->hciemu)) {
 		tester_print("Delayed check whether scann is off failed");
 		tester_test_failed();
-		return FALSE;
+		return;
 	}
 
 	tester_test_passed();
-	return FALSE;
 }
 
-static gboolean test_close_socket_1_part_2(gpointer args)
+static void test_close_socket_1_part_2(void *args)
 {
 	struct test_data *data = tester_get_data();
 	int sk = data->sk;
@@ -1443,7 +1454,7 @@ static gboolean test_close_socket_1_part_2(gpointer args)
 	if (!hciemu_get_master_le_scan_enable(data->hciemu)) {
 		tester_print("Error - should be still scanning");
 		tester_test_failed();
-		return FALSE;
+		return;
 	}
 
 	/* Calling close() should remove device from  whitelist, and stop
@@ -1452,15 +1463,14 @@ static gboolean test_close_socket_1_part_2(gpointer args)
 	if (close(sk) < 0) {
 		tester_print("Error when closing socket");
 		tester_test_failed();
-		return FALSE;
+		return;
 	}
 
 	data->sk = -1;
 	/* tester_test_passed will be called when scan is stopped. */
-	return FALSE;
 }
 
-static gboolean test_close_socket_2_part_3(gpointer arg)
+static void test_close_socket_2_part_3(void *arg)
 {
 	struct test_data *data = tester_get_data();
 	int sk = data->sk;
@@ -1470,7 +1480,7 @@ static gboolean test_close_socket_2_part_3(gpointer arg)
 	if (hciemu_get_master_le_scan_enable(data->hciemu)) {
 		tester_print("Error - should no longer scan");
 		tester_test_failed();
-		return FALSE;
+		return;
 	}
 
 	/* Calling close() should eventually cause CMD_LE_CREATE_CONN_CANCEL */
@@ -1478,11 +1488,10 @@ static gboolean test_close_socket_2_part_3(gpointer arg)
 	if (err < 0) {
 		tester_print("Error when closing socket");
 		tester_test_failed();
-		return FALSE;
+		return;
 	}
 
 	/* CMD_LE_CREATE_CONN_CANCEL will trigger test pass. */
-	return FALSE;
 }
 
 static bool test_close_socket_cc_hook(const void *data, uint16_t len,
@@ -1491,7 +1500,7 @@ static bool test_close_socket_cc_hook(const void *data, uint16_t len,
 	return false;
 }
 
-static gboolean test_close_socket_2_part_2(gpointer arg)
+static void test_close_socket_2_part_2(void *arg)
 {
 	struct test_data *data = tester_get_data();
 	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
@@ -1507,7 +1516,6 @@ static gboolean test_close_socket_2_part_2(gpointer arg)
 	 */
 	bthost_set_adv_enable(bthost, 0x01);
 	bthost_set_adv_enable(bthost, 0x00);
-	return FALSE;
 }
 
 static void test_close_socket_scan_enabled(void)
@@ -1516,9 +1524,9 @@ static void test_close_socket_scan_enabled(void)
 	const struct l2cap_data *l2data = data->test_data;
 
 	if (l2data == &le_client_close_socket_test_1)
-		g_idle_add(test_close_socket_1_part_2, NULL);
+		l_idle_oneshot(test_close_socket_1_part_2, NULL, NULL);
 	else if (l2data == &le_client_close_socket_test_2)
-		g_idle_add(test_close_socket_2_part_2, NULL);
+		l_idle_oneshot(test_close_socket_2_part_2, NULL, NULL);
 }
 
 static void test_close_socket_scan_disabled(void)
@@ -1527,9 +1535,9 @@ static void test_close_socket_scan_disabled(void)
 	const struct l2cap_data *l2data = data->test_data;
 
 	if (l2data == &le_client_close_socket_test_1)
-		g_idle_add(test_close_socket_1_part_3, NULL);
+		l_idle_oneshot(test_close_socket_1_part_3, NULL, NULL);
 	else if (l2data == &le_client_close_socket_test_2)
-		g_idle_add(test_close_socket_2_part_3, NULL);
+		l_idle_oneshot(test_close_socket_2_part_3, NULL, NULL);
 }
 
 static void test_close_socket_conn_cancel(void)
@@ -1571,21 +1579,19 @@ static void test_close_socket(const void *test_data)
 	else
 		client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
 
-	data->sk = connect_socket(client_bdaddr, NULL, false);
+	data->io = connect_socket(client_bdaddr, NULL, false);
+	data->sk = l_io_get_fd(data->io);
 }
 
 static uint8_t test_2_connect_cb_cnt;
-static gboolean test_2_connect_cb(GIOChannel *io, GIOCondition cond,
-							gpointer user_data)
+static bool test_2_connect_cb(struct l_io *io, void *user_data)
 {
 	struct test_data *data = tester_get_data();
 	const struct l2cap_data *l2data = data->test_data;
 	int err, sk_err, sk;
 	socklen_t len = sizeof(sk_err);
 
-	data->io_id = 0;
-
-	sk = g_io_channel_unix_get_fd(io);
+	sk = l_io_get_fd(io);
 
 	if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &sk_err, &len) < 0)
 		err = -errno;
@@ -1595,7 +1601,7 @@ static gboolean test_2_connect_cb(GIOChannel *io, GIOCondition cond,
 	if (err < 0) {
 		tester_warn("Connect failed: %s (%d)", strerror(-err), -err);
 		tester_test_failed();
-		return FALSE;
+		return false;
 	}
 
 	tester_print("Successfully connected");
@@ -1612,16 +1618,15 @@ static gboolean test_2_connect_cb(GIOChannel *io, GIOCondition cond,
 		tester_test_passed();
 	}
 
-	return FALSE;
+	return true;
 }
 
-static gboolean enable_advertising(gpointer args)
+static void enable_advertising(void *args)
 {
 	struct test_data *data = tester_get_data();
 	struct bthost *bthost = hciemu_client_get_host(data->hciemu);
 
 	bthost_set_adv_enable(bthost, 0x01);
-	return FALSE;
 }
 
 static void test_connect_2_part_2(void)
@@ -1631,14 +1636,15 @@ static void test_connect_2_part_2(void)
 	const uint8_t *client_bdaddr;
 
 	client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
-	data->sk2 = connect_socket(client_bdaddr, test_2_connect_cb, false);
+	data->io2 = connect_socket(client_bdaddr, test_2_connect_cb, false);
+	data->sk2 = l_io_get_fd(data->io2);
 
 	if (l2data->close_1) {
 		tester_print("Closing first socket! %d", data->sk);
 		close(data->sk);
 	}
 
-	g_idle_add(enable_advertising, NULL);
+	l_idle_oneshot(enable_advertising, NULL, NULL);
 }
 
 static uint8_t test_scan_enable_counter;
@@ -1654,7 +1660,7 @@ static void test_connect_2_router(uint16_t opcode, const void *param,
 		if (test_scan_enable_counter == 1)
 			test_connect_2_part_2();
 		else if (test_scan_enable_counter == 2)
-			g_idle_add(enable_advertising, NULL);
+			l_idle_oneshot(enable_advertising, NULL, NULL);
 	}
 }
 
@@ -1683,50 +1689,47 @@ static void test_connect_2(const void *test_data)
 
 	client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
 	if (l2data->close_1)
-		data->sk = connect_socket(client_bdaddr, NULL, defer);
+		data->io = connect_socket(client_bdaddr, NULL, defer);
 	else
-		data->sk = connect_socket(client_bdaddr, test_2_connect_cb,
+		data->io = connect_socket(client_bdaddr, test_2_connect_cb,
 								defer);
+	data->sk = l_io_get_fd(data->io);
 }
 
-static gboolean l2cap_listen_cb(GIOChannel *io, GIOCondition cond,
-							gpointer user_data)
+static bool l2cap_listen_cb(struct l_io *io, void *user_data)
 {
 	struct test_data *data = tester_get_data();
 	const struct l2cap_data *l2data = data->test_data;
 	int sk, new_sk;
 
-	data->io_id = 0;
-
-	sk = g_io_channel_unix_get_fd(io);
+	sk = l_io_get_fd(io);
 
 	new_sk = accept(sk, NULL, NULL);
 	if (new_sk < 0) {
 		tester_warn("accept failed: %s (%u)", strerror(errno), errno);
 		tester_test_failed();
-		return FALSE;
+		return false;
 	}
 
 	if (!check_mtu(data, new_sk)) {
 		tester_test_failed();
-		return FALSE;
+		return false;
 	}
 
 	if (l2data->read_data) {
 		struct bthost *bthost;
-		GIOChannel *new_io;
+		struct l_io *new_io;
+
+		new_io = l_io_new(new_sk);
 
-		new_io = g_io_channel_unix_new(new_sk);
-		g_io_channel_set_close_on_unref(new_io, TRUE);
+		l_io_set_close_on_destroy(new_io, true);
 
 		bthost = hciemu_client_get_host(data->hciemu);
-		g_io_add_watch(new_io, G_IO_IN, server_received_data, NULL);
+		l_io_set_read_handler(new_io, server_received_data, NULL, NULL);
 		bthost_send_cid(bthost, data->handle, data->dcid,
 					l2data->read_data, l2data->data_len);
 
-		g_io_channel_unref(new_io);
-
-		return FALSE;
+		return false;
 	} else if (l2data->write_data) {
 		struct bthost *bthost;
 		ssize_t ret;
@@ -1743,7 +1746,7 @@ static gboolean l2cap_listen_cb(GIOChannel *io, GIOCondition cond,
 			tester_test_failed();
 		}
 
-		return FALSE;
+		return false;
 	}
 
 	tester_print("Successfully connected");
@@ -1752,7 +1755,7 @@ static gboolean l2cap_listen_cb(GIOChannel *io, GIOCondition cond,
 
 	tester_test_passed();
 
-	return FALSE;
+	return false;
 }
 
 static void client_l2cap_rsp(uint8_t code, const void *data, uint16_t len,
@@ -1839,7 +1842,6 @@ static void test_server(const void *test_data)
 	const uint8_t *master_bdaddr;
 	uint8_t addr_type;
 	struct bthost *bthost;
-	GIOChannel *io;
 	int sk;
 
 	if (l2data->server_psm || l2data->cid) {
@@ -1859,12 +1861,10 @@ static void test_server(const void *test_data)
 			return;
 		}
 
-		io = g_io_channel_unix_new(sk);
-		g_io_channel_set_close_on_unref(io, TRUE);
+		data->io = l_io_new(sk);
 
-		data->io_id = g_io_add_watch(io, G_IO_IN, l2cap_listen_cb,
-									NULL);
-		g_io_channel_unref(io);
+		l_io_set_close_on_destroy(data->io, true);
+		l_io_set_read_handler(data->io, l2cap_listen_cb, NULL, NULL);
 
 		tester_print("Listening for connections");
 	}
