Index: uspace/srv/audio/hound/Makefile
===================================================================
--- uspace/srv/audio/hound/Makefile	(revision 57e8b3ba054d7a008b430e7b6b67994b03197240)
+++ uspace/srv/audio/hound/Makefile	(revision 50fa3f71ca2caf299b38bcd97bee669a74d1585b)
@@ -32,8 +32,10 @@
 EXTRA_CFLAGS = \
 	-DNAME="\"hound\"" \
-	-I$(LIBDRV_PREFIX)/include
+	-I$(LIBDRV_PREFIX)/include \
+	-I$(LIBHOUND_PREFIX)/include
 
 LIBS = \
-	$(LIBDRV_PREFIX)/libdrv.a
+	$(LIBDRV_PREFIX)/libdrv.a \
+	$(LIBHOUND_PREFIX)/libhound.a
 
 SOURCES = \
Index: uspace/srv/audio/hound/main.c
===================================================================
--- uspace/srv/audio/hound/main.c	(revision 57e8b3ba054d7a008b430e7b6b67994b03197240)
+++ uspace/srv/audio/hound/main.c	(revision 50fa3f71ca2caf299b38bcd97bee669a74d1585b)
@@ -38,8 +38,9 @@
 #include <bool.h>
 #include <errno.h>
-#include <loc.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <str_error.h>
+#include <hound/server.h>
+
 
 #include "hound.h"
@@ -51,86 +52,15 @@
 #include "audio_client.h"
 #include "log.h"
-#include "protocol.h"
 
 static hound_t hound;
 
-static inline audio_format_t read_format(const ipc_call_t *call)
-{
-	audio_format_t format = {
-		.channels = IPC_GET_ARG1(*call),
-		.sampling_rate = IPC_GET_ARG2(*call),
-		.sample_format = IPC_GET_ARG3(*call),
-	};
-	return format;
-}
-static inline const char *get_name()
-{
-	size_t size = 0;
-	ipc_callid_t callid;
-	async_data_write_receive(&callid, &size);
-	char *buffer = malloc(size);
-	if (buffer) {
-		async_data_write_finalize(callid, buffer, size);
-		buffer[size - 1] = 0;
-		log_verbose("Got name from client: %s", buffer);
-	}
-	return buffer;
-}
-static inline async_sess_t *get_session()
-{
-	ipc_call_t call;
-	ipc_callid_t callid = async_get_call(&call);
-	async_sess_t *s = async_callback_receive_start(EXCHANGE_ATOMIC, &call);
-	async_answer_0(callid, s ? EOK : ENOMEM);
-	if (s) {
-		log_verbose("Received callback session");
-	} else
-		log_debug("Failed to receive callback session");
-	return s;
-}
-
+static int device_callback(service_id_t id, const char *name)
+{
+	return hound_add_device(&hound, id, name);
+}
 
 static void scan_for_devices(void)
 {
-	static bool cat_resolved = false;
-	static category_id_t cat;
-
-	if (!cat_resolved) {
-		log_verbose("Resolving category \"%s\".", CATEGORY);
-		const int ret = loc_category_get_id(CATEGORY, &cat,
-		    IPC_FLAG_BLOCKING);
-		if (ret != EOK) {
-			log_error("Failed to get category: %s", str_error(ret));
-			return;
-		}
-		cat_resolved = true;
-	}
-
-	log_verbose("Getting available services in category.");
-
-	service_id_t *svcs = NULL;
-	size_t count = 0;
-	const int ret = loc_category_get_svcs(cat, &svcs, &count);
-	if (ret != EOK) {
-		log_error("Failed to get audio devices: %s", str_error(ret));
-		return;
-	}
-
-	for (unsigned i = 0; i < count; ++i) {
-		char *name = NULL;
-		int ret = loc_service_get_name(svcs[i], &name);
-		if (ret != EOK) {
-			log_error("Failed to get dev name: %s", str_error(ret));
-			continue;
-		}
-		ret = hound_add_device(&hound, svcs[i], name);
-		if (ret != EOK && ret != EEXISTS) {
-			log_error("Failed to add audio device \"%s\": %s",
-			    name, str_error(ret));
-		}
-		free(name);
-	}
-
-	free(svcs);
+	hound_server_devices_iterate(device_callback);
 }
 
@@ -141,4 +71,7 @@
 	LIST_INITIALIZE(local_playback);
 	LIST_INITIALIZE(local_recording);
+	audio_format_t format = {0};
+	const char *name = NULL;
+	async_sess_t *sess = NULL;
 
 	while (1) {
@@ -147,7 +80,7 @@
 		switch (IPC_GET_IMETHOD(call)) {
 		case HOUND_REGISTER_PLAYBACK: {
-			const audio_format_t format = read_format(&call);
-			const char *name = get_name();
-			async_sess_t *sess = get_session();
+			hound_server_get_register_params(&name, &sess,
+			    &format.channels, &format.sampling_rate,
+			    &format.sample_format);
 			audio_client_t *client =
 			    audio_client_get_playback(name, &format, sess);
@@ -173,8 +106,8 @@
 		}
 		case HOUND_REGISTER_RECORDING: {
-			const audio_format_t format = read_format(&call);
-			const char *name = get_name();
-			async_sess_t *sess = get_session();
-			audio_client_t * client =
+			hound_server_get_register_params(&name, &sess,
+			    &format.channels, &format.sampling_rate,
+			    &format.sample_format);
+			audio_client_t *client =
 			    audio_client_get_recording(name, &format, sess);
 			free(name);
@@ -197,5 +130,6 @@
 		}
 		case HOUND_UNREGISTER_PLAYBACK: {
-			const char *name = get_name();
+			const char *name = NULL;
+			hound_server_get_unregister_params(&name);
 			int ret = ENOENT;
 			list_foreach(local_playback, it) {
@@ -217,5 +151,6 @@
 		}
 		case HOUND_UNREGISTER_RECORDING: {
-			const char *name = get_name();
+			const char *name = NULL;
+			hound_server_get_unregister_params(&name);
 			int ret = ENOENT;
 			list_foreach(local_recording, it) {
@@ -237,24 +172,24 @@
 		}
 		case HOUND_CONNECT: {
-			const char *name_a = get_name();
-			const char *name_b = get_name();
-			const int ret = hound_connect(&hound, name_a, name_b);
+			const char *source = NULL, *sink = NULL;
+			hound_server_get_connection_params(&source, &sink);
+			const int ret = hound_connect(&hound, source, sink);
 			if (ret != EOK)
 				log_error("Failed to connect '%s' to '%s': %s",
-				    name_a, name_b, str_error(ret));
-			free(name_a);
-			free(name_b);
+				    source, sink, str_error(ret));
+			free(source);
+			free(sink);
 			async_answer_0(callid, ret);
 			break;
 		}
 		case HOUND_DISCONNECT: {
-			const char *name_a = get_name();
-			const char *name_b = get_name();
-			const int ret = hound_disconnect(&hound, name_a, name_b);
+			const char *source = NULL, *sink = NULL;
+			hound_server_get_connection_params(&source, &sink);
+			const int ret = hound_disconnect(&hound, source, sink);
 			if (ret != EOK)
 				log_error("Failed to disconnect '%s' from '%s'"
-				    ": %s", name_a, name_b, str_error(ret));
-			free(name_a);
-			free(name_b);
+				    ": %s", source, sink, str_error(ret));
+			free(source);
+			free(sink);
 			async_answer_0(callid, ret);
 			break;
@@ -282,5 +217,4 @@
 				audio_client_destroy(client);
 			}
-			//TODO remove all clients
 			return;
 		}
@@ -300,26 +234,17 @@
 
 	async_set_client_connection(client_connection);
-	ret = loc_server_register(NAME);
+
+	service_id_t id = 0;
+	ret = hound_server_register(NAME, &id);
 	if (ret != EOK) {
-		log_fatal("Failed to register sound server: %s",
+		log_fatal("Failed to register server: %s", str_error(ret));
+		return -ret;
+	}
+
+	ret = hound_server_set_device_change_callback(scan_for_devices);
+	if (ret != EOK) {
+		log_fatal("Failed to register for device changes: %s",
 		    str_error(ret));
-		return -ret;
-	}
-
-	char fqdn[LOC_NAME_MAXLEN + 1];
-	snprintf(fqdn, LOC_NAME_MAXLEN, "%s/%s", NAMESPACE, NAME);
-	service_id_t id = 0;
-	ret = loc_service_register(fqdn, &id);
-	if (ret != EOK) {
-		log_fatal("Failed to register sound service: %s",
-		    str_error(ret));
-		return -ret;
-	}
-
-	ret = loc_register_cat_change_cb(scan_for_devices);
-	if (ret != EOK) {
-		log_fatal("Failed to register for category changes: %s",
-		    str_error(ret));
-		loc_service_unregister(id);
+		hound_server_unregister(id);
 		return -ret;
 	}
Index: uspace/srv/audio/hound/protocol.h
===================================================================
--- uspace/srv/audio/hound/protocol.h	(revision 57e8b3ba054d7a008b430e7b6b67994b03197240)
+++ 	(revision )
@@ -1,51 +1,0 @@
-/*
- * Copyright (c) 2012 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 audio
- * @brief HelenOS sound server
- * @{
- */
-/** @file
- */
-
-#ifndef PROTOCOL_H_
-#define PROTOCOL_H_
-
-#include <async.h>
-
-enum {
-	HOUND_REGISTER_PLAYBACK = IPC_FIRST_USER_METHOD,
-	HOUND_REGISTER_RECORDING,
-	HOUND_UNREGISTER_PLAYBACK,
-	HOUND_UNREGISTER_RECORDING,
-	HOUND_CONNECT,
-	HOUND_DISCONNECT,
-};
-
-#endif
-
