diff --git a/auto_tests/tox_test.c b/auto_tests/tox_test.c index d3f9472a..7cae9da6 100644 --- a/auto_tests/tox_test.c +++ b/auto_tests/tox_test.c @@ -202,6 +202,18 @@ void write_file(Tox *tox, uint32_t friendnumber, uint32_t filenumber, uint64_t p } } +unsigned int connected_t1; +void tox_connection_status(Tox *tox, TOX_CONNECTION connection_status, void *user_data) +{ + if (*((uint32_t *)user_data) != 974536) + return; + + if (connected_t1 && !connection_status) + ck_abort_msg("Tox went offline"); + + connected_t1 = connection_status; +} + START_TEST(test_one) { Tox *tox1 = tox_new(0, 0, 0, 0); @@ -286,6 +298,8 @@ START_TEST(test_few_clients) } uint32_t to_compare = 974536; + connected_t1 = 0; + tox_callback_connection_status(tox1, tox_connection_status, &to_compare); tox_callback_friend_request(tox2, accept_friend_request, &to_compare); uint8_t address[TOX_ADDRESS_SIZE]; tox_self_get_address(tox2, address); @@ -299,20 +313,22 @@ START_TEST(test_few_clients) tox_iteration(tox2); tox_iteration(tox3); - if (tox_get_connection_status(tox1) && tox_get_connection_status(tox2) && tox_get_connection_status(tox3) && off) { - printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time); - con_time = time(NULL); - off = 0; + if (tox_get_connection_status(tox1) && tox_get_connection_status(tox2) && tox_get_connection_status(tox3)) { + if (off) { + printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time); + con_time = time(NULL); + off = 0; + } + + if (tox_friend_get_connection_status(tox2, 0, 0) == TOX_CONNECTION_UDP + && tox_friend_get_connection_status(tox3, 0, 0) == TOX_CONNECTION_UDP) + break; } - - if (tox_friend_get_connection_status(tox2, 0, 0) == TOX_CONNECTION_UDP - && tox_friend_get_connection_status(tox3, 0, 0) == TOX_CONNECTION_UDP) - break; - c_sleep(50); } + ck_assert_msg(connected_t1, "Tox1 isn't connected. %u", connected_t1); printf("tox clients connected took %llu seconds\n", time(NULL) - con_time); to_compare = 974536; tox_callback_friend_message(tox3, print_message, &to_compare); diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c index 08b62660..546fe4a8 100644 --- a/toxcore/Messenger.c +++ b/toxcore/Messenger.c @@ -865,6 +865,12 @@ void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, ui m->friend_connectionstatuschange_userdata = userdata; } +void m_callback_core_connection(Messenger *m, void (*function)(Messenger *m, unsigned int, void *), void *userdata) +{ + m->core_connection_change = function; + m->core_connection_change_userdata = userdata; +} + void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, void *), void *userdata) { @@ -2047,7 +2053,17 @@ void do_friends(Messenger *m) } } +static void connection_status_cb(Messenger *m) +{ + unsigned int conn_status = onion_connection_status(m->onion_c); + if (conn_status != m->last_connection_status) { + if (m->core_connection_change) + (*m->core_connection_change)(m, conn_status, m->core_connection_change_userdata); + + m->last_connection_status = conn_status; + } +} #ifdef LOGGING @@ -2112,6 +2128,7 @@ void do_messenger(Messenger *m) do_friend_connections(m->fr_c); do_friends(m); LANdiscovery(m); + connection_status_cb(m); #ifdef LOGGING diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h index 5215f989..ae80760f 100644 --- a/toxcore/Messenger.h +++ b/toxcore/Messenger.h @@ -271,6 +271,10 @@ struct Messenger { void (*lossless_packethandler)(struct Messenger *m, uint32_t, const uint8_t *, size_t, void *); void *lossless_packethandler_userdata; + void (*core_connection_change)(struct Messenger *m, unsigned int, void *); + void *core_connection_change_userdata; + unsigned int last_connection_status; + Messenger_Options options; }; @@ -543,6 +547,11 @@ void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Mess void *userdata); +/* Set the callback for typing changes. + * Function(unsigned int connection_status (0 = not connected, 1 = TCP only, 2 = UDP + TCP)) + */ +void m_callback_core_connection(Messenger *m, void (*function)(Messenger *m, unsigned int, void *), void *userdata); + /**********GROUP CHATS************/ /* Set the callback for group invites. diff --git a/toxcore/onion_client.c b/toxcore/onion_client.c index 3643cb2f..a9fc1643 100644 --- a/toxcore/onion_client.c +++ b/toxcore/onion_client.c @@ -1351,6 +1351,64 @@ static void do_announce(Onion_Client *onion_c) } } +/* return 0 if we are not connected to the network. + * return 1 if we are. + */ +static int onion_isconnected(const Onion_Client *onion_c) +{ + unsigned int i, num = 0, announced = 0; + + if (is_timeout(onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT)) + return 0; + + if (onion_c->path_nodes_index == 0) + return 0; + + for (i = 0; i < MAX_ONION_CLIENTS; ++i) { + if (!is_timeout(onion_c->clients_announce_list[i].timestamp, ONION_NODE_TIMEOUT)) { + ++num; + + if (onion_c->clients_announce_list[i].is_stored) { + ++announced; + } + } + } + + unsigned int pnodes = onion_c->path_nodes_index; + + if (pnodes > MAX_ONION_CLIENTS) { + pnodes = MAX_ONION_CLIENTS; + } + + /* Consider ourselves online if we are announced to half or more nodes + we are connected to */ + if (num && announced) { + if ((num / 2) <= announced && (pnodes / 2) <= num) + return 1; + } + + return 0; +} + +#define ONION_CONNECTION_SECONDS 2 + +/* return 0 if we are not connected to the network. + * return 1 if we are connected with TCP only. + * return 2 if we are also connected with UDP. + */ +unsigned int onion_connection_status(const Onion_Client *onion_c) +{ + if (onion_c->onion_connected >= ONION_CONNECTION_SECONDS) { + if (onion_c->UDP_connected) { + return 2; + } else { + return 1; + } + } + + return 0; +} + void do_onion_client(Onion_Client *onion_c) { unsigned int i; @@ -1363,11 +1421,23 @@ void do_onion_client(Onion_Client *onion_c) do_announce(onion_c); if (onion_isconnected(onion_c)) { + if (onion_c->onion_connected < ONION_CONNECTION_SECONDS * 2) { + ++onion_c->onion_connected; + } + + onion_c->UDP_connected = DHT_non_lan_connected(onion_c->dht); + } else { + populate_path_nodes_tcp(onion_c); + + if (onion_c->onion_connected != 0) { + --onion_c->onion_connected; + } + } + + if (onion_connection_status(onion_c)) { for (i = 0; i < onion_c->num_friends; ++i) { do_friend(onion_c, i); } - } else { - populate_path_nodes_tcp(onion_c); } onion_c->last_run = unix_time(); @@ -1418,42 +1488,3 @@ void kill_onion_client(Onion_Client *onion_c) free(onion_c); } - -/* return 0 if we are not connected to the network. - * return 1 if we are. - */ -int onion_isconnected(const Onion_Client *onion_c) -{ - unsigned int i, num = 0, announced = 0; - - if (is_timeout(onion_c->last_packet_recv, ONION_OFFLINE_TIMEOUT)) - return 0; - - if (onion_c->path_nodes_index == 0) - return 0; - - for (i = 0; i < MAX_ONION_CLIENTS; ++i) { - if (!is_timeout(onion_c->clients_announce_list[i].timestamp, ONION_NODE_TIMEOUT)) { - ++num; - - if (onion_c->clients_announce_list[i].is_stored) { - ++announced; - } - } - } - - unsigned int pnodes = onion_c->path_nodes_index; - - if (pnodes > MAX_ONION_CLIENTS) { - pnodes = MAX_ONION_CLIENTS; - } - - /* Consider ourselves online if we are announced to half or more nodes - we are connected to */ - if (num && announced) { - if ((num / 2) <= announced && (pnodes / 2) <= num) - return 1; - } - - return 0; -} diff --git a/toxcore/onion_client.h b/toxcore/onion_client.h index 6851d929..e10a86c5 100644 --- a/toxcore/onion_client.h +++ b/toxcore/onion_client.h @@ -157,6 +157,9 @@ typedef struct { } Onion_Data_Handlers[256]; uint64_t last_packet_recv; + + unsigned int onion_connected; + _Bool UDP_connected; } Onion_Client; @@ -278,8 +281,9 @@ void kill_onion_client(Onion_Client *onion_c); /* return 0 if we are not connected to the network. - * return 1 if we are. + * return 1 if we are connected with TCP only. + * return 2 if we are also connected with UDP. */ -int onion_isconnected(const Onion_Client *onion_c); +unsigned int onion_connection_status(const Onion_Client *onion_c); #endif diff --git a/toxcore/tox.c b/toxcore/tox.c index 6bb20c81..554414b1 100644 --- a/toxcore/tox.c +++ b/toxcore/tox.c @@ -278,21 +278,22 @@ TOX_CONNECTION tox_get_connection_status(const Tox *tox) { const Messenger *m = tox; - if (onion_isconnected(m->onion_c)) { - if (DHT_non_lan_connected(m->dht)) { - return TOX_CONNECTION_UDP; - } + unsigned int ret = onion_connection_status(m->onion_c); + if (ret == 2) { + return TOX_CONNECTION_UDP; + } else if (ret == 1) { return TOX_CONNECTION_TCP; + } else { + return TOX_CONNECTION_NONE; } - - return TOX_CONNECTION_NONE; } void tox_callback_connection_status(Tox *tox, tox_connection_status_cb *function, void *user_data) { - //TODO + Messenger *m = tox; + m_callback_core_connection(m, function, user_data); } uint32_t tox_iteration_interval(const Tox *tox)