+
+ return SILC_FSM_WAIT;
+}
+
+/* Resuming completed */
+
+SILC_FSM_STATE(silc_client_st_resume_completed)
+{
+ SilcClientConnection conn = fsm_context;
+ SilcClient client = conn->client;
+ SilcClientResumeSession resume = state_context;
+ SilcIDCacheEntry entry;
+ SilcChannelEntry channel;
+ SilcList channels;
+
+ if (conn->internal->disconnected) {
+ /** Disconnected */
+ silc_fsm_next(fsm, silc_client_st_resume_error);
+ return SILC_FSM_CONTINUE;
+ }
+
+ if (resume->channel_count > 0) {
+ resume->channel_count--;
+ if (resume->channel_count)
+ return SILC_FSM_WAIT;
+ }
+
+ SILC_LOG_DEBUG(("Resuming completed"));
+
+ /* Issue IDENTIFY command for itself to get resolved hostname
+ correctly from server. */
+ silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY,
+ silc_client_register_command_called, NULL,
+ 1, 5, silc_buffer_data(conn->internal->local_idp),
+ silc_buffer_len(conn->internal->local_idp));
+
+ /* Issue INFO command to fetch the real server name and server
+ information and other stuff. */
+ silc_client_command_send(client, conn, SILC_COMMAND_INFO,
+ silc_client_register_command_called, NULL,
+ 1, 2, silc_buffer_data(conn->internal->remote_idp),
+ silc_buffer_len(conn->internal->remote_idp));
+
+ /* Call connection callback. We have now resumed to SILC network. */
+ conn->callback(client, conn, SILC_CLIENT_CONN_SUCCESS_RESUME, 0, NULL,
+ conn->callback_context);
+
+ /* Call NICK command reply. */
+ silc_client_resume_command_callback(client, conn, SILC_COMMAND_NICK,
+ conn->local_entry,
+ conn->local_entry->nickname,
+ &conn->local_entry->id);
+
+ /* Call JOIN command replies for all joined channel */
+ silc_idcache_get_all(conn->internal->channel_cache, &channels);
+ silc_list_start(channels);
+ while ((entry = silc_list_get(channels))) {
+ SilcHashTableList htl;
+ const char *cipher, *hmac;
+
+ channel = entry->context;
+ cipher = (channel->internal.channel_key ?
+ silc_cipher_get_name(channel->internal.channel_key) : NULL);
+ hmac = (channel->internal.hmac ?
+ silc_hmac_get_name(channel->internal.hmac) : NULL);
+ silc_hash_table_list(channel->user_list, &htl);
+ silc_client_resume_command_callback(client, conn, SILC_COMMAND_JOIN,
+ channel->channel_name, channel,
+ channel->mode, &htl, channel->topic,
+ cipher, hmac, channel->founder_key,
+ channel->channel_pubkeys,
+ channel->user_limit);
+ silc_hash_table_list_reset(&htl);
+ }
+
+ conn->internal->registering = FALSE;
+ silc_schedule_task_del_by_all(conn->internal->schedule, 0,
+ silc_client_connect_timeout, conn);
+ silc_free(resume->nickname);
+ silc_free(resume);