5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2006 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
21 #include "silcclient.h"
22 #include "client_internal.h"
24 /************************** Types and definitions ***************************/
27 /************************ Static utility functions **************************/
30 /****************************** NEW_ID packet *******************************/
32 /* Received new ID packet from server during registering to SILC network */
34 SILC_FSM_STATE(silc_client_new_id)
36 SilcClientConnection conn = fsm_context;
37 SilcClient client = conn->client;
38 SilcPacket packet = state_context;
44 SILC_LOG_DEBUG(("New ID received from server"));
46 if (!silc_id_payload_parse_id(silc_buffer_data(&packet->buffer),
47 silc_buffer_len(&packet->buffer), &id))
50 /* Create local client entry */
51 conn->local_entry = silc_client_add_client(client, conn,
58 if (!conn->local_entry)
62 conn->local_id = &conn->local_entry->id;
63 conn->local_idp = silc_buffer_copy(&packet->buffer);
65 /* Save cache entry */
66 silc_idcache_find_by_id_one(conn->internal->client_cache, conn->local_id,
67 &conn->internal->local_entry);
70 if (packet->src_id_len) {
71 conn->remote_idp = silc_id_payload_encode_data(packet->src_id,
74 if (!conn->remote_idp)
76 silc_id_payload_parse_id(silc_buffer_data(conn->remote_idp),
77 silc_buffer_len(conn->remote_idp),
81 /* Signal connection that new ID was received so it can continue
82 with the registering. */
83 if (conn->internal->registering)
84 silc_fsm_continue_sync(&conn->internal->event_thread);
87 /** Packet processed */
88 silc_packet_free(packet);
89 return SILC_FSM_FINISH;
93 /************************ Register to SILC network **************************/
95 /* Register to network */
97 SILC_FSM_STATE(silc_client_st_register)
99 SilcClientConnection conn = fsm_context;
100 SilcClient client = conn->client;
102 SILC_LOG_DEBUG(("Register to network"));
104 /* Send NEW_CLIENT packet to register to network */
105 if (!silc_packet_send_va(conn->stream, SILC_PACKET_NEW_CLIENT, 0,
106 SILC_STR_UI_SHORT(strlen(client->username)),
107 SILC_STR_DATA(client->username,
108 strlen(client->username)),
109 SILC_STR_UI_SHORT(strlen(client->realname)),
110 SILC_STR_DATA(client->realname,
111 strlen(client->realname)),
113 /** Error sending packet */
114 silc_fsm_next(fsm, silc_client_st_register_error);
115 return SILC_FSM_CONTINUE;
118 /** Wait for new ID */
119 conn->internal->registering = TRUE;
120 silc_fsm_next_later(fsm, silc_client_st_register_complete, 15, 0);
121 return SILC_FSM_WAIT;
124 /* Wait for NEW_ID packet to arrive */
126 SILC_FSM_STATE(silc_client_st_register_complete)
128 SilcClientConnection conn = fsm_context;
129 SilcClient client = conn->client;
131 if (!conn->local_id) {
132 /* Timeout, ID not received */
133 conn->internal->registering = FALSE;
134 silc_fsm_next(fsm, silc_client_st_register_error);
135 return SILC_FSM_CONTINUE;
138 SILC_LOG_DEBUG(("Registered to network"));
140 /* Issue IDENTIFY command for itself to get resolved hostname
141 correctly from server. */
142 silc_client_command_send(client, conn, SILC_COMMAND_IDENTIFY, NULL, NULL,
143 1, 5, silc_buffer_data(conn->local_idp),
144 silc_buffer_len(conn->local_idp));
146 /* Send NICK command if the nickname was set by the application (and is
147 not same as the username). Send this with little timeout. */
148 if (client->nickname &&
149 !silc_utf8_strcasecmp(client->nickname, client->username))
150 silc_client_command_send(client, conn, SILC_COMMAND_NICK, NULL, NULL,
151 1, 1, client->nickname, strlen(client->nickname));
153 /* Issue INFO command to fetch the real server name and server
154 information and other stuff. */
155 silc_client_command_send(client, conn, SILC_COMMAND_INFO, NULL, NULL,
156 1, 2, silc_buffer_data(conn->remote_idp),
157 silc_buffer_len(conn->remote_idp));
159 /* Call connection callback. We are now inside SILC network. */
160 conn->callback(client, conn, SILC_CLIENT_CONN_SUCCESS, 0, NULL,
163 conn->internal->registering = FALSE;
164 return SILC_FSM_FINISH;
167 SILC_FSM_STATE(silc_client_st_register_error)
169 SilcClientConnection conn = fsm_context;
170 SilcClient client = conn->client;
173 /* Close connection */
175 conn->callback(client, conn, SILC_CLIENT_CONN_ERROR, 0, NULL, conn->context);
177 return SILC_FSM_FINISH;
181 /************************* Resume detached session **************************/
183 /* Resume detached session */
185 SILC_FSM_STATE(silc_client_st_resume)
188 return SILC_FSM_FINISH;
191 SILC_FSM_STATE(silc_client_st_resume_new_id)
193 SilcClientConnection conn = fsm_context;
195 return SILC_FSM_FINISH;
198 SILC_FSM_STATE(silc_client_st_resume_error)
201 /* Close connection */
203 return SILC_FSM_FINISH;