diff --git a/core/network_thread.c b/core/network_thread.c
index 0e6080d..ae4eb24 100644
--- a/core/network_thread.c
+++ b/core/network_thread.c
@@ -87,9 +87,9 @@ static bool is_selection_allowed(const char *software_set, char *running_mode,
 
 	if (allowed) {
 		INFO("Accepted selection %s,%s", software_set, running_mode);
-	}else 
+	}else
 		ERROR("Selection %s,%s is not allowed, rejected !",
-		      software_set, running_mode); 
+		      software_set, running_mode);
 	return allowed;
 }
 
@@ -445,6 +445,15 @@ void *network_thread (void *data)
 					       ? ACK
 					       : NACK;
 				break;
+			case GET_UPDATE_STATE:
+				msg.data.msg[0] = get_state();
+				msg.type = ACK;
+				break;
+			case UNSET_UPDATE_STATE:
+				msg.type = unset_state(msg.data.msg[0]) == 0 ?
+					ACK : NACK;
+
+				break;
 			default:
 				msg.type = NACK;
 			}
diff --git a/core/state.c b/core/state.c
index 8ddd760..74c1d55 100644
--- a/core/state.c
+++ b/core/state.c
@@ -30,19 +30,19 @@
 	} \
 } while(0)
 
-static server_op_res_t do_save_state(char *key, char* value)
+static int do_save_state(char *key, char* value)
 {
-	char c;
 	CHECK_STATE_VAR(key);
 	if (!value)
 		return -EINVAL;
-	c = *value;
+	char c = *value;
 	if (c < STATE_OK || c > STATE_LAST)
 		return -EINVAL;
-	return bootloader_env_set(key, value) == 0 ? SERVER_OK : SERVER_EERR;
+
+	return bootloader_env_set(key, value);
 }
 
-server_op_res_t save_state(char *key, update_state_t value)
+int save_state(char *key, update_state_t value)
 {
 	char value_str[2] = {value, '\0'};
 	ipc_message msg;
@@ -52,64 +52,96 @@ server_op_res_t save_state(char *key, update_state_t value)
 		msg.type = SET_UPDATE_STATE;
 		msg.data.msg[0] = (char)value;
 		return (ipc_send_cmd(&msg));
-	} else { /* Main process */
+	} else {
+		/* Main process */
 		return do_save_state(key, value_str);
 	}
 }
 
 
-server_op_res_t save_state_string(char *key, update_state_t value)
+int save_state_string(char *key, update_state_t value)
 {
 	CHECK_STATE_VAR(key);
 	if (!value)
 		return -EINVAL;
 	if (value < STATE_OK || value > STATE_LAST)
 		return -EINVAL;
-	return bootloader_env_set(key, get_state_string(value)) == 0 ?
-		SERVER_OK : SERVER_EERR;
+	return bootloader_env_set(key, get_state_string(value));
 }
 
-server_op_res_t read_state(char *key, update_state_t *value)
+static update_state_t read_state(char *key)
 {
-	char *envval;
 	CHECK_STATE_VAR(key);
 
-	envval = bootloader_env_get(key);
+	char *envval = bootloader_env_get(key);
 	if (envval == NULL) {
 		INFO("Key '%s' not found in Bootloader's environment.", key);
-		*value = STATE_NOT_AVAILABLE;
-		return SERVER_OK;
+		return STATE_NOT_AVAILABLE;
 	}
 	/* TODO It's a bit whacky just to cast this but as we're the only */
 	/*      ones touching the variable, it's maybe OK for a PoC now. */
-	*value = (update_state_t)*envval;
 
+	update_state_t val = (update_state_t)*envval;
 	/* bootloader get env allocates space for the value */
 	free(envval);
 
-	return SERVER_OK;
+	return val;
 }
-server_op_res_t unset_state(char *key)
-{
-	int ret;
 
+static int do_unset_state(char *key)
+{
 	CHECK_STATE_VAR(key);
-	ret = bootloader_env_unset(key);
-	return ret == 0 ? SERVER_OK : SERVER_EERR;
+	return bootloader_env_unset(key);
 }
 
-update_state_t get_state(void) {
-	update_state_t state;
+int unset_state(char *key)
+{
+	if (pid == getpid())
+	{
+		ipc_message msg;
+		memset(&msg, 0, sizeof(msg));
+
+		msg.type = UNSET_UPDATE_STATE;
+		return ipc_send_cmd(&msg) == 0 && msg.type == ACK;
+	} else {
+		// Main process
+		return do_unset_state(key);
+	}
+}
+
+static update_state_t do_get_state(void) {
+	update_state_t state = read_state((char *)STATE_KEY);
 
-	if (read_state((char *)STATE_KEY, &state) != SERVER_OK) {
+	if (state == STATE_NOT_AVAILABLE) {
 		ERROR("Cannot read stored update state.");
-		return STATE_ERROR;
+		return STATE_NOT_AVAILABLE;
 	}
-	TRACE("Read state=%c from persistent storage.", state);
 
 	if (is_valid_state(state)) {
+		TRACE("Read state=%c from persistent storage.", state);
 		return state;
 	}
+
 	ERROR("Unknown update state=%c", state);
-	return STATE_ERROR;
+	return STATE_NOT_AVAILABLE;
+}
+
+update_state_t get_state(void) {
+	if (pid == getpid())
+	{
+		ipc_message msg;
+		memset(&msg, 0, sizeof(msg));
+
+		msg.type = GET_UPDATE_STATE;
+
+		if (ipc_send_cmd(&msg) || msg.type == NACK) {
+			ERROR("Failed to get current bootloader update state.");
+			return STATE_NOT_AVAILABLE;
+		}
+
+		return (update_state_t)msg.data.msg[0];
+	} else {
+		// Main process
+		return do_get_state();
+	}
 }
diff --git a/include/network_ipc.h b/include/network_ipc.h
index 22ecb9a..34bc43d 100644
--- a/include/network_ipc.h
+++ b/include/network_ipc.h
@@ -35,6 +35,8 @@ typedef enum {
 	SWUPDATE_SUBPROCESS,
 	SET_AES_KEY,
 	SET_UPDATE_STATE,	/* set bootloader ustate */
+	GET_UPDATE_STATE,
+	UNSET_UPDATE_STATE,
 	REQ_INSTALL_EXT
 } msgtype;
 
@@ -71,7 +73,7 @@ struct swupdate_request {
 
 typedef union {
 	char msg[128];
-	struct { 
+	struct {
 		int current;
 		int last_result;
 		int error;
@@ -100,7 +102,7 @@ typedef union {
 		char ivt_ascii[33]; /* Key size in ASCII (16 bytes bin) + termination */
 	} aeskeymsg;
 } msgdata;
-	
+
 typedef struct {
 	int magic;	/* magic number */
 	int type;
diff --git a/include/state.h b/include/state.h
index f006b6c..cb9a947 100644
--- a/include/state.h
+++ b/include/state.h
@@ -63,8 +63,7 @@ static inline char* get_state_string(update_state_t state) {
 	return (char*)"<nil>";
 }
 
-server_op_res_t save_state(char *key, update_state_t value);
-server_op_res_t save_state_string(char *key, update_state_t value);
-server_op_res_t read_state(char *key, update_state_t *value);
-server_op_res_t unset_state(char *key);
+int save_state(char *key, update_state_t value);
+int save_state_string(char *key, update_state_t value);
+int unset_state(char *key);
 update_state_t get_state(void);
diff --git a/test/test_server_hawkbit.c b/test/test_server_hawkbit.c
index 9c7c128..03c5475 100644
--- a/test/test_server_hawkbit.c
+++ b/test/test_server_hawkbit.c
@@ -115,22 +115,20 @@ channel_op_res_t __wrap_channel_get(channel_t *this, void *data)
 	return mock_type(channel_op_res_t);
 }
 
-extern server_op_res_t __real_save_state(char *key, update_state_t value);
-server_op_res_t __wrap_save_state(char *key, update_state_t *value);
-server_op_res_t __wrap_save_state(char *key, update_state_t *value)
+extern int  __real_save_state(char *key, update_state_t value);
+int __wrap_save_state(char *key, update_state_t *value);
+int __wrap_save_state(char *key, update_state_t *value)
 {
 	(void)key;
 	(void)value;
-	return mock_type(server_op_res_t);
+	return mock_type(int);
 }
 
-extern server_op_res_t __real_read_state(char *key, update_state_t *value);
-server_op_res_t __wrap_read_state(char *key, update_state_t *value);
-server_op_res_t __wrap_read_state(char *key, update_state_t *value)
+extern update_state_t __real_get_state(void);
+update_state_t __wrap_get_state(void);
+update_state_t __wrap_get_state(void)
 {
-	(void)key;
-	*value = mock_type(update_state_t);
-	return mock_type(server_op_res_t);
+	return mock_type(update_state_t);
 }
 
 extern server_op_res_t server_has_pending_action(int *action_id);
@@ -218,14 +216,11 @@ static void test_server_has_pending_action(void **state)
 	will_return(__wrap_channel_get,
 		    json_tokener_parse(json_reply_update_data));
 	will_return(__wrap_channel_get, CHANNEL_OK);
-#if 0
-	will_return(__wrap_read_state, STATE_NOT_AVAILABLE);
-	will_return(__wrap_read_state, SERVER_OK);
-#endif
+
+	will_return(__wrap_get_state, STATE_NOT_AVAILABLE);
 	assert_int_equal(SERVER_UPDATE_AVAILABLE,
 			 server_has_pending_action(&action_id));
 
-#if 0
 	/* Test Case: Update Action available && STATE_INSTALLED. */
 	will_return(__wrap_channel_get,
 		    json_tokener_parse(json_reply_update_available));
@@ -233,11 +228,9 @@ static void test_server_has_pending_action(void **state)
 	will_return(__wrap_channel_get,
 		    json_tokener_parse(json_reply_update_data));
 	will_return(__wrap_channel_get, CHANNEL_OK);
-	will_return(__wrap_read_state, STATE_INSTALLED);
-	will_return(__wrap_read_state, SERVER_OK);
+	will_return(__wrap_get_state, STATE_INSTALLED);
 	assert_int_equal(SERVER_NO_UPDATE_AVAILABLE,
 			 server_has_pending_action(&action_id));
-#endif
 
 	/* Test Case: Cancel Action available. */
 	will_return(__wrap_channel_get,
@@ -247,7 +240,7 @@ static void test_server_has_pending_action(void **state)
 		    json_tokener_parse(json_reply_cancel_data));
 	will_return(__wrap_channel_get, CHANNEL_OK);
 	will_return(__wrap_channel_put, CHANNEL_OK);
-	will_return(__wrap_save_state, SERVER_OK);
+	will_return(__wrap_save_state, 0);
 	assert_int_equal(SERVER_OK, server_has_pending_action(&action_id));
 }
 
@@ -542,7 +535,7 @@ static void test_server_install_update(void **state)
 	will_return(__wrap_channel_get_file, CHANNEL_OK);
 	will_return(__wrap_ipc_wait_for_complete, SUCCESS);
 	will_return(__wrap_channel_put, CHANNEL_OK);
-	//will_return(__wrap_save_state, SERVER_OK);
+	//will_return(__wrap_save_state, 0);
 	will_return(__wrap_channel_put, CHANNEL_OK);
 	assert_int_equal(SERVER_OK, server_install_update());
 }
