Index: uspace/lib/hound/src/protocol.c
===================================================================
--- uspace/lib/hound/src/protocol.c	(revision 9e1800cd0d11714b8a9dd6d7e56a5e435315d57d)
+++ uspace/lib/hound/src/protocol.c	(revision 842eecdd6f82b689a612a0107057725b919e8a61)
@@ -49,10 +49,12 @@
 	IPC_M_HOUND_CONTEXT_REGISTER = IPC_FIRST_USER_METHOD,
 	IPC_M_HOUND_CONTEXT_UNREGISTER,
-	IPC_M_HOUND_STREAM_START,
-	IPC_M_HOUND_STREAM_STOP,
+	IPC_M_HOUND_STREAM_ENTER,
+	IPC_M_HOUND_STREAM_EXIT,
 	IPC_M_HOUND_STREAM_DRAIN,
-	IPC_M_HOUND_STREAM_WRITE,
-	IPC_M_HOUND_STREAM_READ,
 };
+
+/****
+ * CLIENT
+ ****/
 
 const char *HOUND_SERVICE = "audio/hound";
@@ -75,14 +77,16 @@
 
 hound_context_id_t hound_service_register_context(hound_sess_t *sess,
-    const char *name)
+    const char *name, bool record)
 {
 	assert(sess);
 	assert(name);
 	async_exch_t *exch = async_exchange_begin(sess);
-	const int ret =
-	    async_req_1_0(exch, IPC_M_HOUND_CONTEXT_REGISTER, str_size(name));
-	//TODO send the string
+	sysarg_t id;
+	int ret =
+	    async_req_1_1(exch, IPC_M_HOUND_CONTEXT_REGISTER, record, &id);
+	if (ret == EOK)
+		ret = async_data_write_start(exch, name, str_size(name));
 	async_exchange_end(exch);
-	return ret;
+	return ret == EOK ? (hound_context_id_t)id : ret;
 }
 
@@ -100,30 +104,144 @@
     int flags, pcm_format_t format, size_t bsize)
 {
+	union {
+		sysarg_t arg;
+		pcm_format_t format;
+	} convert = { .format = format };
+	return async_req_4_0(exch, IPC_M_HOUND_STREAM_ENTER, id, flags,
+	    convert.arg, bsize);
+}
+
+int hound_service_stream_exit(async_exch_t *exch)
+{
+	return async_req_0_0(exch, IPC_M_HOUND_STREAM_EXIT);
+}
+
+int hound_service_stream_drain(async_exch_t *exch)
+{
+	//TODO implement
 	return ENOTSUP;
 }
 
-int hound_service_stream_exit(async_exch_t *exch)
-{
+int hound_service_stream_write(async_exch_t *exch, const void *data, size_t size)
+{
+	return async_data_write_start(exch, data, size);
+}
+
+int hound_service_stream_read(async_exch_t *exch, void *data, size_t size)
+{
+	//TODO implement
 	return ENOTSUP;
 }
 
-int hound_service_stream_drain(async_exch_t *exch)
-{
-	return ENOTSUP;
-}
-
-int hound_service_stream_write(async_exch_t *exch, const void *data, size_t size)
-{
-	return ENOTSUP;
-}
-
-int hound_service_stream_read(async_exch_t *exch, void *data, size_t size)
-{
-	return ENOTSUP;
-}
-
+/****
+ * SERVER
+ ****/
+
+static int hound_server_read_data(void *stream);
+static hound_server_iface_t *server_iface;
+
+void hound_service_set_server_iface(hound_server_iface_t *iface)
+{
+	server_iface = iface;
+}
+
+void hound_connection_handler(ipc_callid_t iid, ipc_call_t *icall, void *arg)
+{
+	/* Accept connection if there is a valid iface*/
+	if (server_iface) {
+		async_answer_0(iid, EOK);
+	} else {
+		async_answer_0(iid, ENOTSUP);
+		return;
+	}
+
+	while (1) {
+		ipc_call_t call;
+		ipc_callid_t callid = async_get_call(&call);
+		switch(IPC_GET_IMETHOD(call)) {
+		case IPC_M_HOUND_CONTEXT_REGISTER: {
+			if (!server_iface || !server_iface->add_context) {
+				async_answer_0(callid, ENOTSUP);
+				break;
+			}
+			bool record = IPC_GET_ARG1(call);
+			void *name;
+			int ret =
+			    async_data_write_accept(&name, true, 0, 0, 0, 0);
+			if (ret != EOK) {
+				async_answer_0(callid, ret);
+				break;
+			}
+			hound_context_id_t id = 0;
+			ret = server_iface->add_context(server_iface->server,
+			    &id, name, record);
+			if (ret != EOK) {
+				free(name);
+				async_answer_0(callid, ret);
+				break;
+			}
+			async_answer_1(callid, EOK, id);
+		}
+		case IPC_M_HOUND_STREAM_ENTER: {
+			if (!server_iface || !server_iface->add_stream) {
+				async_answer_0(callid, ENOTSUP);
+				break;
+			}
+
+			hound_context_id_t id = IPC_GET_ARG1(call);
+			int flags = IPC_GET_ARG2(call);
+			union {
+				sysarg_t arg;
+				pcm_format_t format;
+			} convert = { .arg = IPC_GET_ARG3(call) };
+			size_t bsize = IPC_GET_ARG4(call);
+			void *stream;
+			int ret = server_iface->add_stream(server_iface->server,
+			    id, flags, convert.format, bsize, &stream);
+			if (ret != EOK) {
+				async_answer_0(callid, ret);
+				break;
+			}
+			hound_server_read_data(stream);
+			break;
+		}
+		case IPC_M_HOUND_CONTEXT_UNREGISTER:
+		case IPC_M_HOUND_STREAM_EXIT:
+		case IPC_M_HOUND_STREAM_DRAIN:
+		default:
+			async_answer_0(callid, ENOTSUP);
+			return;
+		}
+	}
+}
+
+static int hound_server_read_data(void *stream)
+{
+	if (!server_iface || !server_iface->stream_data_write)
+		return ENOTSUP;
+
+	ipc_callid_t callid;
+	size_t size = 0;
+	while (async_data_write_receive(&callid, &size)) {
+		char *buffer = malloc(size);
+		if (!buffer) {
+			async_answer_0(callid, ENOMEM);
+			continue;
+		}
+		int ret = async_data_write_finalize(callid, buffer, size);
+		if (ret == EOK) {
+			server_iface->stream_data_write(stream, buffer, size);
+		} else {
+			// TODO did answering fail?
+			async_answer_0(callid, ret);
+		}
+	}
+	//TODO we assume that the fail was caused by IPC_M_HOUND_STREAM_EXIT
+	async_answer_0(callid, EOK);
+	return EOK;
+}
 
 /***
- * CLIENT SIDE
+ * CLIENT SIDE -DEPRECATED
  ***/
 
@@ -348,6 +466,7 @@
 
 /***
- * SERVER SIDE
+ * SERVER SIDE - DEPRECATED
  ***/
+
 static const char * get_name(void);
 
Index: uspace/lib/hound/src/protocol.h
===================================================================
--- uspace/lib/hound/src/protocol.h	(revision 9e1800cd0d11714b8a9dd6d7e56a5e435315d57d)
+++ 	(revision )
@@ -1,65 +1,0 @@
-/*
- * Copyright (c) 2013 Jan Vesely
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- *   notice, this list of conditions and the following disclaimer.
- * - Redistributions in binary form must reproduce the above copyright
- *   notice, this list of conditions and the following disclaimer in the
- *   documentation and/or other materials provided with the distribution.
- * - The name of the author may not be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-/** @addtogroup libhound
- * @addtogroup audio
- * @{
- */
-/** @file
- * @brief Audio PCM buffer interface.
- */
-
-#ifndef LIBHOUND_PROTOCOL_H_
-#define LIBHOUND_PROTOCOL_H_
-
-#include <async.h>
-#include <pcm/format.h>
-
-const char *HOUND_SERVICE;
-
-typedef async_sess_t hound_sess_t;
-typedef int hound_context_id_t;
-
-hound_sess_t *hound_service_connect(const char *service);
-void hound_service_disconnect(hound_sess_t *sess);
-
-hound_context_id_t hound_service_register_context(hound_sess_t *sess,
-    const char *name);
-int hound_service_unregister_context(hound_sess_t *sess, hound_context_id_t id);
-
-int hound_service_stream_enter(async_exch_t *exch, hound_context_id_t id,
-    int flags, pcm_format_t format, size_t bsize);
-int hound_service_stream_drain(async_exch_t *exch);
-int hound_service_stream_exit(async_exch_t *exch);
-
-int hound_service_stream_write(async_exch_t *exch, const void *data, size_t size);
-int hound_service_stream_read(async_exch_t *exch, void *data, size_t size);
-
-
-#endif
-/** @}
- */
