diff --git a/mtproto-client.c b/mtproto-client.c index f96424d..a4b94d9 100644 --- a/mtproto-client.c +++ b/mtproto-client.c @@ -238,6 +238,9 @@ int rpc_send_message (struct connection *c, void *data, int len) { self->total_packets_sent ++; self->total_data_sent += total_len; + + self->queries_num ++; + logprintf("queries_num=%d\n", self->queries_num); return 1; } @@ -1787,6 +1790,7 @@ int tc_becomes_ready (struct connection *c) { break; case st_authorized: auth_work_start (c); + telegram_change_state(c->instance, STATE_AUTHORIZED, NULL); break; default: logprintf ( "c_state = %d\n", c->mtconnection->c_state); @@ -1890,3 +1894,4 @@ void mtproto_close(struct mtproto_connection *c) // stop_ping_timer (c->connection); fd_close_connection(c->connection); } + diff --git a/net.c b/net.c index 20f2dc8..01c88ff 100644 --- a/net.c +++ b/net.c @@ -722,10 +722,11 @@ struct connection *fd_create_connection (struct dc *DC, int fd, S->c = c; DC->sessions[0] = S; } + // add backreference to session + c->session = DC->sessions[0]; // add backreference to used mtproto-connection c->mtconnection = mtp; - return c; } diff --git a/purple-plugin/telegram-purple.c b/purple-plugin/telegram-purple.c index 4cc93cc..5fd923e 100644 --- a/purple-plugin/telegram-purple.c +++ b/purple-plugin/telegram-purple.c @@ -203,18 +203,18 @@ static void tgprpl_on_state_change(struct telegram *instance, int state, void *d do_send_code_result_auth (instance, code, hash, first_name, last_name); break; - case STATE_PHONE_CODE_NOT_ENTERED: - purple_connection_set_state(_gc, PURPLE_CONNECTED); + case STATE_PHONE_CODE_NOT_ENTERED: { + char *hash = data; + const char *code = purple_account_get_string(conn->pa, "verification_key", NULL); + do_send_code_result(instance, code, hash); // TODO: Request SMS code - break; - - case STATE_CLIENT_NOT_REGISTERED: - // ask for registration type + } break; case STATE_CLIENT_CODE_NOT_ENTERED: { + char *hash = data; const char *code = purple_account_get_string(conn->pa, "verification_key", NULL); - const char *hash = purple_account_get_string(conn->pa, "verification_hash", NULL); + //const char *hash = purple_account_get_string(conn->pa, "verification_hash", NULL); do_send_code_result(instance, code, hash); // enter SMS code } @@ -248,7 +248,9 @@ static void tgprpl_on_state_change(struct telegram *instance, int state, void *d // get new messages purple_debug_info(PLUGIN_ID, "Fetching new messages...\n"); do_get_difference(instance); - telegram_flush_queries(instance); + + tgprpl_has_output(instance); + //telegram_flush_queries(instance); break; case STATE_ERROR: { @@ -302,15 +304,12 @@ void tgprpl_login_on_connected(gpointer *data, gint fd, const gchar *error_messa purple_debug_info(PLUGIN_ID, "tgprpl_login_on_connected()\n"); struct telegram *tg = (struct telegram*) data; telegram_conn *conn = tg->extra; - //running_for_first_time(); - if (fd == -1) { logprintf("purple_proxy_connect failed: %s\n", error_message); telegram_free(tg); return; } - purple_debug_info(PLUGIN_ID, "Connecting to the telegram network...\n"); conn->wh = purple_input_add(fd, PURPLE_INPUT_WRITE, tgprpl_output_cb, tg); conn->rh = purple_input_add(fd, PURPLE_INPUT_READ, tgprpl_input_cb, tg); diff --git a/queries.c b/queries.c index 7e01d4e..494b627 100644 --- a/queries.c +++ b/queries.c @@ -140,11 +140,6 @@ void query_restart (long long id) { struct query *send_query (struct dc *DC, int ints, void *data, struct query_methods *methods, void *extra) { logprintf("send_query(...)\n"); - /* - if (!DC->sessions[0]) { - dc_create_session (DC); - } - */ if (verbosity) { logprintf ( "Sending query of size %d to DC (%s:%d)\n", 4 * ints, DC->ip, DC->port); } @@ -173,8 +168,10 @@ struct query *send_query (struct dc *DC, int ints, void *data, struct query_meth insert_event_timer (&q->ev); q->extra = extra; - //queries_num ++; - //logprintf("queries_num: %d\n", queries_num); + + struct mtproto_connection *mtp = DC->sessions[0]->c->mtconnection; + mtp->queries_num ++; + logprintf("queries_num: %d\n", mtp->queries_num); return q; } @@ -211,8 +208,9 @@ void query_error (long long id) { tfree (q->data, q->data_len * 4); tfree (q, sizeof (*q)); } - //queries_num --; - //logprintf("queries_num: %d\n", queries_num); + + mtp->queries_num --; + logprintf("queries_num: %d\n", mtp->queries_num); } #define MAX_PACKED_SIZE (1 << 24) @@ -355,9 +353,7 @@ void fetch_dc_option (struct telegram *instance) { int l2 = prefetch_strlen (mtp); char *ip = fetch_str (mtp, l2); int port = fetch_int (mtp); - if (verbosity) { - logprintf ( "id = %d, name = %.*s ip = %.*s port = %d\n", id, l1, name, l2, ip, port); - } + logprintf ( "id = %d, name = %.*s ip = %.*s port = %d\n", id, l1, name, l2, ip, port); bl_do_dc_option (mtp, id, l1, name, l2, ip, port, instance); } @@ -374,9 +370,7 @@ int help_get_config_on_answer (struct query *q UU) { assert (test_mode == CODE_bool_true || test_mode == CODE_bool_false); assert (test_mode == CODE_bool_false || test_mode == CODE_bool_true); int this_dc = fetch_int (mtp); - if (verbosity) { - logprintf ( "this_dc = %d\n", this_dc); - } + logprintf ( "this_dc = %d\n", this_dc); assert (fetch_int (mtp) == CODE_vector); int n = fetch_int (mtp); assert (n <= 10); @@ -388,10 +382,9 @@ int help_get_config_on_answer (struct query *q UU) { if (op == CODE_config) { max_bcast_size = fetch_int (mtp); } - if (verbosity >= 2) { - logprintf ( "chat_size = %d\n", max_chat_size); - } - telegram_change_state(instance, STATE_CONNECTED, 0); + logprintf ( "max_chat_size = %d\n", max_chat_size); + + telegram_change_state(instance, STATE_CONFIG_RECEIVED, NULL); return 0; } @@ -405,7 +398,8 @@ void do_help_get_config (struct telegram *instance) { clear_packet (mtp); out_int (mtp, CODE_help_get_config); struct dc *DC_working = telegram_get_working_dc(instance); - send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, mtp->packet_buffer, &help_get_config_methods, instance); + send_query (DC_working, mtp->packet_ptr - mtp->packet_buffer, + mtp->packet_buffer, &help_get_config_methods, instance); } /* }}} */ @@ -567,6 +561,18 @@ int check_phone_on_answer (struct query *q UU) { assert (fetch_int (mtp) == (int)CODE_auth_checked_phone); check_phone_result = fetch_bool (mtp); fetch_bool (mtp); + + if (mtp->connection->instance->session_state != STATE_CONFIG_RECEIVED) { + logprintf("check_phone_on_answer(): invalid state: %d\n", mtp->connection->instance->session_state); + telegram_change_state(mtp->connection->instance, STATE_ERROR, NULL); + return -1; + } + logprintf("check_phone_result=%d\n", check_phone_result); + if (check_phone_result) { + telegram_change_state(mtp->connection->instance, STATE_CLIENT_NOT_REGISTERED, NULL); + } else { + telegram_change_state(mtp->connection->instance, STATE_PHONE_NOT_REGISTERED, NULL); + } return 0; } @@ -592,7 +598,7 @@ int check_phone_on_error (struct query *q UU, int error_code, int l, char *error } else { logprintf ( "error_code = %d, error = %.*s\n", error_code, l, error); } - telegram_change_state(instance, STATE_ERROR, error); + telegram_change_state(instance, STATE_DISCONNECTED_SWITCH_DC, error); return 0; } @@ -601,7 +607,7 @@ struct query_methods check_phone_methods = { .on_error = check_phone_on_error }; -int do_auth_check_phone (struct telegram *instance, const char *user) { +void do_auth_check_phone (struct telegram *instance, const char *user) { struct mtproto_connection *mtp = instance->connection; suser = tstrdup (user); @@ -617,7 +623,6 @@ int do_auth_check_phone (struct telegram *instance, const char *user) { send_query (DC_working, packet_ptr - packet_buffer, packet_buffer, &check_phone_methods, instance); net_loop (0, cr_f); */ - return check_phone_result; } /* }}} */ diff --git a/queries.h b/queries.h index 2dca703..2e5917e 100644 --- a/queries.h +++ b/queries.h @@ -103,7 +103,7 @@ void do_load_video (struct telegram *instance, struct video *V, int next); void do_load_document (struct telegram *instance, struct document *V, int next); void do_load_document_thumb (struct telegram *instance, struct document *video, int next); void do_help_get_config (struct telegram *instance); -int do_auth_check_phone (struct telegram *instance, const char *user); +void do_auth_check_phone (struct telegram *instance, const char *user); void do_get_nearest_dc (struct telegram*); void do_send_code_result_auth (struct telegram *instance, const char *code, const char *sms_hash, const char *first_name, const char *last_name); void do_import_auth (struct telegram *instance, int num); diff --git a/structures.c b/structures.c index 1edc1a5..2dd3101 100644 --- a/structures.c +++ b/structures.c @@ -1535,7 +1535,7 @@ static int id_cmp (struct message *M1, struct message *M2) { } struct user *fetch_alloc_user (struct mtproto_connection *mtp) { - logprintf("fetch_alloc_user()\n"); + logprintf("fetch_alloc_user()\n"); int send_event = 0; int data[2]; prefetch_data (mtp, data, 8); diff --git a/telegram.c b/telegram.c index f275b13..30058a3 100755 --- a/telegram.c +++ b/telegram.c @@ -55,8 +55,57 @@ void telegram_change_state(struct telegram *instance, int state, void *data) logprintf("telegram connection state changed to: %d\n", state); instance->session_state = state; GList *curr = instance->change_state_listeners; - while ((curr = g_list_next(change_listeners)) != NULL) { + do { ((state_listener_t)curr->data)(instance, state, data); + } while ((curr = g_list_next(change_listeners)) != NULL); +} + +void on_state_change(struct telegram *instance, int state, void *data) +{ + logprintf("on_state_change: %d\n", state); + switch (state) { + case STATE_ERROR: { + const char* err = data; + logprintf("Telegram errored: %s \n", err); + } + break; + + case STATE_AUTHORIZED: + logprintf("requesting configuration"); + telegram_change_state(instance, STATE_CONFIG_REQUESTED, NULL); + do_help_get_config (instance); + break; + + case STATE_CONFIG_RECEIVED: + logprintf("received network configuration, checking whether phone is registered."); + telegram_store_session(instance); + do_auth_check_phone(instance, instance->login); + break; + + case STATE_PHONE_NOT_REGISTERED: + logprintf("phone is not registered, need to register phone number.\n"); + do_send_code(instance, instance->login); + break; + + case STATE_PHONE_CODE_REQUESTED: + logprintf("phone authenticion, user needs to enter code, first and last name.\n"); + // wait for user input ... + break; + + case STATE_CLIENT_NOT_REGISTERED: + logprintf("phone is already registered, need to register client.\n"); + do_send_code(instance, instance->login); + break; + + case STATE_CLIENT_CODE_NOT_ENTERED: + logprintf("client authentication, user needs to enter code"); + // wait for user input ... + break; + + case STATE_DISCONNECTED_SWITCH_DC: + logprintf("Have to migrate to other DC"); + instance->connection + break; } } @@ -81,6 +130,7 @@ struct telegram *telegram_new(struct dc *DC, const char* login, const char *conf logprintf("%s\n", this->auth_path); logprintf("%s\n", this->state_path); + telegram_add_state_change_listener(this, on_state_change); telegram_change_state(this, STATE_INITIALISED, NULL); return this; } @@ -125,7 +175,6 @@ struct connection *telegram_get_connection(struct telegram *instance) assert(DC); assert(DC->sessions[0]); assert(DC->sessions[0]->c); - //logprintf("get_connection() -> fd: %d\n", DC->sessions[0]->c->fd); return DC->sessions[0]->c; } @@ -171,51 +220,45 @@ char *telegram_get_config(struct telegram *instance, char *config) return g_strdup_printf("%s/%s", instance->config_path, config); } -void on_connected(struct mtproto_connection *c, void* data); +void on_authorized(struct mtproto_connection *c, void* data); + +/** + * Connect to the currently active data center + */ void telegram_network_connect(struct telegram *instance, int fd) { logprintf("telegram_network_connect()\n"); if (!instance->auth.DC_list) { - logprintf("telegram_network_connect(): cannot connect, restore / initialise a session first.\n"); + logprintf("telegram_network_connect(): cannot connect, restore / init a session first.\n"); assert(0); } struct dc *DC_working = telegram_get_working_dc(instance); instance->connection = mtproto_new(DC_working, fd, instance); - instance->connection->on_ready = on_connected; + instance->connection->on_ready = on_authorized; instance->connection->on_ready_data = instance; mtproto_connect(instance->connection); } -void on_connected(struct mtproto_connection *c, void *data) +/** + * Login, and perform a registration when needed + */ +int telegram_login(struct telegram *instance) { - struct telegram *instance = data; - logprintf("Authorized... storing current session.\n"); - telegram_store_session(instance); + if (instance->session_state != STATE_AUTHORIZED) { + logprintf("Cannot log in, invalid state: %d \n", instance->session_state); + return -1; + } + do_help_get_config(instance); + telegram_change_state(instance, STATE_CONFIG_REQUESTED, NULL); + return 0; } -void on_state_change(struct telegram *instance, int state, void *data) +void on_authorized(struct mtproto_connection *c, void *data) { - switch (state) { - case STATE_CONNECTED: - break; - - case STATE_ERROR: { - const char* err = data; - logprintf("Telegram errored: %s \n", err); - } - break; - - case STATE_AUTH_DONE: - logprintf("requesting configuration"); - telegram_change_state(instance, STATE_CONFIG_REQUESTED, NULL); - do_help_get_config (instance); - break; - - case STATE_CONFIG_REQUESTED: - logprintf("switch: config_requested\n"); - telegram_store_session(instance); - break; - } + struct telegram *instance = data; + logprintf("Authorized... storing current session %d.\n", c->connection->session[0]); + telegram_store_session(instance); + telegram_change_state(instance, STATE_AUTHORIZED, NULL); } void telegram_read_input (struct telegram *instance) diff --git a/telegram.h b/telegram.h index 9b4d6e2..30f70ee 100644 --- a/telegram.h +++ b/telegram.h @@ -26,7 +26,7 @@ struct protocol_state; struct authorization_state; /* - * Libtelegram states + * telegram states */ #define STATE_INITIALISED 0 @@ -35,35 +35,35 @@ struct authorization_state; // Error #define STATE_ERROR 2 -// Authentication -#define STATE_PQ_REQUESTED 3 -#define STATE_DH_REQUESTED 4 -#define STATE_CDH_REQUESTED 5 -#define STATE_AUTH_DONE 6 +// intermediate authorization states already present and handled in mtproto-client.c +//#define STATE_PQ_REQUESTED 3 +//#define STATE_DH_REQUESTED 4 +//#define STATE_CDH_REQUESTED 5 +#define STATE_AUTHORIZED 6 + +// dc discovery #define STATE_CONFIG_REQUESTED 7 #define STATE_EXPORTING_CONFIG 8 #define STATE_DISCONNECTED_SWITCH_DC 9 +#define STATE_CONFIG_RECEIVED 11 -// Login -#define STATE_CONNECTED 10 +// login // - Phone Registration -#define STATE_PHONE_IS_REGISTERED_SENT 11 -#define STATE_PHONE_IS_REGISTERED_SENT_2 12 #define STATE_PHONE_NOT_REGISTERED 13 #define STATE_PHONE_CODE_REQUESTED 14 #define STATE_PHONE_CODE_NOT_ENTERED 15 #define STATE_PHONE_CODE_ENTERED 16 // - Client Registration -#define STATE_CLIENT_IS_REGISTERED_SENT 16 -#define STATE_CLIENT_NOT_REGISTERED 17 -#define STATE_CLIENT_CODE_REQUESTED 18 -#define STATE_CLIENT_CODE_NOT_ENTERED 19 -#define STATE_CLIENT_CODE_ENTERED 20 +#define STATE_CLIENT_IS_REGISTERED_SENT 17 +#define STATE_CLIENT_NOT_REGISTERED 18 +#define STATE_CLIENT_CODE_REQUESTED 19 +#define STATE_CLIENT_CODE_NOT_ENTERED 20 +#define STATE_CLIENT_CODE_ENTERED 21 // Ready for sending and receiving messages -#define STATE_READY 21 +#define STATE_READY 22 /** * A telegram session @@ -173,6 +173,8 @@ void telegram_change_state(struct telegram *instance, int state, void *data); */ void telegram_network_connect (struct telegram *instance, int fd); +int telegram_login (struct telegram *instance); + /** * Read the authorization_state stored in the given file */