diff --git a/CMakeLists.txt b/CMakeLists.txt
index 37260446c30caf1e13e979c190757abf395b35f3..887d2abad903e87e1e5d277a91e7f16020c6de30 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,7 +2,7 @@ project(cellframe-sdk C)
 cmake_minimum_required(VERSION 2.8)
 
 set(CMAKE_C_STANDARD 11)
-set(CELLFRAME_SDK_NATIVE_VERSION "2.6-88")
+set(CELLFRAME_SDK_NATIVE_VERSION "2.6-89")
 add_definitions ("-DCELLFRAME_SDK_VERSION=\"${CELLFRAME_SDK_NATIVE_VERSION}\"")
 set(DAPSDK_MODULES "")
 
diff --git a/modules/channel/chain/dap_stream_ch_chain.c b/modules/channel/chain/dap_stream_ch_chain.c
index 65e8690ef89bad19eb74eb656cde511bc86a2e8d..cad808a43ce0301ef5a131b672566dfb4eb388d3 100644
--- a/modules/channel/chain/dap_stream_ch_chain.c
+++ b/modules/channel/chain/dap_stream_ch_chain.c
@@ -140,6 +140,7 @@ void dap_stream_ch_chain_deinit()
  */
 void s_stream_ch_new(dap_stream_ch_t* a_ch, void* a_arg)
 {
+    UNUSED(a_arg);
     a_ch->internal = DAP_NEW_Z(dap_stream_ch_chain_t);
     dap_stream_ch_chain_t * l_ch_chain = DAP_STREAM_CH_CHAIN(a_ch);
     l_ch_chain->ch = a_ch;
@@ -1040,7 +1041,8 @@ void s_stream_ch_packet_out(dap_stream_ch_t* a_ch, void* a_arg)
 
         // Synchronize chains
         case CHAIN_STATE_SYNC_CHAINS: {
-            if (l_ch_chain->request_atom_iter->cur) { // Process one chain from l_ch_chain->request_atom_iter
+
+            if (l_ch_chain->request_atom_iter && l_ch_chain->request_atom_iter->cur) { // Process one chain from l_ch_chain->request_atom_iter
                 if(s_debug_chain_sync){
                     dap_chain_hash_fast_t l_atom_hash={0};
                     dap_hash_fast(l_ch_chain->request_atom_iter->cur, l_ch_chain->request_atom_iter->cur_size,&l_atom_hash);
@@ -1056,7 +1058,7 @@ void s_stream_ch_packet_out(dap_stream_ch_t* a_ch, void* a_arg)
                 // Then get next atom and populate new last
                 l_ch_chain->request_atom_iter->chain->callback_atom_iter_get_next(l_ch_chain->request_atom_iter, NULL);
             } else { // All chains synced
-                dap_stream_ch_chain_sync_request_t l_request = {};
+                dap_stream_ch_chain_sync_request_t l_request = {0};
                 // last message
                 dap_stream_ch_chain_pkt_write_unsafe(a_ch, DAP_STREAM_CH_CHAIN_PKT_TYPE_SYNCED_CHAINS,
                                                      l_ch_chain->request_hdr.net_id, l_ch_chain->request_hdr.chain_id,
diff --git a/modules/net/dap_chain_net.c b/modules/net/dap_chain_net.c
index a636a5c5ada7a336463e2e67a51904d2c4241fc4..6aa49a7a8c6dd66c0f5688aa3308026433b4615d 100644
--- a/modules/net/dap_chain_net.c
+++ b/modules/net/dap_chain_net.c
@@ -523,6 +523,7 @@ static int s_net_states_proc(dap_chain_net_t *a_net)
         case NET_STATE_SYNC_GDB:{
             for (dap_list_t *l_tmp = l_pvt_net->links; l_tmp; ) {
                 dap_chain_node_client_t *l_node_client = (dap_chain_node_client_t *)l_tmp->data;
+                dap_stream_worker_t *l_worker = dap_client_get_stream_worker(l_node_client->client);
                 dap_stream_ch_t *l_ch_chain = dap_client_get_stream_ch_unsafe(l_node_client->client, dap_stream_ch_chain_get_id());
                 if (   !l_ch_chain) { // Channel or stream or client itself closed
                     l_tmp = dap_list_next(l_tmp);
@@ -530,7 +531,7 @@ static int s_net_states_proc(dap_chain_net_t *a_net)
                     l_pvt_net->links = dap_list_remove(l_pvt_net->links, l_node_client);
                     continue;
                 }
-                dap_stream_worker_t *l_worker = dap_client_get_stream_worker(l_node_client->client);
+
                 dap_stream_ch_chain_sync_request_t l_sync_gdb = {};
                 // Get last timestamp in log if wasn't SYNC_FROM_ZERO flag
                 if (! (l_pvt_net->flags & F_DAP_CHAIN_NET_SYNC_FROM_ZERO) )
diff --git a/modules/net/dap_chain_node_client.c b/modules/net/dap_chain_node_client.c
index 61a8d6eac6f50ba36c1251c5e66f30c6b9f87fa8..06c6d203283e07135f7dca461485fcdce577b0bf 100644
--- a/modules/net/dap_chain_node_client.c
+++ b/modules/net/dap_chain_node_client.c
@@ -404,8 +404,27 @@ static void s_ch_chain_callback_notify_packet_R(dap_stream_ch_chain_net_srv_t* a
  *
  * return a connection handle, or NULL, if an error
  */
-dap_chain_node_client_t* dap_chain_client_connect(dap_chain_node_info_t *a_node_info, dap_client_stage_t a_stage_target,
-        const char *a_active_channels)
+
+dap_chain_node_client_t* dap_chain_client_connect(dap_chain_node_info_t *a_node_info, const char *a_active_channels)
+{
+    return dap_chain_node_client_create_n_connect(a_node_info,a_active_channels,NULL,NULL,NULL,NULL,NULL);
+}
+
+/**
+ * @brief dap_chain_node_client_go_stage
+ * @param a_node_info
+ * @param a_active_channels
+ * @param a_callback_connected
+ * @param a_callback_disconnected
+ * @param a_callback_stage
+ * @param a_callback_error
+ * @param a_callback_arg
+ * @return
+ */
+dap_chain_node_client_t* dap_chain_node_client_create_n_connect(dap_chain_node_info_t *a_node_info,
+        const char *a_active_channels, dap_chain_node_client_callback_t a_callback_connected, dap_chain_node_client_callback_t a_callback_disconnected,
+                                                        dap_chain_node_client_callback_stage_t a_callback_stage,
+                                                        dap_chain_node_client_callback_error_t a_callback_error, void * a_callback_arg )
 {
     if(!a_node_info) {
         log_it(L_ERROR, "Can't connect to the node: null object node_info");
@@ -413,6 +432,11 @@ dap_chain_node_client_t* dap_chain_client_connect(dap_chain_node_info_t *a_node_
     }
     dap_chain_node_client_t *l_node_client = DAP_NEW_Z(dap_chain_node_client_t);
     l_node_client->state = NODE_CLIENT_STATE_DISCONNECTED;
+    l_node_client->callback_arg = a_callback_arg;
+    l_node_client->callback_connected = a_callback_connected;
+    l_node_client->callback_discconnected = a_callback_disconnected;
+    l_node_client->callback_error = a_callback_error;
+    l_node_client->callback_stage = a_callback_stage;
 
 #ifndef _WIN32
     pthread_condattr_t attr;
@@ -458,7 +482,7 @@ dap_chain_node_client_t* dap_chain_client_connect(dap_chain_node_info_t *a_node_
     // ref pvt client
     //dap_client_pvt_ref(DAP_CLIENT_PVT(l_node_client->client));
     // Handshake & connect
-    dap_client_go_stage(l_node_client->client, a_stage_target, s_stage_connected_callback);
+    dap_client_go_stage(l_node_client->client, STAGE_STREAM_STREAMING, s_stage_connected_callback);
     return l_node_client;
 }
 
@@ -469,9 +493,8 @@ dap_chain_node_client_t* dap_chain_client_connect(dap_chain_node_info_t *a_node_
  */
 dap_chain_node_client_t* dap_chain_node_client_connect(dap_chain_node_info_t *a_node_info)
 {
-    dap_client_stage_t l_stage_target = STAGE_STREAM_STREAMING;
     const char *l_active_channels = "CN";
-    return dap_chain_client_connect(a_node_info, l_stage_target, l_active_channels);
+    return dap_chain_client_connect(a_node_info, l_active_channels);
 }
 
 void dap_chain_node_client_reset(dap_chain_node_client_t *a_client)
diff --git a/modules/net/include/dap_chain_node_client.h b/modules/net/include/dap_chain_node_client.h
index 11d4b6ce6705ac13954982b6be4d7efabeffcac0..aedb408b74d318fcd05920f5be3d0a3816527471 100644
--- a/modules/net/include/dap_chain_node_client.h
+++ b/modules/net/include/dap_chain_node_client.h
@@ -50,6 +50,8 @@ typedef enum dap_chain_node_client_state {
 typedef struct dap_chain_node_client dap_chain_node_client_t;
 
 typedef void (*dap_chain_node_client_callback_t)(dap_chain_node_client_t *, void*);
+typedef void (*dap_chain_node_client_callback_stage_t)(dap_chain_node_client_t *, dap_client_stage_t, void * );
+typedef void (*dap_chain_node_client_callback_error_t)(dap_chain_node_client_t *, int, void *);
 
 // state for a client connection
 typedef struct dap_chain_node_client {
@@ -59,7 +61,6 @@ typedef struct dap_chain_node_client {
     dap_events_t *events;
     char last_error[128];
 
-    dap_chain_node_client_callback_t callback_connected;
     #ifndef _WIN32
     pthread_cond_t wait_cond;
     #else
@@ -75,6 +76,13 @@ typedef struct dap_chain_node_client {
     struct in6_addr remote_ipv6;
 
     bool keep_connection;
+
+    // callbacks
+    dap_chain_node_client_callback_t callback_connected;
+    dap_chain_node_client_callback_t callback_discconnected;
+    dap_chain_node_client_callback_stage_t callback_stage;
+    dap_chain_node_client_callback_error_t callback_error;
+    void * callback_arg;
 } dap_chain_node_client_t;
 #define DAP_CHAIN_NODE_CLIENT(a) (a ? (dap_chain_node_client_t *) (a)->_inheritor : NULL)
 
@@ -82,14 +90,24 @@ int dap_chain_node_client_init(void);
 
 void dap_chain_node_client_deinit(void);
 
-dap_chain_node_client_t* dap_chain_client_connect(dap_chain_node_info_t *a_node_info, dap_client_stage_t a_stage_target,
-        const char *a_active_channels);
+
+dap_chain_node_client_t* dap_chain_node_client_create_n_connect(dap_chain_node_info_t *a_node_info,  const char *a_active_channels,
+                                                                dap_chain_node_client_callback_t a_callback_connected,
+                                                                dap_chain_node_client_callback_t a_callback_disconnected,
+                                                                dap_chain_node_client_callback_stage_t a_callback_stage,
+                                                                dap_chain_node_client_callback_error_t a_callback_error,
+                                                                void * a_callback_arg );
+
+
+dap_chain_node_client_t* dap_chain_client_connect(dap_chain_node_info_t *a_node_info,  const char *a_active_channels);
 /**
  * Create handshake to server
  *
  * return a connection handle, or NULL, if an error
  */
 dap_chain_node_client_t* dap_chain_node_client_connect(dap_chain_node_info_t *node_info);
+
+
 /**
  * Reset client state to connected state if it is connected
  */
diff --git a/modules/service/vpn/dap_chain_net_vpn_client.c b/modules/service/vpn/dap_chain_net_vpn_client.c
index 25042bf8d5610074c96305325a5f9c576f2e367f..d60335d6358f016d06326d591663e85e53145fb6 100644
--- a/modules/service/vpn/dap_chain_net_vpn_client.c
+++ b/modules/service/vpn/dap_chain_net_vpn_client.c
@@ -431,14 +431,13 @@ int dap_chain_net_vpn_client_check(dap_chain_net_t *a_net, const char *a_ipv4_st
     gettimeofday(&l_t, NULL);//get_cur_time_msec
     long l_t1 = (long) l_t.tv_sec * 1000 + l_t.tv_usec / 1000;
 
-    dap_client_stage_t l_stage_target = STAGE_STREAM_STREAMING; //DAP_CLIENT_STAGE_STREAM_CTL;//STAGE_STREAM_STREAMING;
     const char l_active_channels[] = { dap_stream_ch_chain_net_srv_get_id(), 0 }; //only R, without S
     if(a_ipv4_str)
         inet_pton(AF_INET, a_ipv4_str, &(s_node_info->hdr.ext_addr_v4));
     if(a_ipv6_str)
         inet_pton(AF_INET6, a_ipv6_str, &(s_node_info->hdr.ext_addr_v6));
 
-    s_vpn_client = dap_chain_client_connect(s_node_info, l_stage_target, l_active_channels);
+    s_vpn_client = dap_chain_client_connect(s_node_info, l_active_channels);
     if(!s_vpn_client) {
         log_it(L_ERROR, "Can't connect to VPN server=%s:%d", a_ipv4_str, a_port);
         // clean client struct
@@ -527,14 +526,13 @@ int dap_chain_net_vpn_client_start(dap_chain_net_t *a_net, const char *a_ipv4_st
         s_node_info = DAP_NEW_Z(dap_chain_node_info_t);
     s_node_info->hdr.ext_port = a_port;
 
-    dap_client_stage_t l_stage_target = STAGE_STREAM_STREAMING; //DAP_CLIENT_STAGE_STREAM_CTL;//STAGE_STREAM_STREAMING;
     const char l_active_channels[] = { dap_stream_ch_chain_net_srv_get_id(), DAP_STREAM_CH_ID_NET_SRV_VPN, 0 }; //R, S
     if(a_ipv4_str)
         inet_pton(AF_INET, a_ipv4_str, &(s_node_info->hdr.ext_addr_v4));
     if(a_ipv6_str)
         inet_pton(AF_INET6, a_ipv6_str, &(s_node_info->hdr.ext_addr_v6));
 
-    s_vpn_client = dap_chain_client_connect(s_node_info, l_stage_target, l_active_channels);
+    s_vpn_client = dap_chain_client_connect(s_node_info, l_active_channels);
     if(!s_vpn_client) {
         log_it(L_ERROR, "Can't connect to VPN server=%s:%d", a_ipv4_str, a_port);
         // clean client struct