diff --git a/src/client/gui.c b/src/client/gui.c
index 54563bf4c34e680770969dc11595256ac8e6b8c6..0b79118d98b11eced340706758eb4d68ab49b621 100644
--- a/src/client/gui.c
+++ b/src/client/gui.c
@@ -197,11 +197,13 @@ static void gui_update_nick(GtkEditable *ed, ChatLog *p)
 
 static void gui_request_control(GtkWidget *w, gpointer data)
 {
-
+	const gchar *pwd;
 	gchar *digest;
 
+	pwd = gtk_entry_get_text(GTK_ENTRY(data));
+
 	digest = g_compute_hmac_for_string(G_CHECKSUM_SHA256,
-					   (guint8*)"radtel", 6,
+					   (guint8*) pwd, 6,
 					   "thisishardcoed", 13);
 
 
@@ -223,6 +225,7 @@ static GtkWidget *gui_create_popover_menu(GtkWidget *widget)
 
 	GtkWidget *w;
 	GtkWidget *pop;
+	GtkWidget *pwd;
 
 	GSettings *s;
 
@@ -321,7 +324,8 @@ static GtkWidget *gui_create_popover_menu(GtkWidget *widget)
 	gtk_grid_attach(GTK_GRID(grid), w, 1, 3, 1, 1);
 
 
-	w = gtk_label_new("Request Control");
+
+	w = gtk_label_new("Control Password");
 	gtk_widget_set_halign(w, GTK_ALIGN_END);
 	gtk_widget_set_valign(w, GTK_ALIGN_BASELINE);
 	gtk_style_context_add_class(gtk_widget_get_style_context(w),
@@ -330,6 +334,27 @@ static GtkWidget *gui_create_popover_menu(GtkWidget *widget)
 
 
 
+	pwd = gtk_entry_new();
+	gtk_entry_set_text(GTK_ENTRY(pwd), "radtel");
+
+	gtk_entry_set_alignment(GTK_ENTRY(pwd), 1.0);
+
+	gtk_widget_set_tooltip_text(pwd, "Control Password");
+	gtk_entry_set_visibility(GTK_ENTRY(pwd), FALSE);
+
+	gtk_grid_attach(GTK_GRID(grid), pwd, 1, 4, 1, 1);
+
+
+
+	w = gtk_label_new("Request Control");
+	gtk_widget_set_halign(w, GTK_ALIGN_END);
+	gtk_widget_set_valign(w, GTK_ALIGN_BASELINE);
+	gtk_style_context_add_class(gtk_widget_get_style_context(w),
+				    "dim-label");
+	gtk_grid_attach(GTK_GRID(grid), w, 0, 5, 1, 1);
+
+
+
 	w = gtk_button_new();
 	gtk_button_set_always_show_image(GTK_BUTTON(w), TRUE);
 	gtk_button_set_image(GTK_BUTTON(w),
@@ -338,9 +363,9 @@ static GtkWidget *gui_create_popover_menu(GtkWidget *widget)
 	gtk_widget_set_tooltip_text(w, "Request Control");
 
 	g_signal_connect(G_OBJECT(w), "clicked",
-			 G_CALLBACK(gui_request_control), NULL);
+			 G_CALLBACK(gui_request_control), pwd);
 
-	gtk_grid_attach(GTK_GRID(grid), w, 1, 4, 1, 1);
+	gtk_grid_attach(GTK_GRID(grid), w, 1, 5, 1, 1);
 
 
 
@@ -349,7 +374,7 @@ static GtkWidget *gui_create_popover_menu(GtkWidget *widget)
 	gtk_widget_set_valign(w, GTK_ALIGN_BASELINE);
 	gtk_style_context_add_class(gtk_widget_get_style_context(w),
 				    "dim-label");
-	gtk_grid_attach(GTK_GRID(grid), w, 0, 5, 1, 1);
+	gtk_grid_attach(GTK_GRID(grid), w, 0, 6, 1, 1);
 
 	w = gtk_button_new();
 	gtk_button_set_always_show_image(GTK_BUTTON(w), TRUE);
@@ -361,9 +386,7 @@ static GtkWidget *gui_create_popover_menu(GtkWidget *widget)
 	g_signal_connect(G_OBJECT(w), "clicked",
 			 G_CALLBACK(gui_reconnect_net), NULL);
 
-	gtk_grid_attach(GTK_GRID(grid), w, 1, 5, 1, 1);
-
-
+	gtk_grid_attach(GTK_GRID(grid), w, 1, 6, 1, 1);
 
 
 
diff --git a/src/client/widgets/chatlog/chatlog.c b/src/client/widgets/chatlog/chatlog.c
index 2b4b5de1ca856020a29740f5ba19843520310523..9f48f52a047387d422551fa816b697d572183402 100644
--- a/src/client/widgets/chatlog/chatlog.c
+++ b/src/client/widgets/chatlog/chatlog.c
@@ -223,6 +223,7 @@ static GtkWidget *chatlog_create_chat(ChatLog *p)
 	gtk_container_add(GTK_CONTAINER(w), textview);
 
 
+	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD);
 	b = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
 	gtk_text_buffer_get_end_iter(b, &iter);
 	/* create right gravity mark on empty buffer, will always stay
@@ -310,6 +311,8 @@ static GtkWidget *chatlog_create_log(ChatLog *p)
 
 	textview = gtk_text_view_new();
 	gtk_text_view_set_left_margin(GTK_TEXT_VIEW(textview), 3);
+	gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(textview), GTK_WRAP_WORD);
+
 	gtk_container_add(GTK_CONTAINER(w), textview);
 
 	b = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview));
diff --git a/src/include/ack.h b/src/include/ack.h
index c903651d7c155fb0be356bbfd06e0f4de5ff3a16..fdde7301bbbb8455a4d2a4ed3506f3fe07667458 100644
--- a/src/include/ack.h
+++ b/src/include/ack.h
@@ -22,6 +22,32 @@
 #include <protocol.h>
 #include <net_common.h>
 
+/* ack packet generation functions */
+
+struct packet *ack_invalid_pkt_gen(uint16_t trans_id);
+struct packet *ack_capabilities_gen(uint16_t trans_id, struct capabilities *c);
+struct packet *ack_getpos_azel_gen(uint16_t trans_id, struct getpos *pos);
+struct packet *ack_spec_data_gen(uint16_t trans_id, struct spec_data *s);
+struct packet *ack_spec_acq_enable_gen(uint16_t trans_id);
+struct packet *ack_spec_acq_disable_gen(uint16_t trans_id);
+struct packet *ack_fail_gen(uint16_t trans_id);
+struct packet *ack_success_gen(uint16_t trans_id);
+struct packet *ack_spec_acq_cfg_gen(uint16_t trans_id,
+				    struct spec_acq_cfg *acq);
+struct packet *ack_status_acq_gen(uint16_t trans_id, struct status *c);
+struct packet *ack_status_slew_get(uint16_t trans_id, struct status *c);
+struct packet *ack_status_move_gen(uint16_t trans_id, struct status *c);
+struct packet *ack_status_rec_gen(uint16_t trans_id, struct status *c);
+struct packet *ack_moveto_azel_gen(uint16_t trans_id, double az, double el);
+struct packet *ack_nopriv_gen(uint16_t trans_id);
+struct packet *ack_userlist_gen(uint16_t trans_id, const uint8_t *userlist,
+				uint16_t len);
+
+
+
+
+/* command generation and sending functions */
+
 void ack_invalid_pkt(uint16_t trans_id);
 void ack_capabilities(uint16_t trans_id, struct capabilities *c);
 void ack_getpos_azel(uint16_t trans_id, struct getpos *pos);
diff --git a/src/include/cmd.h b/src/include/cmd.h
index a7034bec262f3e1925fbbc5b3d2d6c618a0b9895..2808495dee8985e6eff6fbc09b3442497e299862 100644
--- a/src/include/cmd.h
+++ b/src/include/cmd.h
@@ -22,6 +22,34 @@
 #include <protocol.h>
 #include <net_common.h>
 
+
+/* command packet generation functions */
+
+struct packet *cmd_invalid_pkt_gen(uint16_t trans_id);
+struct packet *cmd_capabilities_gen(uint16_t trans_id);
+struct packet *cmd_success_gen(uint16_t trans_id);
+struct packet *cmd_fail_gen(uint16_t trans_id);
+struct packet *cmd_moveto_azel_gen(uint16_t trans_id, double az, double el);
+struct packet *cmd_recalibrate_pointing_gen(uint16_t trans_id);
+struct packet *cmd_park_telescope_gen(uint16_t trans_id);
+struct packet *cmd_spec_acq_cfg_gen(uint16_t trans_id,
+				    uint64_t f0, uint64_t f1, uint32_t bw_div,
+				    uint32_t bin_div, uint32_t n_stack,
+				    uint32_t acq_max);
+struct packet *cmd_getpos_azel_gen(uint16_t trans_id);
+struct packet *cmd_spec_acq_enable_gen(uint16_t trans_id);
+struct packet *cmd_spec_acq_disable_gen(uint16_t trans_id);
+struct packet *cmd_spec_acq_cfg_get_gen(uint16_t trans_id);
+struct packet *cmd_control_gen(uint16_t trans_id, const uint8_t *digest,
+			       uint16_t len);
+struct packet *cmd_message_gen(uint16_t trans_id, const uint8_t *message,
+			       uint16_t len);
+struct packet *cmd_nick_gen(uint16_t trans_id, const uint8_t *nick,
+			    uint16_t len);
+
+
+/* command generation and sending functions */
+
 void cmd_invalid_pkt(uint16_t trans_id);
 void cmd_capabilities(uint16_t trans_id);
 void cmd_success(uint16_t trans_id);
diff --git a/src/include/protocol.h b/src/include/protocol.h
index b439c74a4de9752944e3401cf0282087d052b63f..1644295451b9eca0dab0bcc38dfab65e1dec8585 100644
--- a/src/include/protocol.h
+++ b/src/include/protocol.h
@@ -104,6 +104,8 @@ struct packet {
 #define MAX_PACKET_SIZE (sizeof(struct packet) + MAX_PAYLOAD_SIZE)
 
 
+size_t pkt_size_get(struct packet *pkt);
+
 void pkt_hdr_to_net_order(struct packet *pkt);
 void pkt_hdr_to_host_order(struct packet *pkt);
 
diff --git a/src/net/acks/ack_capabilities.c b/src/net/acks/ack_capabilities.c
index 71471bf0d52c23ac72d885dd9e6e29e925d3bff3..61e688aa58e177ff0247e74bb9ab84a4f38bf182 100644
--- a/src/net/acks/ack_capabilities.c
+++ b/src/net/acks/ack_capabilities.c
@@ -25,7 +25,7 @@
  * @brief acknowledge backend capabilities command
  */
 
-void ack_capabilities(uint16_t trans_id, struct capabilities *c)
+struct packet *ack_capabilities_gen(uint16_t trans_id, struct capabilities *c)
 {
 	gsize pkt_size;
 	gsize data_size;
@@ -54,8 +54,19 @@ void ack_capabilities(uint16_t trans_id, struct capabilities *c)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void ack_capabilities(uint16_t trans_id, struct capabilities *c)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_capabilities_gen(trans_id, c);
+
 	g_debug("Sending capabilities");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/acks/ack_fail.c b/src/net/acks/ack_fail.c
index 200cc8cb2bb1d10dfb1b692f94bedb8bd203eb7a..b55ec13ae3c6f4666d947f6f145e8512a58ebeea 100644
--- a/src/net/acks/ack_fail.c
+++ b/src/net/acks/ack_fail.c
@@ -19,7 +19,7 @@
 #include <ack.h>
 
 
-void ack_fail(uint16_t trans_id, gpointer ref)
+struct packet *ack_fail_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,23 @@ void ack_fail(uint16_t trans_id, gpointer ref)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+/**
+ * @note this ack is always directed to a single client
+ */
+
+void ack_fail(uint16_t trans_id, gpointer ref)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_fail_gen(trans_id);
+
 	g_debug("Signalling failed operation");
-	net_send_single(ref, (void *) pkt, pkt_size);
+	net_send_single(ref, (void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/acks/ack_getpos_azel.c b/src/net/acks/ack_getpos_azel.c
index d823fa9f65ea196646502664c9aeadfa0caff5e8..10682b041e82a083e7cafa33b55f3cbc640783e8 100644
--- a/src/net/acks/ack_getpos_azel.c
+++ b/src/net/acks/ack_getpos_azel.c
@@ -20,14 +20,7 @@
 #include <net_common.h>
 
 
-
-/**
- * @brief acknowledge backend getpos_azel command
- *
- * @note the caller is responsible for freeing pos
- */
-
-void ack_getpos_azel(uint16_t trans_id, struct getpos *pos)
+struct packet *ack_getpos_azel_gen(uint16_t trans_id, struct getpos *pos)
 {
 	gsize pkt_size;
 
@@ -49,8 +42,25 @@ void ack_getpos_azel(uint16_t trans_id, struct getpos *pos)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+/**
+ * @brief acknowledge backend getpos_azel command
+ *
+ * @note the caller is responsible for freeing pos
+ */
+
+void ack_getpos_azel(uint16_t trans_id, struct getpos *pos)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_getpos_azel_gen(trans_id, pos);
+
 	g_debug("Sending AZEL");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	g_free(pkt);
 }
diff --git a/src/net/acks/ack_invalid_pkt.c b/src/net/acks/ack_invalid_pkt.c
index 9217bd98ca33c0ea57f1b45c201cbfd524b81d7d..39990d883f8e83c17a9d4264d1c90f874623e94e 100644
--- a/src/net/acks/ack_invalid_pkt.c
+++ b/src/net/acks/ack_invalid_pkt.c
@@ -19,7 +19,7 @@
 #include <ack.h>
 
 
-void ack_invalid_pkt(uint16_t trans_id)
+struct packet *ack_invalid_pkt_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,20 @@ void ack_invalid_pkt(uint16_t trans_id)
 
 	pkt_hdr_to_net_order(pkt);
 
+
+	return pkt;
+}
+
+
+void ack_invalid_pkt(uint16_t trans_id)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_invalid_pkt_gen(trans_id);
+
 	g_debug("Signalling invalid packet");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/acks/ack_moveto_azel.c b/src/net/acks/ack_moveto_azel.c
index de4e14b84a0f38cd74d6265f09e7b63042e6f3dc..ce1d779df021f06f42c451e7412543cbdafafa02 100644
--- a/src/net/acks/ack_moveto_azel.c
+++ b/src/net/acks/ack_moveto_azel.c
@@ -21,6 +21,12 @@
 #include <net_common.h>
 
 
+struct packet *ack_moveto_azel_gen(uint16_t trans_id, double az, double el)
+{
+	return cmd_moveto_azel_gen(trans_id, az, el);
+}
+
+
 
 /**
  * @brief acknowledge moveto_azel command
diff --git a/src/net/acks/ack_nopriv.c b/src/net/acks/ack_nopriv.c
index 0d012ecf1d387862191a7591a2e566762bfadbdc..758f64a922e67fae0fff0904aa0ebb79bd29a0d6 100644
--- a/src/net/acks/ack_nopriv.c
+++ b/src/net/acks/ack_nopriv.c
@@ -19,7 +19,7 @@
 #include <ack.h>
 
 
-void ack_nopriv(uint16_t trans_id, gpointer ref)
+struct packet *ack_nopriv_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,24 @@ void ack_nopriv(uint16_t trans_id, gpointer ref)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+/**
+ * @note this ack is always directed to a single client
+ */
+
+void ack_nopriv(uint16_t trans_id, gpointer ref)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_nopriv_gen(trans_id);
+
+
 	g_debug("Signalling lack of priviledge");
-	net_send_single(ref, (void *) pkt, pkt_size);
+	net_send_single(ref, (void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/acks/ack_spec_acq_cfg.c b/src/net/acks/ack_spec_acq_cfg.c
index d58aa17ad38930347053887573fc8b321c096634..2567cff5e369454ff5f7f681fe11de37ce2a2a4d 100644
--- a/src/net/acks/ack_spec_acq_cfg.c
+++ b/src/net/acks/ack_spec_acq_cfg.c
@@ -20,7 +20,7 @@
 #include <ack.h>
 
 
-void ack_spec_acq_cfg(uint16_t trans_id, struct spec_acq_cfg *acq)
+struct packet *ack_spec_acq_cfg_gen(uint16_t trans_id, struct spec_acq_cfg *acq)
 {
 	gsize pkt_size;
 
@@ -43,6 +43,17 @@ void ack_spec_acq_cfg(uint16_t trans_id, struct spec_acq_cfg *acq)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void ack_spec_acq_cfg(uint16_t trans_id, struct spec_acq_cfg *acq)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_spec_acq_cfg_gen(trans_id, acq);
+
 	g_debug("Sending current spectrometer configuration "
 		  "FREQ range: %g - %g MHz, BW div: %d, BIN div %d,"
 		  "STACK: %d, ACQ %d",
@@ -54,8 +65,7 @@ void ack_spec_acq_cfg(uint16_t trans_id, struct spec_acq_cfg *acq)
 		  acq->acq_max);
 
 
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	g_free(pkt);
 }
-
diff --git a/src/net/acks/ack_spec_acq_disable.c b/src/net/acks/ack_spec_acq_disable.c
index ec5b307298beae40fd2d65a73424e23c76aa7920..0c7cf70fa1c7b70f460d99eae1175e158ce2c950 100644
--- a/src/net/acks/ack_spec_acq_disable.c
+++ b/src/net/acks/ack_spec_acq_disable.c
@@ -21,11 +21,7 @@
 
 
 
-/**
- * @brief acknowledge backend spec_acq_disable command
- */
-
-void ack_spec_acq_disable(uint16_t trans_id)
+struct packet *ack_spec_acq_disable_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -45,8 +41,23 @@ void ack_spec_acq_disable(uint16_t trans_id)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+/**
+ * @brief acknowledge backend spec_acq_disable command
+ */
+
+void ack_spec_acq_disable(uint16_t trans_id)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_spec_acq_disable_gen(trans_id);
+
 	g_debug("Sending SPEC ACQ DISABLE");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	g_free(pkt);
 }
diff --git a/src/net/acks/ack_spec_acq_enable.c b/src/net/acks/ack_spec_acq_enable.c
index 251a7f541e78a2e5b6715dadbe1c654687243f5f..8c9039e2bcbb183ba8754c240544ef7c709ea8b8 100644
--- a/src/net/acks/ack_spec_acq_enable.c
+++ b/src/net/acks/ack_spec_acq_enable.c
@@ -20,12 +20,7 @@
 #include <net_common.h>
 
 
-
-/**
- * @brief acknowledge backend spec_acq_enable command
- */
-
-void ack_spec_acq_enable(uint16_t trans_id)
+struct packet *ack_spec_acq_enable_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -45,8 +40,23 @@ void ack_spec_acq_enable(uint16_t trans_id)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+/**
+ * @brief acknowledge backend spec_acq_enable command
+ */
+
+void ack_spec_acq_enable(uint16_t trans_id)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_spec_acq_enable_gen(trans_id);
+
 	g_debug("Sending SPEC ACQ ENABLE");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	g_free(pkt);
 }
diff --git a/src/net/acks/ack_spec_data.c b/src/net/acks/ack_spec_data.c
index 5e0fda4dc788318e9275ed321d0692d2b943ee4a..3a5a74cc235fcf1d9b657352d80e9ddf6b7a231b 100644
--- a/src/net/acks/ack_spec_data.c
+++ b/src/net/acks/ack_spec_data.c
@@ -20,13 +20,8 @@
 #include <ack.h>
 
 
-/**
- * @brief send spectral data
- *
- * @note the caller must take care to clean the spectral data supplied
- */
 
-void ack_spec_data(uint16_t trans_id, struct spec_data *s)
+struct packet *ack_spec_data_gen(uint16_t trans_id, struct spec_data *s)
 {
 	gsize pkt_size;
 	gsize data_size;
@@ -51,9 +46,27 @@ void ack_spec_data(uint16_t trans_id, struct spec_data *s)
 
 	pkt_hdr_to_net_order(pkt);
 
-	g_debug("Transmitting spectral data");
 
-	net_send((void *) pkt, pkt_size);
+	return pkt;
+}
+
+
+/**
+ * @brief send spectral data
+ *
+ * @note the caller must take care to clean the spectral data supplied
+ */
+
+void ack_spec_data(uint16_t trans_id, struct spec_data *s)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_spec_data_gen(trans_id, s);
+
+
+	g_debug("Transmitting spectral data");
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up packet */
 	g_free(pkt);
diff --git a/src/net/acks/ack_status_acq.c b/src/net/acks/ack_status_acq.c
index 06e48d14abdfc051bff15a707fff43c2dd30de95..07d85ad75b406fc9b135d61379f94f99961ffe77 100644
--- a/src/net/acks/ack_status_acq.c
+++ b/src/net/acks/ack_status_acq.c
@@ -21,11 +21,7 @@
 
 
 
-/**
- * @brief acknowledge acquisition status
- */
-
-void ack_status_acq(uint16_t trans_id, struct status *c)
+struct packet *ack_status_acq_gen(uint16_t trans_id, struct status *c)
 {
 	gsize pkt_size;
 
@@ -48,8 +44,25 @@ void ack_status_acq(uint16_t trans_id, struct status *c)
 
 	pkt_hdr_to_net_order(pkt);
 
+
+	return pkt;
+}
+
+
+
+/**
+ * @brief acknowledge acquisition status
+ */
+
+void ack_status_acq(uint16_t trans_id, struct status *c)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_status_acq_gen(trans_id, c);
+
 	g_debug("Sending ACQ status");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/acks/ack_status_move.c b/src/net/acks/ack_status_move.c
index 58fb4f693329601d958cb0e3788a66fd9c7e4793..235371f9453a5277b33b99d65e8d9e38fc2aa815 100644
--- a/src/net/acks/ack_status_move.c
+++ b/src/net/acks/ack_status_move.c
@@ -21,11 +21,7 @@
 
 
 
-/**
- * @brief acknowledge move-to-target status
- */
-
-void ack_status_move(uint16_t trans_id, struct status *c)
+struct packet *ack_status_move_gen(uint16_t trans_id, struct status *c)
 {
 	gsize pkt_size;
 
@@ -48,8 +44,24 @@ void ack_status_move(uint16_t trans_id, struct status *c)
 
 	pkt_hdr_to_net_order(pkt);
 
+
+	return pkt;
+}
+
+
+/**
+ * @brief acknowledge move-to-target status
+ */
+
+void ack_status_move(uint16_t trans_id, struct status *c)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_status_move_gen(trans_id, c);
+
 	g_debug("Sending MOVE status");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/acks/ack_status_rec.c b/src/net/acks/ack_status_rec.c
index 774f36655abf95a7469f42f80dcac1a5fe15076c..88235dd2246e3ca7a05051804f0b1d8670ffabfc 100644
--- a/src/net/acks/ack_status_rec.c
+++ b/src/net/acks/ack_status_rec.c
@@ -21,11 +21,7 @@
 
 
 
-/**
- * @brief acknowledge recording status
- */
-
-void ack_status_rec(uint16_t trans_id, struct status *c)
+struct packet *ack_status_rec_gen(uint16_t trans_id, struct status *c)
 {
 	gsize pkt_size;
 
@@ -48,8 +44,24 @@ void ack_status_rec(uint16_t trans_id, struct status *c)
 
 	pkt_hdr_to_net_order(pkt);
 
+
+	return pkt;
+}
+
+
+/**
+ * @brief acknowledge recording status
+ */
+
+void ack_status_rec(uint16_t trans_id, struct status *c)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_status_rec_gen(trans_id, c);
+
 	g_debug("Sending REC status");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/acks/ack_status_slew.c b/src/net/acks/ack_status_slew.c
index ad9b497e228c5cf861dc84016f7577c757fd70d9..cfe87ea58bb2341f23e397be2af47164207771f8 100644
--- a/src/net/acks/ack_status_slew.c
+++ b/src/net/acks/ack_status_slew.c
@@ -20,12 +20,7 @@
 #include <net_common.h>
 
 
-
-/**
- * @brief acknowledge slew status
- */
-
-void ack_status_slew(uint16_t trans_id, struct status *c)
+struct packet *ack_status_slew_get(uint16_t trans_id, struct status *c)
 {
 	gsize pkt_size;
 
@@ -48,8 +43,24 @@ void ack_status_slew(uint16_t trans_id, struct status *c)
 
 	pkt_hdr_to_net_order(pkt);
 
+
+	return pkt;
+}
+
+
+/**
+ * @brief acknowledge slew status
+ */
+
+void ack_status_slew(uint16_t trans_id, struct status *c)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_status_slew_get(trans_id, c);
+
 	g_debug("Sending SLEW status");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/acks/ack_success.c b/src/net/acks/ack_success.c
index 6bc237c42173d440df298b8d6c91bf12a333a39a..7cf87408efec06692311fc94c376d966995291f1 100644
--- a/src/net/acks/ack_success.c
+++ b/src/net/acks/ack_success.c
@@ -19,7 +19,7 @@
 #include <ack.h>
 
 
-void ack_success(uint16_t trans_id, gpointer ref)
+struct packet *ack_success_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,24 @@ void ack_success(uint16_t trans_id, gpointer ref)
 
 	pkt_hdr_to_net_order(pkt);
 
+
+	return pkt;
+}
+
+
+/**
+ * @note this ack is always directed to a single client
+ */
+
+void ack_success(uint16_t trans_id, gpointer ref)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_success_gen(trans_id);
+
 	g_debug("Signalling successful operation");
-	net_send((void *) pkt, pkt_size);
+	net_send_single(ref, (void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/acks/ack_userlist.c b/src/net/acks/ack_userlist.c
index ff549505f428e9308178e3303f678b339b278542..4faca4e4326a342583239335a2cf76a69d484327 100644
--- a/src/net/acks/ack_userlist.c
+++ b/src/net/acks/ack_userlist.c
@@ -20,7 +20,8 @@
 #include <protocol.h>
 
 
-void ack_userlist(uint16_t trans_id, const uint8_t *userlist, uint16_t len)
+struct packet *ack_userlist_gen(uint16_t trans_id, const uint8_t *userlist,
+				uint16_t len)
 {
 	gsize pkt_size;
 	gsize data_size;
@@ -30,7 +31,7 @@ void ack_userlist(uint16_t trans_id, const uint8_t *userlist, uint16_t len)
 
 
 	if (len != strlen(userlist))
-	       	return;
+	       	return NULL;
 
 	/* all strings terminate with \0 char, we transport that as well! */
 	data_size = sizeof(struct userlist) + (len + 1) * sizeof(uint8_t);
@@ -52,9 +53,22 @@ void ack_userlist(uint16_t trans_id, const uint8_t *userlist, uint16_t len)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void ack_userlist(uint16_t trans_id, const uint8_t *userlist, uint16_t len)
+{
+	struct packet *pkt;
+
+
+	pkt = ack_userlist_gen(trans_id, userlist, len);
+	if (!pkt)
+		return;
+
 	g_debug("Sending userlist: %s", userlist);
 
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/cmds/cmd_capabilities.c b/src/net/cmds/cmd_capabilities.c
index 945f6bba0c758225a87b9a9179afceff3da3bdbe..b3f37352de16921a486d2a2d4b7501c998d11b2c 100644
--- a/src/net/cmds/cmd_capabilities.c
+++ b/src/net/cmds/cmd_capabilities.c
@@ -19,7 +19,7 @@
 #include <cmd.h>
 
 
-void cmd_capabilities(uint16_t trans_id)
+struct packet *cmd_capabilities_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,19 @@ void cmd_capabilities(uint16_t trans_id)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void cmd_capabilities(uint16_t trans_id)
+{
+	struct packet *pkt;
+
+
+	pkt = cmd_capabilities_gen(trans_id);
+
 	g_debug("Requesting capabilities");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/cmds/cmd_control.c b/src/net/cmds/cmd_control.c
index 5cb473fe9df8e29ea92d61fb83dbc9942488567f..4f58f481f21c68c9937e2bbd75ddc22de7edc728 100644
--- a/src/net/cmds/cmd_control.c
+++ b/src/net/cmds/cmd_control.c
@@ -19,7 +19,8 @@
 #include <cmd.h>
 
 
-void cmd_control(uint16_t trans_id, const uint8_t *digest, uint16_t len)
+struct packet *cmd_control_gen(uint16_t trans_id, const uint8_t *digest,
+			       uint16_t len)
 {
 	gsize pkt_size;
 	gsize data_size;
@@ -29,7 +30,7 @@ void cmd_control(uint16_t trans_id, const uint8_t *digest, uint16_t len)
 
 
 	if (len != strlen(digest))
-	       	return;
+	       	return NULL;
 
 	/* all strings terminate with \0 char, we transport that as well! */
 	data_size = sizeof(struct control) + (len + 1) * sizeof(uint8_t);
@@ -51,9 +52,23 @@ void cmd_control(uint16_t trans_id, const uint8_t *digest, uint16_t len)
 
 	pkt_hdr_to_net_order(pkt);
 
+
+	return pkt;
+}
+
+
+void cmd_control(uint16_t trans_id, const uint8_t *digest, uint16_t len)
+{
+	struct packet *pkt;
+
+
+	pkt = cmd_control_gen(trans_id, digest, len);
+	if (!pkt)
+		return;
+
 	g_debug("Requesting telescope control");
 
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/cmds/cmd_fail.c b/src/net/cmds/cmd_fail.c
index 3d2f807b580bb263ff145ea56deca181ad639882..3eed38d8ce6a148b9a64ccd272472fa5df338e34 100644
--- a/src/net/cmds/cmd_fail.c
+++ b/src/net/cmds/cmd_fail.c
@@ -19,7 +19,7 @@
 #include <cmd.h>
 
 
-void cmd_fail(uint16_t trans_id)
+struct packet *cmd_fail_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,17 @@ void cmd_fail(uint16_t trans_id)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void cmd_fail(uint16_t trans_id)
+{
+	struct packet *pkt;
+
+
 	g_debug("Signalling failed command");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/cmds/cmd_getpos_azel.c b/src/net/cmds/cmd_getpos_azel.c
index 524d86321955df9012a1d97083ba7417c06e022c..85f5640e7c0102d8eb1b5b08e168bebad335662a 100644
--- a/src/net/cmds/cmd_getpos_azel.c
+++ b/src/net/cmds/cmd_getpos_azel.c
@@ -19,7 +19,7 @@
 #include <cmd.h>
 
 
-void cmd_getpos_azel(uint16_t trans_id)
+struct packet *cmd_getpos_azel_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,18 @@ void cmd_getpos_azel(uint16_t trans_id)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void cmd_getpos_azel(uint16_t trans_id)
+{
+	struct packet *pkt;
+
+	pkt = cmd_getpos_azel_gen(trans_id);
+
 	g_debug("Requesting telescope AZEL");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/cmds/cmd_invalid_pkt.c b/src/net/cmds/cmd_invalid_pkt.c
index 1d7a5f88a63c3145c523e1f35e7a9c3c1471cefa..4b412c21e441697b083275fbc52bba0643d372b2 100644
--- a/src/net/cmds/cmd_invalid_pkt.c
+++ b/src/net/cmds/cmd_invalid_pkt.c
@@ -19,7 +19,7 @@
 #include <cmd.h>
 
 
-void cmd_invalid_pkt(uint16_t trans_id)
+struct packet *cmd_invalid_pkt_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,19 @@ void cmd_invalid_pkt(uint16_t trans_id)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void cmd_invalid_pkt(uint16_t trans_id)
+{
+	struct packet *pkt;
+
+
+	pkt = cmd_invalid_pkt_gen(trans_id);
+
 	g_debug("Signalling invalid packet");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/cmds/cmd_message.c b/src/net/cmds/cmd_message.c
index 60f4aa2bca2d5492d89832c55b60996b37654c09..1c2041b2c99c29af69bac86ac7c44224cec20497 100644
--- a/src/net/cmds/cmd_message.c
+++ b/src/net/cmds/cmd_message.c
@@ -20,7 +20,8 @@
 #include <protocol.h>
 
 
-void cmd_message(uint16_t trans_id, const uint8_t *message, uint16_t len)
+struct packet *cmd_message_gen(uint16_t trans_id, const uint8_t *message,
+			       uint16_t len)
 {
 	gsize pkt_size;
 	gsize data_size;
@@ -30,7 +31,7 @@ void cmd_message(uint16_t trans_id, const uint8_t *message, uint16_t len)
 
 
 	if (len != strlen(message))
-	       	return;
+	       	return NULL;
 
 	/* all strings terminate with \0 char, we transport that as well! */
 	data_size = sizeof(struct message) + (len + 1) * sizeof(uint8_t);
@@ -52,9 +53,23 @@ void cmd_message(uint16_t trans_id, const uint8_t *message, uint16_t len)
 
 	pkt_hdr_to_net_order(pkt);
 
+
+	return pkt;
+}
+
+
+void cmd_message(uint16_t trans_id, const uint8_t *message, uint16_t len)
+{
+	struct packet *pkt;
+
+
+	pkt = cmd_message_gen(trans_id, message, len);
+	if (!pkt)
+		return;
+
 	g_debug("Sending text message: %s", message);
 
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/cmds/cmd_moveto_azel.c b/src/net/cmds/cmd_moveto_azel.c
index 8d25ab89caea90984b8c3adf4c7adb371f55a1de..7af900798403fc06628c2495f2a27a04d6a0b0da 100644
--- a/src/net/cmds/cmd_moveto_azel.c
+++ b/src/net/cmds/cmd_moveto_azel.c
@@ -19,7 +19,7 @@
 #include <cmd.h>
 
 
-void cmd_moveto_azel(uint16_t trans_id, double az, double el)
+struct packet *cmd_moveto_azel_gen(uint16_t trans_id, double az, double el)
 {
 	gsize pkt_size;
 
@@ -49,10 +49,20 @@ void cmd_moveto_azel(uint16_t trans_id, double az, double el)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void cmd_moveto_azel(uint16_t trans_id, double az, double el)
+{
+	struct packet *pkt;
+
+
+	pkt = cmd_moveto_azel_gen(trans_id, az, el);
+
 	g_debug("Sending command moveto AZ/EL %g/%g", az, el);
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
 }
-
diff --git a/src/net/cmds/cmd_nick.c b/src/net/cmds/cmd_nick.c
index 93a13cfd6b22042977221f762cd4119ad5465a91..9ebd1ac8bb6ee0482786f6231b6dd8697078bb9e 100644
--- a/src/net/cmds/cmd_nick.c
+++ b/src/net/cmds/cmd_nick.c
@@ -20,7 +20,8 @@
 #include <protocol.h>
 
 
-void cmd_nick(uint16_t trans_id, const uint8_t *nick, uint16_t len)
+struct packet *cmd_nick_gen(uint16_t trans_id, const uint8_t *nick,
+			    uint16_t len)
 {
 	gsize pkt_size;
 	gsize data_size;
@@ -30,7 +31,7 @@ void cmd_nick(uint16_t trans_id, const uint8_t *nick, uint16_t len)
 
 
 	if (len != strlen(nick))
-	       	return;
+	       	return NULL;
 
 	/* all strings terminate with \0 char, we transport that as well! */
 	data_size = sizeof(struct nick) + (len + 1) * sizeof(uint8_t);
@@ -52,9 +53,22 @@ void cmd_nick(uint16_t trans_id, const uint8_t *nick, uint16_t len)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void cmd_nick(uint16_t trans_id, const uint8_t *nick, uint16_t len)
+{
+	struct packet *pkt;
+
+
+	pkt = cmd_nick_gen(trans_id, nick, len);
+	if (!pkt)
+		return;
+
 	g_debug("Sending new nick: %s", nick);
 
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/cmds/cmd_park_telescope.c b/src/net/cmds/cmd_park_telescope.c
index f29bfbb460c948abdc10fb76d17b6018e5a6bbee..eee398aa314f3eacd3284caa5762686fa2988fc4 100644
--- a/src/net/cmds/cmd_park_telescope.c
+++ b/src/net/cmds/cmd_park_telescope.c
@@ -19,7 +19,7 @@
 #include <cmd.h>
 
 
-void cmd_park_telescope(uint16_t trans_id)
+struct packet *cmd_park_telescope_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,19 @@ void cmd_park_telescope(uint16_t trans_id)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void cmd_park_telescope(uint16_t trans_id)
+{
+	struct packet *pkt;
+
+
+	pkt = cmd_park_telescope_gen(trans_id);
+
 	g_debug("Requesting park_telescope");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/cmds/cmd_recalibrate_pointing.c b/src/net/cmds/cmd_recalibrate_pointing.c
index 5f2fc139f90a67257d3c3a3a76a28c7bdf555d27..5cb01a24fc2830269b056706b92b9c42cd16b04d 100644
--- a/src/net/cmds/cmd_recalibrate_pointing.c
+++ b/src/net/cmds/cmd_recalibrate_pointing.c
@@ -19,7 +19,7 @@
 #include <cmd.h>
 
 
-void cmd_recalibrate_pointing(uint16_t trans_id)
+struct packet *cmd_recalibrate_pointing_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,19 @@ void cmd_recalibrate_pointing(uint16_t trans_id)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void cmd_recalibrate_pointing(uint16_t trans_id)
+{
+	struct packet *pkt;
+
+
+	pkt = cmd_recalibrate_pointing_gen(trans_id);
+
 	g_debug("Requesting recalibrate_pointing");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/cmds/cmd_spec_acq_cfg.c b/src/net/cmds/cmd_spec_acq_cfg.c
index 57ae9a5abe50aaf57437d1abc269207103af8e69..63b42ca6ff23576b345556d4033d4e7c3be6561b 100644
--- a/src/net/cmds/cmd_spec_acq_cfg.c
+++ b/src/net/cmds/cmd_spec_acq_cfg.c
@@ -31,9 +31,10 @@
  *
  */
 
-void cmd_spec_acq_cfg(uint16_t trans_id,
-		      uint64_t f0, uint64_t f1, uint32_t bw_div,
-		      uint32_t bin_div, uint32_t n_stack, uint32_t acq_max)
+struct packet *cmd_spec_acq_cfg_gen(uint16_t trans_id,
+				    uint64_t f0, uint64_t f1, uint32_t bw_div,
+				    uint32_t bin_div, uint32_t n_stack,
+				    uint32_t acq_max)
 {
 	gsize pkt_size;
 
@@ -66,6 +67,22 @@ void cmd_spec_acq_cfg(uint16_t trans_id,
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void cmd_spec_acq_cfg(uint16_t trans_id,
+		      uint64_t f0, uint64_t f1, uint32_t bw_div,
+		      uint32_t bin_div, uint32_t n_stack, uint32_t acq_max)
+{
+	struct packet *pkt;
+	struct spec_acq_cfg *acq;
+
+	pkt = cmd_spec_acq_cfg_gen(trans_id, f0, f1, bw_div,
+				   bin_div, n_stack, acq_max);
+
+	acq = (struct spec_acq_cfg *) pkt->data;
+
 	g_debug("Sending command acquire spectrum "
 		  "FREQ range: %g - %g MHz, BW div: %d, BIN div %d,"
 		  "STACK: %d, ACQ %d",
@@ -77,9 +94,8 @@ void cmd_spec_acq_cfg(uint16_t trans_id,
 		  acq->acq_max);
 
 
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
 }
-
diff --git a/src/net/cmds/cmd_spec_acq_cfg_get.c b/src/net/cmds/cmd_spec_acq_cfg_get.c
index 3088670a95c21cff4055a2059e1ada9a7ea17428..c697eeba735acb25882386446f237c723161c60e 100644
--- a/src/net/cmds/cmd_spec_acq_cfg_get.c
+++ b/src/net/cmds/cmd_spec_acq_cfg_get.c
@@ -19,7 +19,7 @@
 #include <cmd.h>
 
 
-void cmd_spec_acq_cfg_get(uint16_t trans_id)
+struct packet *cmd_spec_acq_cfg_get_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,19 @@ void cmd_spec_acq_cfg_get(uint16_t trans_id)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void cmd_spec_acq_cfg_get(uint16_t trans_id)
+{
+	struct packet *pkt;
+
+
+	pkt = cmd_spec_acq_cfg_get_gen(trans_id);
+
 	g_debug("Requesting spectral acquisition configuration");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/cmds/cmd_spec_acq_disable.c b/src/net/cmds/cmd_spec_acq_disable.c
index 684b7a2ff671fdbfab8fcf9b39fe8d4f6aa19b0f..036ded26afbad5d98f4f99d71756222c5337a688 100644
--- a/src/net/cmds/cmd_spec_acq_disable.c
+++ b/src/net/cmds/cmd_spec_acq_disable.c
@@ -19,7 +19,7 @@
 #include <cmd.h>
 
 
-void cmd_spec_acq_disable(uint16_t trans_id)
+struct packet *cmd_spec_acq_disable_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,20 @@ void cmd_spec_acq_disable(uint16_t trans_id)
 
 	pkt_hdr_to_net_order(pkt);
 
+
+	return pkt;
+}
+
+
+void cmd_spec_acq_disable(uint16_t trans_id)
+{
+	struct packet *pkt;
+
+
+	pkt = cmd_spec_acq_disable_gen(trans_id);
+
 	g_debug("Requesting disable of spectral acquisition");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/cmds/cmd_spec_acq_enable.c b/src/net/cmds/cmd_spec_acq_enable.c
index 5371cbccb2a6ed6ce9f0c6a709d04bd2a15c58e7..8b65bafd36683efd19b81fc0e5ba7b81ed7eb0db 100644
--- a/src/net/cmds/cmd_spec_acq_enable.c
+++ b/src/net/cmds/cmd_spec_acq_enable.c
@@ -19,7 +19,7 @@
 #include <cmd.h>
 
 
-void cmd_spec_acq_enable(uint16_t trans_id)
+struct packet *cmd_spec_acq_enable_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,20 @@ void cmd_spec_acq_enable(uint16_t trans_id)
 
 	pkt_hdr_to_net_order(pkt);
 
+
+	return pkt;
+}
+
+
+void cmd_spec_acq_enable(uint16_t trans_id)
+{
+	struct packet *pkt;
+
+
+	pkt = cmd_spec_acq_enable_gen(trans_id);
+
 	g_debug("Requesting enable of spectral acquisition");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/cmds/cmd_success.c b/src/net/cmds/cmd_success.c
index f5d5d403389b1b506cf6cdaf5bda3155e0d2ce49..e6aac0fbdea2e689e6cef4ff2860ed1eecbaffe0 100644
--- a/src/net/cmds/cmd_success.c
+++ b/src/net/cmds/cmd_success.c
@@ -19,7 +19,7 @@
 #include <cmd.h>
 
 
-void cmd_success(uint16_t trans_id)
+struct packet *cmd_success_gen(uint16_t trans_id)
 {
 	gsize pkt_size;
 
@@ -38,8 +38,19 @@ void cmd_success(uint16_t trans_id)
 
 	pkt_hdr_to_net_order(pkt);
 
+	return pkt;
+}
+
+
+void cmd_success(uint16_t trans_id)
+{
+	struct packet *pkt;
+
+
+	pkt = cmd_success_gen(trans_id);
+
 	g_debug("Signalling successful command");
-	net_send((void *) pkt, pkt_size);
+	net_send((void *) pkt, pkt_size_get(pkt));
 
 	/* clean up */
 	g_free(pkt);
diff --git a/src/net/protocol.c b/src/net/protocol.c
index bf1e24119967bca42b31ca29fd7d98539e633265..dcfdb0ff0bbf1148ada376e00a0823e05dd43c83 100644
--- a/src/net/protocol.c
+++ b/src/net/protocol.c
@@ -19,6 +19,21 @@
 #include <glib.h>
 #include <protocol.h>
 
+
+
+/**
+ * @brief get the total size of a packet in bytes
+ */
+
+size_t pkt_size_get(struct packet *pkt)
+{
+	if (!pkt)
+		return 0;
+
+	return sizeof(struct packet) + g_htonl(pkt->data_size);
+}
+
+
 /**
  * @brief convert packet header to network byte order
  */
@@ -78,7 +93,7 @@ uint16_t CRC16(unsigned char *buf, size_t size)
 
 			if ((b & 0x80) ^ ((S & 0x8000) >> 8))
 				S = ((S << 1) ^ 0x1021) & 0xFFFF;
-			else 
+			else
 				S = (S << 1) & 0xFFFF;
 
 			b = b << 1;
diff --git a/src/server/cfg.c b/src/server/cfg.c
index c457a83cd6edff89de1c7c9a22db3e9eb292c883..4fa6cf19521f05df46d867e73e31936b73bd6aaa 100644
--- a/src/server/cfg.c
+++ b/src/server/cfg.c
@@ -32,6 +32,8 @@ static void server_cfg_load_network(GKeyFile *kf, struct server_settings *s)
 
 
 	s->port = g_key_file_get_integer(kf, grp, "port", NULL);
+
+	s->masterkey = g_key_file_get_string(kf, grp, "masterkey", NULL);
 }
 
 
@@ -79,6 +81,17 @@ static void server_cfg_load_location(GKeyFile *kf, struct server_settings *s)
 	s->n_hor = len_az;
 }
 
+/**
+ * @brief load configuration keys in the message of the day group
+ */
+
+static void server_cfg_load_motd(GKeyFile *kf, struct server_settings *s)
+{
+	const char *grp = "MOTD";
+
+
+	s->motd = g_key_file_get_string(kf, grp, "motd", NULL);
+}
 
 
 /**
@@ -170,6 +183,42 @@ gsize server_cfg_get_hor_limits(gint32 **hor_az, gint32 **hor_el)
 }
 
 
+/**
+ * @brief get the message of the day
+ *
+ * @returns a copy of the motd, cleanup using g_free()
+ *
+ */
+
+gchar *server_cfg_get_motd(void)
+{
+	return g_strdup(server_cfg->motd);
+}
+
+/**
+ * @brief update the message of the day at run time
+ *
+ * @note does not update the configuration file
+ */
+
+void server_cfg_set_motd(const gchar *motd)
+{
+	g_free(server_cfg->motd);
+
+	server_cfg->motd = g_strdup(motd);
+}
+
+
+/**
+ * @brief get the server masterkey
+ */
+
+const gchar *server_cfg_get_masterkey(void)
+{
+	return server_cfg->masterkey;
+}
+
+
 /**
  * @brief load the server configuration file from a given prefix
  *
@@ -211,6 +260,7 @@ static int server_load_config_from_prefix(const gchar *prefix, GError **err)
 	server_cfg_load_network(kf, server_cfg);
 	server_cfg_load_backend(kf, server_cfg);
 	server_cfg_load_location(kf, server_cfg);
+	server_cfg_load_motd(kf, server_cfg);
 
 	g_key_file_free(kf);
 	g_free(cfg);
diff --git a/src/server/config/server.cfg b/src/server/config/server.cfg
index fc358c8b83a27ddd0a600893c0e247d4706c47fa..c04c7088fae84120a2bbb237bd7a17d734e5c544 100644
--- a/src/server/config/server.cfg
+++ b/src/server/config/server.cfg
@@ -1,16 +1,22 @@
+[MOTD]
+motd = \t\thi / good luck and have fun
+ 
 [Network]
-port=1420
-#masterpasswd= unimplemented sha512hash (or somesuch)
+port = 1420
+# a SHA256 hash digest for maximum privilege level
+masterkey = b2e17e7c7599dd9e6c4517b294c3dbe3aef0dc5ac8193eb59e33f53f15facdd0
 
 [Backend]
-#uncommecnt for Vienna SRT hardware
+# uncomment for Vienna SRT hardware
 #plugins=SRT/srt_comlink;SRT/srt_drive;SRT/srt_spectrometer;
-plugins=SIM/rt_sim
+plugins = SIM/rt_sim
+
 [Location]
-station=Vienna SRT
-lat=48.23
-# XXX: east = positive
-lon=-16.34
+station = RT Simulator
+#station = Vienna University Observatory SRT
+lat = 48.23
+# east = negative
+lon = -16.34
 # XXX: implement, check
 alt=245.
 
diff --git a/src/server/include/cfg.h b/src/server/include/cfg.h
index 8a237c373643f2346c1e1ce74d26b9a37cfe8fc3..9d3449f6e5c93b4da402651ad10622bcdd8744ab 100644
--- a/src/server/include/cfg.h
+++ b/src/server/include/cfg.h
@@ -27,7 +27,9 @@ struct server_settings {
 	gdouble   lon;		/* station longitude */
 	gint32   *hor_az;	/* horizon profile azimuth values */
 	gint32   *hor_el;	/* horizon profile elevaltion values */
-	gsize     n_hor;		/* number of profile values */
+	gsize     n_hor;	/* number of profile values */
+	gchar    *motd;		/* a message of the day */
+	gchar    *masterkey;	/* guess */
 };
 
 
@@ -44,6 +46,11 @@ gsize server_cfg_get_hor_limits(int **hor_az, int **hor_el);
 
 int server_cfg_load(void);
 
+gchar *server_cfg_get_motd(void);
+void server_cfg_set_motd(const gchar *motd);
+
+const gchar *server_cfg_get_masterkey(void);
+
 
 
 #endif /* _SERVER_INCLUDE_CFG_H_ */
diff --git a/src/server/include/net.h b/src/server/include/net.h
index 3c8d0df632ff6b66e9714f5a9627864b50b9d396..afce07d32c9eb55f4b6509fd0a4066d2137b6607 100644
--- a/src/server/include/net.h
+++ b/src/server/include/net.h
@@ -23,7 +23,10 @@
 
 int net_server(void);
 void net_server_reassign_control(gpointer ref);
+void net_server_drop_priv(gpointer ref);
+void net_server_iddqd(gpointer ref);
 void net_server_broadcast_message(const gchar *msg, gpointer ref);
+void net_server_direct_message(const gchar *msg, gpointer ref);
 void net_server_set_nickname(const gchar *nick, gpointer ref);
 
 
diff --git a/src/server/net.c b/src/server/net.c
index e215d797d6ab0522de936c8026c9882f2a90a9b9..6d28d43aff1b652916523de0b19c4766f86e4152 100644
--- a/src/server/net.c
+++ b/src/server/net.c
@@ -38,13 +38,19 @@
 /* max allowed client */
 #define SERVER_CON_MAX 64
 
+/* privilege range */
+#define PRIV_DEFAULT	0
+#define PRIV_CONTROL	1
+#define PRIV_FULL	2
+
+
 
 /* client connection data */
 struct con_data {
 	GSocketConnection *con;
 	GInputStream *istream;
 	gsize nbytes;
-	gboolean priv;
+	gint priv;
 	gchar *nick;
 	gboolean new;
 	gboolean kick;
@@ -97,6 +103,78 @@ static gchar *net_get_host_string(GSocketConnection *con)
 }
 
 
+/**
+ * @brief generate a chat message string
+ *
+ * @param msg the message
+ * @param c the connection (may be NULL)
+ *
+ * @returns an allocated buffer holding the string, clean using g_free()
+ *
+ * @note if c is NULL, it is assumed the server generated the message
+ */
+
+static gchar *net_server_msg_nick(const gchar *msg, struct con_data *c)
+{
+	gchar *buf;
+	gchar *nick;
+	gchar *col;
+
+
+	col  = "#FF0000";
+	nick = "A hollow voice says";
+
+	if (c) {
+		col  = "#7F9F7F";
+		nick = c->nick;
+	}
+
+	buf = g_strdup_printf("<tt><span foreground='%s'>"
+			      "%s:</span></tt> %s\n",
+			      col, nick, msg);
+
+
+	return buf;
+}
+
+static gboolean net_push_station_single(gpointer data)
+{
+	gchar *buf;
+
+	buf = g_strdup_printf("Your are connected to %s\n",
+			      server_cfg_get_station());
+
+	net_server_direct_message(buf, data);
+
+	g_free(buf);
+
+	return G_SOURCE_REMOVE;
+}
+
+
+static gboolean net_push_motd_single(gpointer data)
+{
+	gchar *buf;
+	gchar *motd;
+
+
+	motd = server_cfg_get_motd();
+	if (!motd)
+		goto exit;
+
+
+	buf = g_strdup_printf("The MOTD is: \n\n%s\n\n", motd);
+
+	net_server_direct_message(buf, data);
+
+	g_free(buf);
+	g_free(motd);
+
+exit:
+	return G_SOURCE_REMOVE;
+}
+
+
 /**
  * @brief distribute a list of users to all clients
  */
@@ -127,13 +205,21 @@ static gboolean net_push_userlist_cb(gpointer data)
 
 		tmp = msg;
 
-		if (c->priv)
+		g_message("%s priv is %d", c->nick, c->priv);
+		switch (c->priv) {
+		case PRIV_FULL:
 			buf = g_strdup_printf("<tt><span foreground='#FF0000'>"
 					      "%s</span></tt>\n", c->nick);
-		else
+			break;
+		case PRIV_CONTROL:
+			buf = g_strdup_printf("<tt><span foreground='#FFFF00'>"
+					      "%s</span></tt>\n", c->nick);
+			break;
+		default:
 			buf = g_strdup_printf("<tt><span foreground='#7F9F7F'>"
 					      "%s</span></tt>\n", c->nick);
-
+			break;
+		}
 		msg = g_strconcat(buf, tmp, NULL);
 
 		g_free(buf);
@@ -143,8 +229,8 @@ static gboolean net_push_userlist_cb(gpointer data)
 			c->new = FALSE;
 
 			msgs[msgcnt++] = g_strdup_printf("<tt><span foreground='#F1C40F'>"
-					"%s</span></tt> joined",
-					c->nick);
+							 "%s</span></tt> joined",
+							 c->nick);
 
 			g_print("%s joined\n", c->nick);
 
@@ -170,6 +256,7 @@ static gboolean net_push_userlist_cb(gpointer data)
 }
 
 
+
 /**
  * @brief if connected, disconnect the socket
  */
@@ -377,6 +464,10 @@ static gboolean net_send_internal(struct con_data *c, const char *pkt, gsize nby
 	if (c->kick)
 		return FALSE;
 
+	if (!G_IS_SOCKET_CONNECTION(c->con)) {
+		g_warning("%s:%d: supplied argument is not a socket connection",
+			  __func__, __LINE__);
+	}
 
 	if (g_thread_pool_get_num_threads(c->pool) >= SERVER_CON_POOL_SIZE) {
 
@@ -526,7 +617,7 @@ pending:
 
 	/* verify packet payload */
 	if (CRC16((guchar *) pkt->data, pkt->data_size) == pkt->data_crc16)  {
-		if (process_pkt(pkt, c->priv, c))
+		if (process_pkt(pkt, (gboolean) c->priv, c))
 			goto drop_pkt;
 
 		/* valid packets were free'd */
@@ -607,7 +698,7 @@ error:
 
 static void assign_default_priv(struct con_data *c)
 {
-	gboolean priv = FALSE;
+	gint priv = PRIV_DEFAULT;
 
 	GList *elem;
 
@@ -621,11 +712,11 @@ static void assign_default_priv(struct con_data *c)
 		item = (struct con_data *) elem->data;
 
 		if (item->priv)
-			priv = TRUE;
+			priv = PRIV_CONTROL;
 	}
 
-	if (!priv)
-		c->priv = TRUE;
+	if (priv == PRIV_DEFAULT)
+		c->priv = PRIV_CONTROL;
 
 	g_mutex_unlock(&listlock);
 }
@@ -717,11 +808,12 @@ static gboolean net_incoming(GSocketService    *service,
 	con_list = g_list_append(con_list, c);
 	g_mutex_unlock(&listlock);
 
-	/* push new username after 1 seconds, so they have time to configure
-	 * theirs
+	/* push usernames and messages after 1 seconds, so the incoming
+	 * connections have time to configure theirs
 	 */
 	g_timeout_add_seconds(1, net_push_userlist_cb, NULL);
-
+	g_timeout_add_seconds(1, net_push_station_single, c);
+	g_timeout_add_seconds(1, net_push_motd_single, c);
 
 	str = net_get_host_string(c->con);
 	g_message("Received connection from %s", str);
@@ -803,35 +895,64 @@ gint net_send(const char *pkt, gsize nbytes)
 	return ret;
 }
 
-
 /**
  * @brief assign control privilege level to connection
  */
 
-void net_server_reassign_control(gpointer ref)
+
+static void net_server_reassign_control_internal(gpointer ref, gint lvl)
 {
 	GList *elem;
 
 	struct con_data *c;
 	struct con_data *item;
 
+	struct con_data *p = NULL;
+
 	gchar *msg;
 	gchar *str;
 
+
 	c = (struct con_data *) ref;
 
 	g_mutex_lock(&listlock);
 	for (elem = con_list; elem; elem = elem->next) {
 		item = (struct con_data *) elem->data;
-		item->priv = FALSE;
+
+		if (item->priv <= lvl) {
+			item->priv = PRIV_DEFAULT;
+		} else {
+			p = item;
+			break;
+		}
 	}
 	g_mutex_unlock(&listlock);
 
-	c->priv = TRUE;
-
 	str = net_get_host_string(c->con);
-	msg = g_strdup_printf("Reassigned control to %s (connected from %s)",
-			      c->nick, str);
+
+	if (!p) {
+		c->priv = lvl;
+		msg = g_strdup_printf("Reassigned control to %s "
+				      "(connected from %s)",
+				      c->nick, str);
+	} else if (p == c) {
+		c->priv = lvl;
+		msg = g_strdup_printf("%s (connected from %s) changed their "
+				      "own privilege level",
+				      c->nick, str);
+	} else {
+		gchar *h;
+
+		h = net_get_host_string(c->con);
+
+		msg = g_strdup_printf("Failed to reassign control to %s "
+				      "(connected from %s), as "
+				      "%s (connected from %s) holds a higher "
+				      "level of privilege",
+				      c->nick, str, p->nick, h);
+		g_free(h);
+	}
+
 
 	net_server_broadcast_message(msg, NULL);
 	net_push_userlist_cb(NULL);
@@ -841,6 +962,35 @@ void net_server_reassign_control(gpointer ref)
 }
 
 
+
+/**
+ * @brief escalate to maximum privilege level
+ */
+
+void net_server_iddqd(gpointer ref)
+{
+	net_server_reassign_control_internal(ref, PRIV_FULL);
+}
+
+
+/**
+ * @brief assign control privilege level to connection
+ */
+
+void net_server_reassign_control(gpointer ref)
+{
+	net_server_reassign_control_internal(ref, PRIV_CONTROL);
+}
+
+/**
+ * @brief drop to lowest priviledge on connection
+ */
+
+void net_server_drop_priv(gpointer ref)
+{
+	net_server_reassign_control_internal(ref, PRIV_DEFAULT);
+}
+
 /**
  * @brief set the nickname for a connection
  */
@@ -856,15 +1006,21 @@ void net_server_set_nickname(const gchar *nick, gpointer ref)
 	c = (struct con_data *) ref;
 
 
+	if (!strlen(nick)) {
+		g_message("Rejected nickname of zero length");
+		return;
+	}
+
+
 	old = c->nick;
 
 	c->nick = g_strdup(nick);
 
 	if (!c->new) {
-		buf = g_strdup_printf("<tt><span foreground='#F1C40F'>%s</span></tt> "
-				      "is now known as "
-				      "<tt><span foreground='#F1C40F'>%s</span></tt> ",
-				      old, c->nick);
+		buf = g_strdup_printf("<tt><span foreground='#F1C40F'>%s</span>"
+				      "</tt> is now known as "
+				      "<tt><span foreground='#F1C40F'>%s</span>"
+				      "</tt> ", old, c->nick);
 
 		net_server_broadcast_message(buf, NULL);
 
@@ -877,6 +1033,7 @@ void net_server_set_nickname(const gchar *nick, gpointer ref)
 }
 
 
+
 /**
  * @brief broadcast a text message to all clients
  */
@@ -885,33 +1042,46 @@ void net_server_broadcast_message(const gchar *msg, gpointer ref)
 {
 	gchar *buf;
 
-
 	struct con_data *c;
 
 
 	c = (struct con_data *) ref;
 
+	buf = net_server_msg_nick(msg, c);
 
-	if (!c) {
-		buf = g_strdup_printf("<tt><span foreground='#FF0000'>"
-				      "A hollow voice says:</span></tt> %s\n",
-				      msg);
-	} else {
-		buf = g_strdup_printf("<tt><span foreground='#7F9F7F'>"
-				      "%s:</span></tt> %s\n",
-				      c->nick, msg);
+	cmd_message(PKT_TRANS_ID_UNDEF, (guchar *) buf, strlen(buf));
 
-		g_print("%s %s\n", c->nick, msg);
-	}
+	g_free(buf);
+}
 
 
-	cmd_message(PKT_TRANS_ID_UNDEF, (guchar *) buf, strlen(buf));
+/**
+ * @brief send a text message to a client
+ *
+ */
+
+void net_server_direct_message(const gchar *msg, gpointer ref)
+{
+	gchar *buf;
+
+	struct con_data *c;
+	struct packet *pkt;
+
 
+	c = (struct con_data *) ref;
+
+	buf = net_server_msg_nick(msg, NULL);
+
+	pkt = cmd_message_gen(PKT_TRANS_ID_UNDEF, (uint8_t *) buf, strlen(buf));
+
+	net_send_single(c, (void *) pkt, pkt_size_get(pkt));
+
+	/* clean up */
+	g_free(pkt);
 	g_free(buf);
 }
 
 
-
 /**
  * initialise server networking
  */
diff --git a/src/server/proc/proc_pr_control.c b/src/server/proc/proc_pr_control.c
index 6b16046cda43c0aad4ecd57a31e9294784ab0b71..0ba4b4efef8aabc7c064c84c7b71bbed6f4debe8 100644
--- a/src/server/proc/proc_pr_control.c
+++ b/src/server/proc/proc_pr_control.c
@@ -22,7 +22,6 @@
 #include <net.h>
 
 
-
 void proc_pr_control(struct packet *pkt, gpointer ref)
 {
 	gchar *digest;
@@ -34,21 +33,35 @@ void proc_pr_control(struct packet *pkt, gpointer ref)
 	c = (struct control *) pkt->data;
 
 
-	if (strlen(c->digest) != c->len)
+	if (strlen((gchar *) c->digest) != c->len)
 		return;
 
+	/* haha, typo'ed :D */
 	digest = g_compute_hmac_for_string(G_CHECKSUM_SHA256,
 					   (guint8*)"radtel", 6,
 					   "thisishardcoed", 13);
 
 
 
-	if (!strcmp(digest, c->digest)) {
+
+	if (!strcmp(digest, (gchar *) c->digest)) {
+
 		g_message("Client telescope control reassigned");
 		net_server_reassign_control(ref);
-	} else {
-		g_message("Client telescope control NOT reassigned, digest "
-			  "mismatch %s %s", digest, c->digest);
+
+	} else if (strlen(server_cfg_get_masterkey())) {
+
+		if(!strcmp(server_cfg_get_masterkey(), (gchar *) c->digest)) {
+			g_message("Escalating privilege");
+			net_server_iddqd(ref);
+		} else {
+			g_message("Client telescope control NOT reassigned, "
+				  "digest mismatch %s %s, dropping client "
+				  "priviledge.",
+				  digest, c->digest);
+
+			net_server_drop_priv(ref);
+		}
 	}
 
 	g_free(digest);
diff --git a/src/server/proc/proc_pr_message.c b/src/server/proc/proc_pr_message.c
index dca0ca8478157186a8f0cadd9a1a09c45c905756..2bc91b216828430d6965ee5278700cab17588ba4 100644
--- a/src/server/proc/proc_pr_message.c
+++ b/src/server/proc/proc_pr_message.c
@@ -32,7 +32,7 @@ void proc_pr_message(struct packet *pkt, gpointer ref)
 	c = (struct message *) pkt->data;
 
 
-	if (strlen(c->message) != c->len)
+	if (strlen((gchar *) c->message) != c->len)
 		return;
 
 	net_server_broadcast_message((const gchar *) c->message, ref);
diff --git a/src/server/proc/proc_pr_moveto_azel.c b/src/server/proc/proc_pr_moveto_azel.c
index a40c5b05cdbafd531d3fe9ea66bcc568adb82fc5..5617f50ff691b05a97a91a11dfa0aefd34f6daac 100644
--- a/src/server/proc/proc_pr_moveto_azel.c
+++ b/src/server/proc/proc_pr_moveto_azel.c
@@ -29,8 +29,6 @@ void proc_pr_moveto_azel(struct packet *pkt, gpointer ref)
 	double az;
 	double el;
 
-	gsize pkt_size;
-
 	struct moveto *m;
 
 
diff --git a/src/server/proc/proc_pr_nick.c b/src/server/proc/proc_pr_nick.c
index 8023a4daa40936f0a96033ea1ab39f2a41632221..b8bdb8466c9fe5ba197aeceb5670e239ec031dec 100644
--- a/src/server/proc/proc_pr_nick.c
+++ b/src/server/proc/proc_pr_nick.c
@@ -32,7 +32,7 @@ void proc_pr_nick(struct packet *pkt, gpointer ref)
 	c = (struct nick *) pkt->data;
 
 
-	if (strlen(c->nick) != c->len)
+	if (strlen((gchar *) c->nick) != c->len)
 		return;
 
 	net_server_set_nickname((const gchar *) c->nick, ref);
diff --git a/src/server/proc/proc_pr_spec_acq_cfg.c b/src/server/proc/proc_pr_spec_acq_cfg.c
index 8c23c5dc0b1ebb7563a47aad3a297675b1876691..20cd5fdd06d7a5dec6d482c6c89f21ad735a91c4 100644
--- a/src/server/proc/proc_pr_spec_acq_cfg.c
+++ b/src/server/proc/proc_pr_spec_acq_cfg.c
@@ -21,8 +21,6 @@
 
 void proc_pr_spec_acq_cfg(struct packet *pkt, gpointer ref)
 {
-	gsize pkt_size;
-
 	struct spec_acq_cfg *acq;