diff --git a/master/ethernet.c b/master/ethernet.c
index 53edc5055768adc4a28368db7690c335ee5dfd4b..9f6d08cad81952f62e9dba380d282ca68edb2902 100644
--- a/master/ethernet.c
+++ b/master/ethernet.c
@@ -317,7 +317,8 @@ int ec_eoe_active(const ec_eoe_t *eoe /**< EoE handler */)
 
 void ec_eoe_state_rx_start(ec_eoe_t *eoe /**< EoE handler */)
 {
-    if (!eoe->slave->online || !eoe->slave->master->main_device.link_state)
+    if (eoe->slave->online_state == EC_SLAVE_OFFLINE ||
+            !eoe->slave->master->main_device.link_state)
         return;
 
     ec_slave_mbox_prepare_check(eoe->slave, &eoe->datagram);
@@ -518,7 +519,8 @@ void ec_eoe_state_tx_start(ec_eoe_t *eoe /**< EoE handler */)
     unsigned int wakeup = 0;
 #endif
 
-    if (!eoe->slave->online || !eoe->slave->master->main_device.link_state)
+    if (eoe->slave->online_state == EC_SLAVE_OFFLINE ||
+            !eoe->slave->master->main_device.link_state)
         return;
 
     spin_lock_bh(&eoe->tx_queue_lock);
diff --git a/master/fsm_master.c b/master/fsm_master.c
index 4f9104bbe8b889dec1de15173f51f2c48ffe8192..e4068552d6535257fdc9fbfc59a2cfeaa21c4a73 100644
--- a/master/fsm_master.c
+++ b/master/fsm_master.c
@@ -185,7 +185,7 @@ void ec_fsm_master_state_broadcast(ec_fsm_master_t *fsm /**< master state machin
         // link is down
         fsm->slaves_responding = 0;
         list_for_each_entry(slave, &master->slaves, list) {
-            slave->online = 0;
+            ec_slave_set_online_state(slave, EC_SLAVE_OFFLINE);
         }
         fsm->state = ec_fsm_master_state_error;
         return;
@@ -302,7 +302,7 @@ int ec_fsm_master_action_process_eeprom(
         up(&master->eeprom_sem);
 
         slave = request->slave;
-        if (!slave->online || slave->error_flag) {
+        if (slave->online_state == EC_SLAVE_OFFLINE || slave->error_flag) {
             EC_ERR("Discarding EEPROM data, slave %i not ready.\n",
                     slave->ring_position);
             request->state = EC_EEPROM_REQ_ERROR;
@@ -344,7 +344,7 @@ void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm
     // check if any slaves are not in the state, they're supposed to be
     list_for_each_entry(slave, &master->slaves, list) {
         if (slave->error_flag
-            || !slave->online
+            || slave->online_state == EC_SLAVE_OFFLINE
             || slave->requested_state == EC_SLAVE_STATE_UNKNOWN
             || (slave->current_state == slave->requested_state
                 && slave->self_configured)) continue;
@@ -380,7 +380,7 @@ void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm
                 EC_DBG("Processing SDO request...\n");
             slave = master->sdo_request->sdo->slave;
             if (slave->current_state == EC_SLAVE_STATE_INIT
-                || !slave->online) {
+                || slave->online_state == EC_SLAVE_OFFLINE) {
                 EC_ERR("Failed to process SDO request, slave %i not ready.\n",
                        slave->ring_position);
                 master->sdo_request->return_code = -1;
@@ -403,7 +403,7 @@ void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm
                 || slave->sdo_dictionary_fetched
                 || slave->current_state == EC_SLAVE_STATE_INIT
                 || jiffies - slave->jiffies_preop < EC_WAIT_SDO_DICT * HZ
-                || !slave->online
+                || slave->online_state == EC_SLAVE_OFFLINE
                 || slave->error_flag) continue;
 
             if (master->debug_level) {
@@ -459,7 +459,7 @@ void ec_fsm_master_action_next_slave_state(ec_fsm_master_t *fsm
     if (fsm->validate) {
         fsm->validate = 0;
         list_for_each_entry(slave, &master->slaves, list) {
-            if (slave->online) continue;
+            if (slave->online_state == EC_SLAVE_ONLINE) continue;
 
             // At least one slave is offline. validate!
             EC_INFO("Validating bus.\n");
@@ -485,7 +485,6 @@ void ec_fsm_master_state_read_states(ec_fsm_master_t *fsm /**< master state mach
 {
     ec_slave_t *slave = fsm->slave;
     ec_datagram_t *datagram = fsm->datagram;
-    uint8_t new_state;
 
     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) {
         ec_master_queue_datagram(fsm->master, fsm->datagram);
@@ -501,39 +500,14 @@ void ec_fsm_master_state_read_states(ec_fsm_master_t *fsm /**< master state mach
 
     // did the slave not respond to its station address?
     if (datagram->working_counter != 1) {
-        if (slave->online) {
-            slave->online = 0;
-            if (slave->master->debug_level)
-                EC_DBG("Slave %i: offline.\n", slave->ring_position);
-        }
+        ec_slave_set_online_state(slave, EC_SLAVE_OFFLINE);
         ec_fsm_master_action_next_slave_state(fsm);
         return;
     }
 
     // slave responded
-    new_state = EC_READ_U8(datagram->data);
-    if (!slave->online) { // slave was offline before
-        slave->online = 1;
-        slave->error_flag = 0; // clear error flag
-        slave->current_state = new_state;
-        if (slave->master->debug_level) {
-            char cur_state[EC_STATE_STRING_SIZE];
-            ec_state_string(slave->current_state, cur_state);
-            EC_DBG("Slave %i: online (%s).\n",
-                   slave->ring_position, cur_state);
-        }
-    }
-    else if (new_state != slave->current_state) {
-        if (slave->master->debug_level) {
-            char old_state[EC_STATE_STRING_SIZE],
-                cur_state[EC_STATE_STRING_SIZE];
-            ec_state_string(slave->current_state, old_state);
-            ec_state_string(new_state, cur_state);
-            EC_DBG("Slave %i: %s -> %s.\n",
-                   slave->ring_position, old_state, cur_state);
-        }
-        slave->current_state = new_state;
-    }
+    ec_slave_set_state(slave, EC_READ_U8(datagram->data)); // set app state first
+    ec_slave_set_online_state(slave, EC_SLAVE_ONLINE);
 
     // check, if new slave state has to be acknowledged
     if (slave->current_state & EC_SLAVE_STATE_ACK_ERR && !slave->error_flag) {
@@ -614,7 +588,7 @@ void ec_fsm_master_action_addresses(ec_fsm_master_t *fsm /**< master state machi
 {
     ec_datagram_t *datagram = fsm->datagram;
 
-    while (fsm->slave->online) {
+    while (fsm->slave->online_state == EC_SLAVE_ONLINE) {
         if (fsm->slave->list.next == &fsm->master->slaves) { // last slave?
             fsm->state = ec_fsm_master_state_start;
             fsm->state(fsm); // execute immediately
diff --git a/master/master.c b/master/master.c
index cd70315ae3dbda00c02f711029229f8cda88acdf..cdd601b75921abef690e44694e8d3d3989a9da7f 100644
--- a/master/master.c
+++ b/master/master.c
@@ -528,7 +528,7 @@ void ec_master_leave_operation_mode(ec_master_t *master
 
         // don't try to set PREOP for slaves that don't respond,
         // because of 3 second timeout.
-        if (!slave->online) {
+        if (slave->online_state == EC_SLAVE_OFFLINE) {
             if (master->debug_level)
                 EC_DBG("Skipping to configure offline slave %i.\n",
                         slave->ring_position);
diff --git a/master/slave.c b/master/slave.c
index ea7aef9116c4fbd0d200d6a55526ad6b835147ae..0679c32a954cd988f397bff2586ffd1d015e478f 100644
--- a/master/slave.c
+++ b/master/slave.c
@@ -116,7 +116,7 @@ int ec_slave_init(ec_slave_t *slave, /**< EtherCAT slave */
     slave->current_state = EC_SLAVE_STATE_UNKNOWN;
     slave->self_configured = 0;
     slave->error_flag = 0;
-    slave->online = 1;
+    slave->online_state = EC_SLAVE_ONLINE;
     slave->fmmu_count = 0;
 
     slave->coupler_index = 0;
@@ -328,6 +328,58 @@ void ec_slave_reset(ec_slave_t *slave /**< EtherCAT slave */)
 
 /*****************************************************************************/
 
+/**
+ * Sets the application state of a slave.
+ */
+
+void ec_slave_set_state(ec_slave_t *slave, /**< EtherCAT slave */
+        ec_slave_state_t new_state /**< new application state */
+        )
+{
+    if (new_state != slave->current_state) {
+        if (slave->master->debug_level) {
+            char old_state[EC_STATE_STRING_SIZE],
+                cur_state[EC_STATE_STRING_SIZE];
+            ec_state_string(slave->current_state, old_state);
+            ec_state_string(new_state, cur_state);
+            EC_DBG("Slave %i: %s -> %s.\n",
+                   slave->ring_position, old_state, cur_state);
+        }
+        slave->current_state = new_state;
+    }
+}
+
+/*****************************************************************************/
+
+/**
+ * Sets the online state of a slave.
+ */
+
+void ec_slave_set_online_state(ec_slave_t *slave, /**< EtherCAT slave */
+        ec_slave_online_state_t new_state /**< new online state */
+        )
+{
+    if (new_state == EC_SLAVE_OFFLINE &&
+            slave->online_state == EC_SLAVE_ONLINE) {
+        if (slave->master->debug_level)
+            EC_DBG("Slave %i: offline.\n", slave->ring_position);
+    }
+    else if (new_state == EC_SLAVE_ONLINE &&
+            slave->online_state == EC_SLAVE_OFFLINE) {
+        slave->error_flag = 0; // clear error flag
+        if (slave->master->debug_level) {
+            char cur_state[EC_STATE_STRING_SIZE];
+            ec_state_string(slave->current_state, cur_state);
+            EC_DBG("Slave %i: online (%s).\n",
+                   slave->ring_position, cur_state);
+        }
+    }
+
+    slave->online_state = new_state;
+}
+
+/*****************************************************************************/
+
 /**
  */
 
@@ -636,8 +688,8 @@ size_t ec_slave_info(const ec_slave_t *slave, /**< EtherCAT slave */
     off += sprintf(buffer + off, " (");
     off += ec_state_string(slave->requested_state, buffer + off);
     off += sprintf(buffer + off, ")\nFlags: %s, %s\n",
-                   slave->online ? "online" : "OFFLINE",
-                   slave->error_flag ? "ERROR" : "ok");
+            slave->online_state == EC_SLAVE_ONLINE ? "online" : "OFFLINE",
+            slave->error_flag ? "ERROR" : "ok");
     off += sprintf(buffer + off, "Ring position: %i\n",
                    slave->ring_position);
     off += sprintf(buffer + off, "Advanced position: %i:%i\n",
diff --git a/master/slave.h b/master/slave.h
index cd6f9fb773ef97df85120b43702a383eb363bbb2..6654422a18879c7166324e32c58384d5e280ccf5 100644
--- a/master/slave.h
+++ b/master/slave.h
@@ -72,6 +72,12 @@ typedef enum
 }
 ec_slave_state_t;
 
+typedef enum {
+    EC_SLAVE_OFFLINE,
+    EC_SLAVE_ONLINE
+}
+ec_slave_online_state_t;
+
 /*****************************************************************************/
 
 /**
@@ -195,11 +201,11 @@ struct ec_slave
     struct kobject kobj; /**< kobject */
     ec_master_t *master; /**< master owning the slave */
 
-    ec_slave_state_t requested_state; /**< requested slave state */
-    ec_slave_state_t current_state; /**< current slave state */
+    ec_slave_state_t requested_state; /**< requested application state */
+    ec_slave_state_t current_state; /**< current application state */
     unsigned int self_configured; /**< slave was configured by this master */
     unsigned int error_flag; /**< stop processing after an error */
-    unsigned int online; /**< non-zero, if the slave responds. */
+    unsigned int online_state; /**< online state */
 
     // addresses
     uint16_t ring_position; /**< ring position */
@@ -266,6 +272,8 @@ int ec_slave_prepare_fmmu(ec_slave_t *, const ec_domain_t *,
                           const ec_sii_sync_t *);
 
 void ec_slave_request_state(ec_slave_t *, ec_slave_state_t);
+void ec_slave_set_state(ec_slave_t *, ec_slave_state_t);
+void ec_slave_set_online_state(ec_slave_t *, ec_slave_online_state_t);
 
 // SII categories
 int ec_slave_fetch_strings(ec_slave_t *, const uint8_t *);