mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Yeah many calls
This commit is contained in:
parent
736f5f8034
commit
42b25a4d3e
|
@ -1,8 +1,10 @@
|
|||
if BUILD_TESTS
|
||||
|
||||
TESTS = messenger_autotest crypto_test network_test assoc_test onion_test TCP_test tox_test
|
||||
check_PROGRAMS = messenger_autotest crypto_test network_test assoc_test onion_test TCP_test tox_test
|
||||
#TESTS = messenger_autotest crypto_test network_test assoc_test onion_test TCP_test tox_test
|
||||
#check_PROGRAMS = messenger_autotest crypto_test network_test assoc_test onion_test TCP_test tox_test
|
||||
|
||||
TESTS = toxav_basic_test
|
||||
check_PROGRAMS = toxav_basic_test
|
||||
|
||||
AUTOTEST_CFLAGS = \
|
||||
$(LIBSODIUM_CFLAGS) \
|
||||
|
@ -19,58 +21,58 @@ AUTOTEST_LDADD = \
|
|||
|
||||
|
||||
if BUILD_AV
|
||||
TESTS += toxav_basic_test
|
||||
check_PROGRAMS += toxav_basic_test
|
||||
#TESTS += toxav_basic_test
|
||||
#check_PROGRAMS += toxav_basic_test
|
||||
AUTOTEST_LDADD += libtoxav.la
|
||||
endif
|
||||
|
||||
messenger_autotest_SOURCES = ../auto_tests/messenger_test.c
|
||||
#messenger_autotest_SOURCES = ../auto_tests/messenger_test.c
|
||||
|
||||
messenger_autotest_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
#messenger_autotest_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
|
||||
messenger_autotest_LDADD = $(AUTOTEST_LDADD)
|
||||
#messenger_autotest_LDADD = $(AUTOTEST_LDADD)
|
||||
|
||||
|
||||
crypto_test_SOURCES = ../auto_tests/crypto_test.c
|
||||
#crypto_test_SOURCES = ../auto_tests/crypto_test.c
|
||||
|
||||
crypto_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
#crypto_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
|
||||
crypto_test_LDADD = $(AUTOTEST_LDADD)
|
||||
#crypto_test_LDADD = $(AUTOTEST_LDADD)
|
||||
|
||||
|
||||
network_test_SOURCES = ../auto_tests/network_test.c
|
||||
#network_test_SOURCES = ../auto_tests/network_test.c
|
||||
|
||||
network_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
#network_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
|
||||
network_test_LDADD = $(AUTOTEST_LDADD)
|
||||
#network_test_LDADD = $(AUTOTEST_LDADD)
|
||||
|
||||
|
||||
assoc_test_SOURCES = ../auto_tests/assoc_test.c
|
||||
#assoc_test_SOURCES = ../auto_tests/assoc_test.c
|
||||
|
||||
assoc_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
#assoc_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
|
||||
assoc_test_LDADD = $(AUTOTEST_LDADD)
|
||||
#assoc_test_LDADD = $(AUTOTEST_LDADD)
|
||||
|
||||
|
||||
onion_test_SOURCES = ../auto_tests/onion_test.c
|
||||
#onion_test_SOURCES = ../auto_tests/onion_test.c
|
||||
|
||||
onion_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
#onion_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
|
||||
onion_test_LDADD = $(AUTOTEST_LDADD)
|
||||
#onion_test_LDADD = $(AUTOTEST_LDADD)
|
||||
|
||||
|
||||
TCP_test_SOURCES = ../auto_tests/TCP_test.c
|
||||
#TCP_test_SOURCES = ../auto_tests/TCP_test.c
|
||||
|
||||
TCP_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
#TCP_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
|
||||
TCP_test_LDADD = $(AUTOTEST_LDADD)
|
||||
#TCP_test_LDADD = $(AUTOTEST_LDADD)
|
||||
|
||||
|
||||
tox_test_SOURCES = ../auto_tests/tox_test.c
|
||||
#tox_test_SOURCES = ../auto_tests/tox_test.c
|
||||
|
||||
tox_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
#tox_test_CFLAGS = $(AUTOTEST_CFLAGS)
|
||||
|
||||
tox_test_LDADD = $(AUTOTEST_LDADD)
|
||||
#tox_test_LDADD = $(AUTOTEST_LDADD)
|
||||
|
||||
|
||||
if BUILD_AV
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "../toxcore/tox.h"
|
||||
#include "../toxcore/logger.h"
|
||||
#include "../toxav/toxav.h"
|
||||
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
|
||||
|
@ -22,6 +23,7 @@
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
typedef enum _CallStatus {
|
||||
none,
|
||||
InCall,
|
||||
|
@ -36,6 +38,7 @@ typedef struct _Party {
|
|||
CallStatus status;
|
||||
ToxAv *av;
|
||||
time_t *CallStarted;
|
||||
int call_index;
|
||||
} Party;
|
||||
|
||||
typedef struct _Status {
|
||||
|
@ -45,42 +48,41 @@ typedef struct _Status {
|
|||
|
||||
void accept_friend_request(Tox *m, uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata)
|
||||
{
|
||||
if (length == 15 && memcmp("ILIKESMALLTITS", data, 15) == 0) {
|
||||
if (length == 7 && memcmp("gentoo", data, 7) == 0) {
|
||||
tox_add_friend_norequest(m, public_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
void callback_recv_invite ( void *_arg )
|
||||
void callback_recv_invite ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Status *cast = _arg;
|
||||
|
||||
|
||||
/* Bob always receives invite */
|
||||
cast->Bob.status = Ringing;
|
||||
cast->Bob.call_index = call_index;
|
||||
}
|
||||
void callback_recv_ringing ( void *_arg )
|
||||
void callback_recv_ringing ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Status *cast = _arg;
|
||||
|
||||
/* Alice always sends invite */
|
||||
cast->Alice.status = Ringing;
|
||||
}
|
||||
void callback_recv_starting ( void *_arg )
|
||||
void callback_recv_starting ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Status *cast = _arg;
|
||||
|
||||
/* Alice always sends invite */
|
||||
printf("Call started on Alice side...\n");
|
||||
cast->Alice.status = InCall;
|
||||
toxav_prepare_transmission(cast->Alice.av, 1);
|
||||
toxav_prepare_transmission(cast->Alice.av, call_index, 1);
|
||||
}
|
||||
void callback_recv_ending ( void *_arg )
|
||||
void callback_recv_ending ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Status *cast = _arg;
|
||||
|
||||
|
||||
|
||||
if ( cast->Alice.status == Rejected) {
|
||||
printf ( "Call ended for Bob!\n" );
|
||||
cast->Bob.status = Ended;
|
||||
|
@ -90,28 +92,28 @@ void callback_recv_ending ( void *_arg )
|
|||
}
|
||||
}
|
||||
|
||||
void callback_recv_error ( void *_arg )
|
||||
void callback_recv_error ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
ck_assert_msg(0, "AV internal error");
|
||||
}
|
||||
|
||||
void callback_call_started ( void *_arg )
|
||||
void callback_call_started ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Status *cast = _arg;
|
||||
|
||||
/* Alice always sends invite */
|
||||
printf("Call started on Bob side...\n");
|
||||
cast->Bob.status = InCall;
|
||||
toxav_prepare_transmission(cast->Bob.av, 1);
|
||||
toxav_prepare_transmission(cast->Bob.av, call_index, 1);
|
||||
}
|
||||
void callback_call_canceled ( void *_arg )
|
||||
void callback_call_canceled ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Status *cast = _arg;
|
||||
|
||||
printf ( "Call Canceled for Bob!\n" );
|
||||
cast->Bob.status = Cancel;
|
||||
}
|
||||
void callback_call_rejected ( void *_arg )
|
||||
void callback_call_rejected ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Status *cast = _arg;
|
||||
|
||||
|
@ -120,7 +122,7 @@ void callback_call_rejected ( void *_arg )
|
|||
/* If Bob rejects, call is ended for alice and she sends ending */
|
||||
cast->Alice.status = Rejected;
|
||||
}
|
||||
void callback_call_ended ( void *_arg )
|
||||
void callback_call_ended ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Status *cast = _arg;
|
||||
|
||||
|
@ -128,7 +130,7 @@ void callback_call_ended ( void *_arg )
|
|||
cast->Bob.status = Ended;
|
||||
}
|
||||
|
||||
void callback_requ_timeout ( void *_arg )
|
||||
void callback_requ_timeout ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
ck_assert_msg(0, "No answer!");
|
||||
}
|
||||
|
@ -142,9 +144,9 @@ void callback_requ_timeout ( void *_arg )
|
|||
tox_do(bootstrap_node); tox_do(Alice); tox_do(Bob); \
|
||||
switch ( step ) {\
|
||||
case 0: /* Alice */ printf("Alice is calling...\n");\
|
||||
toxav_call(status_control.Alice.av, 0, AliceCallType, 10); step++; break;\
|
||||
toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, AliceCallType, 10); step++; break;\
|
||||
case 1: /* Bob */ if (status_control.Bob.status == Ringing) { printf("Bob answers...\n");\
|
||||
cur_time = time(NULL); toxav_answer(status_control.Bob.av, BobCallType); step++; } break; \
|
||||
cur_time = time(NULL); toxav_answer(status_control.Bob.av, status_control.Bob.call_index, BobCallType); step++; } break; \
|
||||
case 2: /* Rtp transmission */ \
|
||||
if (status_control.Bob.status == InCall && status_control.Alice.status == InCall)
|
||||
|
||||
|
@ -153,7 +155,7 @@ void callback_requ_timeout ( void *_arg )
|
|||
case 3: /* Wait for Both to have status ended */\
|
||||
if (status_control.Alice.status == Ended && status_control.Bob.status == Ended) running = 0; break; } c_sleep(20); } } printf("\n");
|
||||
|
||||
START_TEST(test_AV)
|
||||
START_TEST(test_AV_flows)
|
||||
{
|
||||
long long unsigned int cur_time = time(NULL);
|
||||
Tox *bootstrap_node = tox_new(0);
|
||||
|
@ -166,7 +168,7 @@ START_TEST(test_AV)
|
|||
tox_callback_friend_request(Alice, accept_friend_request, &to_compare);
|
||||
uint8_t address[TOX_FRIEND_ADDRESS_SIZE];
|
||||
tox_get_address(Alice, address);
|
||||
int test = tox_add_friend(Bob, address, (uint8_t *)"ILIKESMALLTITS", 15);
|
||||
int test = tox_add_friend(Bob, address, (uint8_t *)"gentoo", 7);
|
||||
|
||||
ck_assert_msg(test == 0, "Failed to add friend error code: %i", test);
|
||||
|
||||
|
@ -195,8 +197,8 @@ START_TEST(test_AV)
|
|||
muhcaps.video_height = muhcaps.video_width = 128;
|
||||
|
||||
Status status_control = {
|
||||
{none, toxav_new(Alice, &muhcaps), NULL},
|
||||
{none, toxav_new(Bob, &muhcaps), NULL},
|
||||
{none, toxav_new(Alice, &muhcaps, 1), NULL},
|
||||
{none, toxav_new(Bob, &muhcaps, 1), NULL},
|
||||
};
|
||||
|
||||
|
||||
|
@ -235,23 +237,23 @@ START_TEST(test_AV)
|
|||
*/
|
||||
CALL_AND_START_LOOP(TypeAudio, TypeAudio) {
|
||||
/* Both send */
|
||||
toxav_send_audio(status_control.Alice.av, sample_payload, 10);
|
||||
toxav_send_audio(status_control.Bob.av, sample_payload, 10);
|
||||
toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, sample_payload, 10);
|
||||
toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, sample_payload, 10);
|
||||
|
||||
/* Both receive */
|
||||
int16_t storage[10];
|
||||
int recved;
|
||||
|
||||
/* Payload from Alice */
|
||||
recved = toxav_recv_audio(status_control.Alice.av, 10, storage);
|
||||
/* Payload from Bob */
|
||||
recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, 10, storage);
|
||||
|
||||
if ( recved ) {
|
||||
/*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");*/
|
||||
memset(storage, 0, 10);
|
||||
}
|
||||
|
||||
/* Payload from Bob */
|
||||
recved = toxav_recv_audio(status_control.Bob.av, 10, storage);
|
||||
/* Payload from Alice */
|
||||
recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, 10, storage);
|
||||
|
||||
if ( recved ) {
|
||||
/*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");*/
|
||||
|
@ -259,11 +261,11 @@ START_TEST(test_AV)
|
|||
|
||||
if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
|
||||
step++; /* This terminates the loop */
|
||||
toxav_kill_transmission(status_control.Alice.av);
|
||||
toxav_kill_transmission(status_control.Bob.av);
|
||||
toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index);
|
||||
toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index);
|
||||
|
||||
/* Call over Alice hangs up */
|
||||
toxav_hangup(status_control.Alice.av);
|
||||
toxav_hangup(status_control.Alice.av, status_control.Alice.call_index);
|
||||
}
|
||||
}
|
||||
TERMINATE_SCOPE()
|
||||
|
@ -274,10 +276,10 @@ START_TEST(test_AV)
|
|||
*/
|
||||
CALL_AND_START_LOOP(TypeAudio, TypeVideo) {
|
||||
/* Both send */
|
||||
toxav_send_audio(status_control.Alice.av, sample_payload, 10);
|
||||
toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, sample_payload, 10);
|
||||
|
||||
toxav_send_audio(status_control.Bob.av, sample_payload, 10);
|
||||
toxav_send_video(status_control.Bob.av, sample_image);
|
||||
toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, sample_payload, 10);
|
||||
toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image);
|
||||
|
||||
/* Both receive */
|
||||
int16_t storage[10];
|
||||
|
@ -285,7 +287,7 @@ START_TEST(test_AV)
|
|||
int recved;
|
||||
|
||||
/* Payload from Bob */
|
||||
recved = toxav_recv_audio(status_control.Alice.av, 10, storage);
|
||||
recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, 10, storage);
|
||||
|
||||
if ( recved ) {
|
||||
/*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");*/
|
||||
|
@ -293,7 +295,7 @@ START_TEST(test_AV)
|
|||
}
|
||||
|
||||
/* Video payload */
|
||||
toxav_recv_video(status_control.Alice.av, &video_storage);
|
||||
toxav_recv_video(status_control.Alice.av, status_control.Alice.call_index, &video_storage);
|
||||
|
||||
if ( video_storage ) {
|
||||
/*ck_assert_msg( memcmp(video_storage->planes[VPX_PLANE_Y], sample_payload, 10) == 0 ||
|
||||
|
@ -305,7 +307,7 @@ START_TEST(test_AV)
|
|||
|
||||
|
||||
/* Payload from Alice */
|
||||
recved = toxav_recv_audio(status_control.Bob.av, 10, storage);
|
||||
recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, 10, storage);
|
||||
|
||||
if ( recved ) {
|
||||
/*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");*/
|
||||
|
@ -313,11 +315,11 @@ START_TEST(test_AV)
|
|||
|
||||
if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
|
||||
step++; /* This terminates the loop */
|
||||
toxav_kill_transmission(status_control.Alice.av);
|
||||
toxav_kill_transmission(status_control.Bob.av);
|
||||
toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index);
|
||||
toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index);
|
||||
|
||||
/* Call over Alice hangs up */
|
||||
toxav_hangup(status_control.Alice.av);
|
||||
toxav_hangup(status_control.Alice.av, status_control.Alice.call_index);
|
||||
}
|
||||
}
|
||||
TERMINATE_SCOPE()
|
||||
|
@ -328,11 +330,11 @@ START_TEST(test_AV)
|
|||
*/
|
||||
CALL_AND_START_LOOP(TypeVideo, TypeVideo) {
|
||||
/* Both send */
|
||||
toxav_send_audio(status_control.Alice.av, sample_payload, 10);
|
||||
toxav_send_video(status_control.Alice.av, sample_image);
|
||||
toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, sample_payload, 10);
|
||||
toxav_send_video(status_control.Alice.av, status_control.Alice.call_index, sample_image);
|
||||
|
||||
toxav_send_audio(status_control.Bob.av, sample_payload, 10);
|
||||
toxav_send_video(status_control.Bob.av, sample_image);
|
||||
toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, sample_payload, 10);
|
||||
toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image);
|
||||
|
||||
/* Both receive */
|
||||
int16_t storage[10];
|
||||
|
@ -340,7 +342,7 @@ START_TEST(test_AV)
|
|||
int recved;
|
||||
|
||||
/* Payload from Bob */
|
||||
recved = toxav_recv_audio(status_control.Alice.av, 10, storage);
|
||||
recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, 10, storage);
|
||||
|
||||
if ( recved ) {
|
||||
/*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");*/
|
||||
|
@ -348,7 +350,7 @@ START_TEST(test_AV)
|
|||
}
|
||||
|
||||
/* Video payload */
|
||||
toxav_recv_video(status_control.Alice.av, &video_storage);
|
||||
toxav_recv_video(status_control.Alice.av, status_control.Alice.call_index, &video_storage);
|
||||
|
||||
if ( video_storage ) {
|
||||
/*ck_assert_msg( memcmp(video_storage->planes[VPX_PLANE_Y], sample_payload, 10) == 0 ||
|
||||
|
@ -360,14 +362,14 @@ START_TEST(test_AV)
|
|||
|
||||
|
||||
/* Payload from Alice */
|
||||
recved = toxav_recv_audio(status_control.Bob.av, 10, storage);
|
||||
recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, 10, storage);
|
||||
|
||||
if ( recved ) {
|
||||
/*ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");*/
|
||||
}
|
||||
|
||||
/* Video payload */
|
||||
toxav_recv_video(status_control.Bob.av, &video_storage);
|
||||
toxav_recv_video(status_control.Bob.av, status_control.Bob.call_index, &video_storage);
|
||||
|
||||
if ( video_storage ) {
|
||||
/*ck_assert_msg( memcmp(video_storage->planes[VPX_PLANE_Y], sample_payload, 10) == 0 ||
|
||||
|
@ -378,11 +380,11 @@ START_TEST(test_AV)
|
|||
|
||||
if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
|
||||
step++; /* This terminates the loop */
|
||||
toxav_kill_transmission(status_control.Alice.av);
|
||||
toxav_kill_transmission(status_control.Bob.av);
|
||||
toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index);
|
||||
toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index);
|
||||
|
||||
/* Call over Alice hangs up */
|
||||
toxav_hangup(status_control.Alice.av);
|
||||
toxav_hangup(status_control.Alice.av, status_control.Alice.call_index);
|
||||
}
|
||||
}
|
||||
TERMINATE_SCOPE()
|
||||
|
@ -408,7 +410,7 @@ START_TEST(test_AV)
|
|||
switch ( step ) {
|
||||
case 0: /* Alice */
|
||||
printf("Alice is calling...\n");
|
||||
toxav_call(status_control.Alice.av, 0, TypeAudio, 10);
|
||||
toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, TypeAudio, 10);
|
||||
step++;
|
||||
break;
|
||||
\
|
||||
|
@ -416,7 +418,7 @@ START_TEST(test_AV)
|
|||
case 1: /* Bob */
|
||||
if (status_control.Bob.status == Ringing) {
|
||||
printf("Bob rejects...\n");
|
||||
toxav_reject(status_control.Bob.av, "Who likes D's anyway?");
|
||||
toxav_reject(status_control.Bob.av, status_control.Bob.call_index, "Who likes D's anyway?");
|
||||
step++;
|
||||
}
|
||||
|
||||
|
@ -450,7 +452,7 @@ START_TEST(test_AV)
|
|||
switch ( step ) {
|
||||
case 0: /* Alice */
|
||||
printf("Alice is calling...\n");
|
||||
toxav_call(status_control.Alice.av, 0, TypeAudio, 10);
|
||||
toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, TypeAudio, 10);
|
||||
step++;
|
||||
break;
|
||||
\
|
||||
|
@ -458,7 +460,7 @@ START_TEST(test_AV)
|
|||
case 1: /* Alice again */
|
||||
if (status_control.Bob.status == Ringing) {
|
||||
printf("Alice cancels...\n");
|
||||
toxav_cancel(status_control.Alice.av, 0, "Who likes D's anyway?");
|
||||
toxav_cancel(status_control.Alice.av, status_control.Alice.call_index, 0, "Who likes D's anyway?");
|
||||
step++;
|
||||
}
|
||||
|
||||
|
@ -484,20 +486,29 @@ END_TEST
|
|||
/*************************************************************************************************/
|
||||
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
/*************************************************************************************************/
|
||||
|
||||
|
||||
Suite *tox_suite(void)
|
||||
{
|
||||
Suite *s = suite_create("ToxAV");
|
||||
|
||||
TCase *tc_av = tcase_create("A/V");
|
||||
tcase_add_test(tc_av, test_AV);
|
||||
tcase_set_timeout(tc_av, 100); /* Timeout on 100 too much? */
|
||||
suite_add_tcase(s, tc_av);
|
||||
TCase *tc_av_flows = tcase_create("AV_flows");
|
||||
tcase_add_test(tc_av_flows, test_AV_flows);
|
||||
tcase_set_timeout(tc_av_flows, 100); /* Timeout on 100 too much? */
|
||||
suite_add_tcase(s, tc_av_flows);
|
||||
|
||||
TCase *tc_av_three_calls = tcase_create("AV_three_calls");
|
||||
tcase_add_test(tc_av_three_calls, test_AV_three_calls);
|
||||
tcase_set_timeout(tc_av_three_calls, 100); /* Timeout on 100 too much? */
|
||||
suite_add_tcase(s, tc_av_three_calls);
|
||||
|
||||
return s;
|
||||
}
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
{
|
||||
Suite *tox = tox_suite();
|
||||
SRunner *test_runner = srunner_create(tox);
|
||||
|
||||
|
|
120
auto_tests/toxav_many.c
Normal file
120
auto_tests/toxav_many.c
Normal file
|
@ -0,0 +1,120 @@
|
|||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <check.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "../toxcore/tox.h"
|
||||
#include "../toxcore/logger.h"
|
||||
#include "../toxav/toxav.h"
|
||||
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
|
||||
#define c_sleep(x) Sleep(1*x)
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define c_sleep(x) usleep(1000*x)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
typedef enum _CallStatus {
|
||||
none,
|
||||
InCall,
|
||||
Ringing,
|
||||
Ended,
|
||||
Rejected,
|
||||
Cancel
|
||||
|
||||
} CallStatus;
|
||||
|
||||
typedef struct _Party {
|
||||
CallStatus status;
|
||||
ToxAv *av;
|
||||
time_t *CallStarted;
|
||||
int call_index;
|
||||
} Party;
|
||||
|
||||
typedef struct _Status {
|
||||
Party Alice;
|
||||
Party Bob;
|
||||
} Status;
|
||||
|
||||
void accept_friend_request(Tox *m, uint8_t *public_key, uint8_t *data, uint16_t length, void *userdata)
|
||||
{
|
||||
if (length == 7 && memcmp("gentoo", data, 7) == 0) {
|
||||
tox_add_friend_norequest(m, public_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
void callback_recv_invite ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = Ringing;
|
||||
cast->call_index = call_index;
|
||||
}
|
||||
void callback_recv_ringing ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = Ringing;
|
||||
}
|
||||
void callback_recv_starting ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = InCall;
|
||||
toxav_prepare_transmission(cast->av, call_index, 1);
|
||||
}
|
||||
void callback_recv_ending ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = Ended;
|
||||
}
|
||||
|
||||
void callback_recv_error ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
ck_assert_msg(0, "AV internal error");
|
||||
}
|
||||
|
||||
void callback_call_started ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = InCall;
|
||||
toxav_prepare_transmission(cast->av, call_index, 1);
|
||||
}
|
||||
void callback_call_canceled ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = Cancel;
|
||||
}
|
||||
void callback_call_rejected ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = Rejected;
|
||||
}
|
||||
void callback_call_ended ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
Party *cast = _arg;
|
||||
|
||||
cast->status = Ended;
|
||||
}
|
||||
|
||||
void callback_requ_timeout ( uint32_t call_index, void *_arg )
|
||||
{
|
||||
ck_assert_msg(0, "No answer!");
|
||||
}
|
||||
/*************************************************************************************************/
|
52
configure.ac
52
configure.ac
|
@ -34,6 +34,9 @@ BUILD_AV="yes"
|
|||
BUILD_PHONE="no"
|
||||
BUILD_TESTING="yes"
|
||||
|
||||
LOGGING="no"
|
||||
LOGGING_OUTNAM="libtoxcore.log"
|
||||
|
||||
NCURSES_FOUND="no"
|
||||
LIBCONFIG_FOUND="no"
|
||||
LIBCHECK_FOUND="no"
|
||||
|
@ -80,6 +83,55 @@ AC_ARG_ENABLE([randombytes-stir],
|
|||
]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE([logging],
|
||||
[AC_HELP_STRING([--enable-logging], [enable logging (default: auto)]) ],
|
||||
[
|
||||
if test "x$enableval" = "xyes"; then
|
||||
LOGGING="yes"
|
||||
|
||||
AC_DEFINE([LOGGING], [], [If logging enabled])
|
||||
AC_DEFINE([LOGGER_LEVEL], [DEBUG], [LoggerLevel value])
|
||||
AC_DEFINE_UNQUOTED([LOGGER_OUTPUT_FILE], ["$LOGGING_OUTNAM"], [Output of logger])
|
||||
fi
|
||||
]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(logger-level,
|
||||
AC_HELP_STRING([--with-logger-level=LEVEL],
|
||||
[Logger levels: INFO; DEBUG; WARNING; ERROR ]),
|
||||
[
|
||||
if test "x$LOGGING" = "xno"; then
|
||||
AC_MSG_WARN([Logging disabled!])
|
||||
else
|
||||
if test "x$withval" = "xINFO"; then
|
||||
AC_DEFINE([LOGGER_LEVEL], [INFO], [LoggerLevel value])
|
||||
|
||||
elif test "x$withval" = "xDEBUG"; then
|
||||
AC_DEFINE([LOGGER_LEVEL], [DEBUG], [LoggerLevel value])
|
||||
|
||||
elif test "x$withval" = "xWARNING"; then
|
||||
AC_DEFINE([LOGGER_LEVEL], [WARNING], [LoggerLevel value])
|
||||
|
||||
elif test "x$withval" = "xERROR"; then
|
||||
AC_DEFINE([LOGGER_LEVEL], [ERROR], [LoggerLevel value])
|
||||
else
|
||||
AC_MSG_WARN([Invalid logger level: $withval. Using default 'DEBUG'])
|
||||
fi
|
||||
fi
|
||||
]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(logger-path,
|
||||
AC_HELP_STRING([--with-logger-path=DIR],
|
||||
[Path of logger output]),
|
||||
[
|
||||
if test "x$LOGGING" = "xno"; then
|
||||
AC_MSG_WARN([Logging disabled!])
|
||||
else
|
||||
AC_DEFINE_UNQUOTED([LOGGER_OUTPUT_FILE], ["$withval""/""$LOGGING_OUTNAM"], [Output of logger])
|
||||
fi
|
||||
]
|
||||
)
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
|
|
708
toxav/msi.c
708
toxav/msi.c
File diff suppressed because it is too large
Load Diff
66
toxav/msi.h
66
toxav/msi.h
|
@ -33,7 +33,7 @@
|
|||
#define CALL_ID_LEN 12
|
||||
|
||||
|
||||
typedef void ( *MSICallback ) ( void *arg );
|
||||
typedef void ( *MSICallback ) ( uint32_t, void *arg );
|
||||
|
||||
|
||||
/**
|
||||
|
@ -62,32 +62,34 @@ typedef enum {
|
|||
* @brief The call struct.
|
||||
*
|
||||
*/
|
||||
typedef struct _MSICall { /* Call info structure */
|
||||
MSICallState state;
|
||||
typedef struct _MSICall { /* Call info structure */
|
||||
struct _MSISession* session; /* Session pointer */
|
||||
|
||||
MSICallState state;
|
||||
|
||||
MSICallType type_local; /* Type of payload user is ending */
|
||||
MSICallType *type_peer; /* Type of payload others are sending */
|
||||
MSICallType type_local; /* Type of payload user is ending */
|
||||
MSICallType *type_peer; /* Type of payload others are sending */
|
||||
|
||||
uint8_t id[CALL_ID_LEN]; /* Random value identifying the call */
|
||||
uint8_t id[CALL_ID_LEN]; /* Random value identifying the call */
|
||||
|
||||
uint8_t *key_local; /* The key for encryption */
|
||||
uint8_t *key_peer; /* The key for decryption */
|
||||
uint8_t *key_local; /* The key for encryption */
|
||||
uint8_t *key_peer; /* The key for decryption */
|
||||
|
||||
uint8_t *nonce_local; /* Local nonce */
|
||||
uint8_t *nonce_peer; /* Peer nonce */
|
||||
uint8_t *nonce_local; /* Local nonce */
|
||||
uint8_t *nonce_peer; /* Peer nonce */
|
||||
|
||||
int ringing_tout_ms; /* Ringing timeout in ms */
|
||||
int ringing_tout_ms; /* Ringing timeout in ms */
|
||||
|
||||
int request_timer_id; /* Timer id for outgoing request/action */
|
||||
int ringing_timer_id; /* Timer id for ringing timeout */
|
||||
|
||||
pthread_mutex_t mutex; /* It's to be assumed that call will have
|
||||
* seperate thread so add mutex
|
||||
*/
|
||||
uint32_t *peers;
|
||||
uint16_t peer_count;
|
||||
int request_timer_id; /* Timer id for outgoing request/action */
|
||||
int ringing_timer_id; /* Timer id for ringing timeout */
|
||||
|
||||
pthread_mutex_t mutex; /* It's to be assumed that call will have
|
||||
* seperate thread so add mutex
|
||||
*/
|
||||
uint32_t *peers;
|
||||
uint16_t peer_count;
|
||||
|
||||
uint32_t call_idx; /* Index of this call in MSISession */
|
||||
} MSICall;
|
||||
|
||||
|
||||
|
@ -97,8 +99,9 @@ typedef struct _MSICall { /* Call info structure */
|
|||
*/
|
||||
typedef struct _MSISession {
|
||||
|
||||
/* Call handler */
|
||||
struct _MSICall *call;
|
||||
/* Call handlers */
|
||||
struct _MSICall **calls;
|
||||
uint32_t max_calls;
|
||||
|
||||
int last_error_id; /* Determine the last error */
|
||||
const uint8_t *last_error_str;
|
||||
|
@ -151,10 +154,11 @@ void msi_register_callback(MSICallback callback, MSICallbackID id, void* userdat
|
|||
* @brief Start the control session.
|
||||
*
|
||||
* @param messenger Tox* object.
|
||||
* @param max_calls Amount of calls possible
|
||||
* @return MSISession* The created session.
|
||||
* @retval NULL Error occured.
|
||||
*/
|
||||
MSISession *msi_init_session ( Messenger *messenger );
|
||||
MSISession *msi_init_session ( Messenger *messenger, uint32_t max_calls );
|
||||
|
||||
|
||||
/**
|
||||
|
@ -170,62 +174,68 @@ int msi_terminate_session ( MSISession *session );
|
|||
* @brief Send invite request to friend_id.
|
||||
*
|
||||
* @param session Control session.
|
||||
* @param call_index Set to new call index.
|
||||
* @param call_type Type of the call. Audio or Video(both audio and video)
|
||||
* @param rngsec Ringing timeout.
|
||||
* @param friend_id The friend.
|
||||
* @return int
|
||||
*/
|
||||
int msi_invite ( MSISession *session, MSICallType call_type, uint32_t rngsec, uint32_t friend_id );
|
||||
int msi_invite ( MSISession *session, uint32_t* call_index, MSICallType call_type, uint32_t rngsec, uint32_t friend_id );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Hangup active call.
|
||||
*
|
||||
* @param session Control session.
|
||||
* @param call_index To which call is this action handled.
|
||||
* @return int
|
||||
* @retval -1 Error occured.
|
||||
* @retval 0 Success.
|
||||
*/
|
||||
int msi_hangup ( MSISession *session );
|
||||
int msi_hangup ( MSISession *session, uint32_t call_index );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Answer active call request.
|
||||
*
|
||||
* @param session Control session.
|
||||
* @param call_index To which call is this action handled.
|
||||
* @param call_type Answer with Audio or Video(both).
|
||||
* @return int
|
||||
*/
|
||||
int msi_answer ( MSISession *session, MSICallType call_type );
|
||||
int msi_answer ( MSISession *session, uint32_t call_index, MSICallType call_type );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Cancel request.
|
||||
*
|
||||
* @param session Control session.
|
||||
* @param call_index To which call is this action handled.
|
||||
* @param peer To which peer.
|
||||
* @param reason Set optional reason header. Pass NULL if none.
|
||||
* @return int
|
||||
*/
|
||||
int msi_cancel ( MSISession* session, uint32_t peer, const char* reason );
|
||||
int msi_cancel ( MSISession* session, uint32_t call_index, uint32_t peer, const char* reason );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reject request.
|
||||
*
|
||||
* @param session Control session.
|
||||
* @param call_index To which call is this action handled.
|
||||
* @param reason Set optional reason header. Pass NULL if none.
|
||||
* @return int
|
||||
*/
|
||||
int msi_reject ( MSISession *session, const uint8_t *reason );
|
||||
int msi_reject ( MSISession *session, uint32_t call_index, const uint8_t *reason );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Terminate the current call.
|
||||
*
|
||||
* @param session Control session.
|
||||
* @param call_index To which call is this action handled.
|
||||
* @return int
|
||||
*/
|
||||
int msi_stopcall ( MSISession *session );
|
||||
int msi_stopcall ( MSISession *session, uint32_t call_index );
|
||||
|
||||
#endif /* __TOXMSI */
|
||||
|
|
196
toxav/toxav.c
196
toxav/toxav.c
|
@ -29,6 +29,8 @@
|
|||
#include "media.h"
|
||||
#include "msi.h"
|
||||
|
||||
#include "../toxcore/logger.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
@ -43,6 +45,9 @@
|
|||
|
||||
static const uint8_t audio_index = 0, video_index = 1;
|
||||
|
||||
typedef struct _CallRTPSessions {
|
||||
RTPSession *crtps[2]; /* Audio is first and video is second */
|
||||
} CallRTPSessions;
|
||||
|
||||
typedef enum {
|
||||
ts_closing,
|
||||
|
@ -56,13 +61,27 @@ struct _ToxAv {
|
|||
|
||||
MSISession *msi_session; /** Main msi session */
|
||||
|
||||
RTPSession *rtp_sessions[2]; /* Audio is first and video is second */
|
||||
CallRTPSessions* rtp_sessions;
|
||||
|
||||
struct jitter_buffer *j_buf;
|
||||
CodecState *cs;
|
||||
|
||||
uint32_t max_calls;
|
||||
};
|
||||
|
||||
const ToxAvCodecSettings av_DefaultSettings = {
|
||||
1000000,
|
||||
800,
|
||||
600,
|
||||
|
||||
64000,
|
||||
20,
|
||||
48000,
|
||||
1,
|
||||
20
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Start new A/V session. There can only be one session at the time. If you register more
|
||||
* it will result in undefined behaviour.
|
||||
|
@ -74,7 +93,7 @@ struct _ToxAv {
|
|||
* @return ToxAv*
|
||||
* @retval NULL On error.
|
||||
*/
|
||||
ToxAv *toxav_new( Tox* messenger, ToxAvCodecSettings* codec_settings)
|
||||
ToxAv *toxav_new( Tox* messenger, ToxAvCodecSettings* codec_settings, uint32_t max_calls)
|
||||
{
|
||||
ToxAv *av = calloc ( sizeof(ToxAv), 1);
|
||||
|
||||
|
@ -83,12 +102,12 @@ ToxAv *toxav_new( Tox* messenger, ToxAvCodecSettings* codec_settings)
|
|||
|
||||
av->messenger = (Messenger *)messenger;
|
||||
|
||||
av->msi_session = msi_init_session(av->messenger);
|
||||
av->msi_session = msi_init_session(av->messenger, max_calls);
|
||||
av->msi_session->agent_handler = av;
|
||||
|
||||
av->rtp_sessions[0] = av->rtp_sessions [1] = NULL;
|
||||
|
||||
/* NOTE: This should be user defined or? */
|
||||
av->rtp_sessions = calloc(sizeof(RTPSession), max_calls);
|
||||
av->max_calls = max_calls;
|
||||
|
||||
av->j_buf = create_queue(codec_settings->jbuf_capacity);
|
||||
|
||||
av->cs = codec_init_session(codec_settings->audio_bitrate,
|
||||
|
@ -98,7 +117,7 @@ ToxAv *toxav_new( Tox* messenger, ToxAvCodecSettings* codec_settings)
|
|||
codec_settings->video_width,
|
||||
codec_settings->video_height,
|
||||
codec_settings->video_bitrate);
|
||||
|
||||
|
||||
return av;
|
||||
}
|
||||
|
||||
|
@ -111,14 +130,19 @@ ToxAv *toxav_new( Tox* messenger, ToxAvCodecSettings* codec_settings)
|
|||
void toxav_kill ( ToxAv *av )
|
||||
{
|
||||
msi_terminate_session(av->msi_session);
|
||||
|
||||
if ( av->rtp_sessions[audio_index] ) {
|
||||
rtp_terminate_session(av->rtp_sessions[audio_index], av->msi_session->messenger_handle);
|
||||
}
|
||||
|
||||
if ( av->rtp_sessions[video_index] ) {
|
||||
rtp_terminate_session(av->rtp_sessions[video_index], av->msi_session->messenger_handle);
|
||||
|
||||
int i = 0;
|
||||
for (; i < av->max_calls; i ++) {
|
||||
if ( av->rtp_sessions[i].crtps[audio_index] ) {
|
||||
rtp_terminate_session(av->rtp_sessions[i].crtps[audio_index], av->msi_session->messenger_handle);
|
||||
}
|
||||
|
||||
if ( av->rtp_sessions[i].crtps[video_index] ) {
|
||||
rtp_terminate_session(av->rtp_sessions[i].crtps[video_index], av->msi_session->messenger_handle);
|
||||
}
|
||||
}
|
||||
|
||||
free(av->rtp_sessions);
|
||||
|
||||
codec_terminate_session(av->cs);
|
||||
|
||||
|
@ -148,13 +172,9 @@ void toxav_register_callstate_callback ( ToxAVCallback callback, ToxAvCallbackID
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_call (ToxAv *av, int user, ToxAvCallType call_type, int ringing_seconds )
|
||||
int toxav_call (ToxAv* av, uint32_t* call_index, int user, ToxAvCallType call_type, int ringing_seconds )
|
||||
{
|
||||
if ( av->msi_session->call ) {
|
||||
return ErrorAlreadyInCall;
|
||||
}
|
||||
|
||||
return msi_invite(av->msi_session, call_type, ringing_seconds * 1000, user);
|
||||
return msi_invite(av->msi_session, call_index, call_type, ringing_seconds * 1000, user);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -165,17 +185,17 @@ int toxav_call (ToxAv *av, int user, ToxAvCallType call_type, int ringing_second
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_hangup ( ToxAv *av )
|
||||
int toxav_hangup ( ToxAv* av, uint32_t call_index )
|
||||
{
|
||||
if ( !av->msi_session->call ) {
|
||||
if ( !av->msi_session->calls[call_index] ) {
|
||||
return ErrorNoCall;
|
||||
}
|
||||
|
||||
if ( av->msi_session->call->state != call_active ) {
|
||||
if ( av->msi_session->calls[call_index]->state != call_active ) {
|
||||
return ErrorInvalidState;
|
||||
}
|
||||
|
||||
return msi_hangup(av->msi_session);
|
||||
return msi_hangup(av->msi_session, call_index);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -187,17 +207,17 @@ int toxav_hangup ( ToxAv *av )
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_answer ( ToxAv *av, ToxAvCallType call_type )
|
||||
int toxav_answer ( ToxAv* av, uint32_t call_index, ToxAvCallType call_type )
|
||||
{
|
||||
if ( !av->msi_session->call ) {
|
||||
if ( !av->msi_session->calls[call_index] ) {
|
||||
return ErrorNoCall;
|
||||
}
|
||||
|
||||
if ( av->msi_session->call->state != call_starting ) {
|
||||
if ( av->msi_session->calls[call_index]->state != call_starting ) {
|
||||
return ErrorInvalidState;
|
||||
}
|
||||
|
||||
return msi_answer(av->msi_session, call_type);
|
||||
return msi_answer(av->msi_session, call_index, call_type);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -209,17 +229,17 @@ int toxav_answer ( ToxAv *av, ToxAvCallType call_type )
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_reject ( ToxAv *av, const char *reason )
|
||||
int toxav_reject ( ToxAv* av, uint32_t call_index, const char* reason )
|
||||
{
|
||||
if ( !av->msi_session->call ) {
|
||||
if ( !av->msi_session->calls[call_index] ) {
|
||||
return ErrorNoCall;
|
||||
}
|
||||
|
||||
if ( av->msi_session->call->state != call_starting ) {
|
||||
if ( av->msi_session->calls[call_index]->state != call_starting ) {
|
||||
return ErrorInvalidState;
|
||||
}
|
||||
|
||||
return msi_reject(av->msi_session, (const uint8_t *) reason);
|
||||
return msi_reject(av->msi_session, call_index, (const uint8_t *) reason);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,13 +252,13 @@ int toxav_reject ( ToxAv *av, const char *reason )
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_cancel ( ToxAv *av, int peer_id, const char *reason )
|
||||
int toxav_cancel ( ToxAv* av, uint32_t call_index, int peer_id, const char* reason )
|
||||
{
|
||||
if ( !av->msi_session->call ) {
|
||||
if ( !av->msi_session->calls[call_index] ) {
|
||||
return ErrorNoCall;
|
||||
}
|
||||
|
||||
return msi_cancel(av->msi_session, peer_id, reason);
|
||||
return msi_cancel(av->msi_session, call_index, peer_id, reason);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -249,13 +269,13 @@ int toxav_cancel ( ToxAv *av, int peer_id, const char *reason )
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_stop_call ( ToxAv *av )
|
||||
int toxav_stop_call ( ToxAv* av, uint32_t call_index )
|
||||
{
|
||||
if ( !av->msi_session->call ) {
|
||||
if ( !av->msi_session->calls[call_index] ) {
|
||||
return ErrorNoCall;
|
||||
}
|
||||
|
||||
return msi_stopcall(av->msi_session);
|
||||
return msi_stopcall(av->msi_session, call_index);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -266,43 +286,43 @@ int toxav_stop_call ( ToxAv *av )
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_prepare_transmission ( ToxAv* av, int support_video )
|
||||
int toxav_prepare_transmission ( ToxAv* av, uint32_t call_index, int support_video )
|
||||
{
|
||||
assert(av->msi_session);
|
||||
|
||||
if ( !av->msi_session || !av->msi_session->call ) {
|
||||
if ( !av->msi_session || !av->msi_session->calls[call_index] ) {
|
||||
return ErrorNoCall;
|
||||
}
|
||||
|
||||
av->rtp_sessions[audio_index] = rtp_init_session(
|
||||
type_audio,
|
||||
av->messenger,
|
||||
av->msi_session->call->peers[0],
|
||||
av->msi_session->call->key_peer,
|
||||
av->msi_session->call->key_local,
|
||||
av->msi_session->call->nonce_peer,
|
||||
av->msi_session->call->nonce_local
|
||||
);
|
||||
av->rtp_sessions[call_index].crtps[audio_index] =
|
||||
rtp_init_session(
|
||||
type_audio,
|
||||
av->messenger,
|
||||
av->msi_session->calls[call_index]->peers[0],
|
||||
av->msi_session->calls[call_index]->key_peer,
|
||||
av->msi_session->calls[call_index]->key_local,
|
||||
av->msi_session->calls[call_index]->nonce_peer,
|
||||
av->msi_session->calls[call_index]->nonce_local
|
||||
);
|
||||
|
||||
|
||||
if ( !av->rtp_sessions[audio_index] ) {
|
||||
if ( !av->rtp_sessions[call_index].crtps[audio_index] ) {
|
||||
fprintf(stderr, "Error while starting audio RTP session!\n");
|
||||
return ErrorStartingAudioRtp;
|
||||
}
|
||||
|
||||
if ( support_video ) {
|
||||
av->rtp_sessions[video_index] = rtp_init_session (
|
||||
type_video,
|
||||
av->messenger,
|
||||
av->msi_session->call->peers[0],
|
||||
av->msi_session->call->key_peer,
|
||||
av->msi_session->call->key_local,
|
||||
av->msi_session->call->nonce_peer,
|
||||
av->msi_session->call->nonce_local
|
||||
);
|
||||
av->rtp_sessions[call_index].crtps[video_index] =
|
||||
rtp_init_session (
|
||||
type_video,
|
||||
av->messenger,
|
||||
av->msi_session->calls[call_index]->peers[0],
|
||||
av->msi_session->calls[call_index]->key_peer,
|
||||
av->msi_session->calls[call_index]->key_local,
|
||||
av->msi_session->calls[call_index]->nonce_peer,
|
||||
av->msi_session->calls[call_index]->nonce_local
|
||||
);
|
||||
|
||||
|
||||
if ( !av->rtp_sessions[video_index] ) {
|
||||
if ( !av->rtp_sessions[call_index].crtps[video_index] ) {
|
||||
fprintf(stderr, "Error while starting video RTP session!\n");
|
||||
return ErrorStartingVideoRtp;
|
||||
}
|
||||
|
@ -318,20 +338,20 @@ int toxav_prepare_transmission ( ToxAv* av, int support_video )
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_kill_transmission ( ToxAv *av )
|
||||
int toxav_kill_transmission ( ToxAv *av, uint32_t call_index )
|
||||
{
|
||||
if ( av->rtp_sessions[audio_index] && -1 == rtp_terminate_session(av->rtp_sessions[audio_index], av->messenger) ) {
|
||||
if ( av->rtp_sessions[call_index].crtps[audio_index] && -1 == rtp_terminate_session(av->rtp_sessions[call_index].crtps[audio_index], av->messenger) ) {
|
||||
fprintf(stderr, "Error while terminating audio RTP session!\n");
|
||||
return ErrorTerminatingAudioRtp;
|
||||
}
|
||||
|
||||
if ( av->rtp_sessions[video_index] && -1 == rtp_terminate_session(av->rtp_sessions[video_index], av->messenger) ) {
|
||||
if ( av->rtp_sessions[call_index].crtps[video_index] && -1 == rtp_terminate_session(av->rtp_sessions[call_index].crtps[video_index], av->messenger) ) {
|
||||
fprintf(stderr, "Error while terminating video RTP session!\n");
|
||||
return ErrorTerminatingVideoRtp;
|
||||
}
|
||||
|
||||
av->rtp_sessions[audio_index] = NULL;
|
||||
av->rtp_sessions[video_index] = NULL;
|
||||
av->rtp_sessions[call_index].crtps[audio_index] = NULL;
|
||||
av->rtp_sessions[call_index].crtps[video_index] = NULL;
|
||||
|
||||
|
||||
return ErrorNone;
|
||||
|
@ -349,10 +369,10 @@ int toxav_kill_transmission ( ToxAv *av )
|
|||
* @retval 0 Success.
|
||||
* @retval -1 Failure.
|
||||
*/
|
||||
inline__ int toxav_send_rtp_payload ( ToxAv *av, ToxAvCallType type, const uint8_t *payload, uint16_t length )
|
||||
inline__ int toxav_send_rtp_payload ( ToxAv *av, uint32_t call_index, ToxAvCallType type, const uint8_t *payload, uint16_t length )
|
||||
{
|
||||
if ( av->rtp_sessions[type - TypeAudio] )
|
||||
return rtp_send_msg ( av->rtp_sessions[type - TypeAudio], av->msi_session->messenger_handle, payload, length );
|
||||
if ( av->rtp_sessions[call_index].crtps[type - TypeAudio] )
|
||||
return rtp_send_msg ( av->rtp_sessions[call_index].crtps[type - TypeAudio], av->msi_session->messenger_handle, payload, length );
|
||||
else return -1;
|
||||
}
|
||||
|
||||
|
@ -366,18 +386,18 @@ inline__ int toxav_send_rtp_payload ( ToxAv *av, ToxAvCallType type, const uint8
|
|||
* @retval ToxAvError On Error.
|
||||
* @retval >=0 Size of received payload.
|
||||
*/
|
||||
inline__ int toxav_recv_rtp_payload ( ToxAv *av, ToxAvCallType type, uint8_t *dest )
|
||||
inline__ int toxav_recv_rtp_payload ( ToxAv *av, uint32_t call_index, ToxAvCallType type, uint8_t *dest )
|
||||
{
|
||||
if ( !dest ) return ErrorInternal;
|
||||
|
||||
if ( !av->rtp_sessions[type - TypeAudio] ) return ErrorNoRtpSession;
|
||||
if ( !av->rtp_sessions[call_index].crtps[type - TypeAudio] ) return ErrorNoRtpSession;
|
||||
|
||||
RTPMessage *message;
|
||||
|
||||
if ( type == TypeAudio ) {
|
||||
|
||||
do {
|
||||
message = rtp_recv_msg(av->rtp_sessions[audio_index]);
|
||||
message = rtp_recv_msg(av->rtp_sessions[call_index].crtps[audio_index]);
|
||||
|
||||
if (message) {
|
||||
/* push the packet into the queue */
|
||||
|
@ -390,7 +410,7 @@ inline__ int toxav_recv_rtp_payload ( ToxAv *av, ToxAvCallType type, uint8_t *de
|
|||
|
||||
if ( success == 2) return ErrorAudioPacketLost;
|
||||
} else {
|
||||
message = rtp_recv_msg(av->rtp_sessions[video_index]);
|
||||
message = rtp_recv_msg(av->rtp_sessions[call_index].crtps[video_index]);
|
||||
}
|
||||
|
||||
if ( message ) {
|
||||
|
@ -415,7 +435,7 @@ inline__ int toxav_recv_rtp_payload ( ToxAv *av, ToxAvCallType type, uint8_t *de
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On Error.
|
||||
*/
|
||||
inline__ int toxav_recv_video ( ToxAv *av, vpx_image_t **output)
|
||||
inline__ int toxav_recv_video ( ToxAv *av, uint32_t call_index, vpx_image_t **output)
|
||||
{
|
||||
if ( !output ) return ErrorInternal;
|
||||
|
||||
|
@ -424,7 +444,7 @@ inline__ int toxav_recv_video ( ToxAv *av, vpx_image_t **output)
|
|||
int error;
|
||||
|
||||
do {
|
||||
recved_size = toxav_recv_rtp_payload(av, TypeVideo, packet);
|
||||
recved_size = toxav_recv_rtp_payload(av, call_index, TypeVideo, packet);
|
||||
|
||||
if (recved_size > 0 && ( error = vpx_codec_decode(&av->cs->v_decoder, packet, recved_size, NULL, 0) ) != VPX_CODEC_OK)
|
||||
fprintf(stderr, "Error decoding: %s\n", vpx_codec_err_to_string(error));
|
||||
|
@ -450,7 +470,7 @@ inline__ int toxav_recv_video ( ToxAv *av, vpx_image_t **output)
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
inline__ int toxav_send_video ( ToxAv *av, vpx_image_t *input)
|
||||
inline__ int toxav_send_video ( ToxAv *av, uint32_t call_index, vpx_image_t *input)
|
||||
{
|
||||
if (vpx_codec_encode(&av->cs->v_encoder, input, av->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US) != VPX_CODEC_OK) {
|
||||
fprintf(stderr, "Could not encode video frame\n");
|
||||
|
@ -465,7 +485,7 @@ inline__ int toxav_send_video ( ToxAv *av, vpx_image_t *input)
|
|||
|
||||
while ( (pkt = vpx_codec_get_cx_data(&av->cs->v_encoder, &iter)) ) {
|
||||
if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
|
||||
if (toxav_send_rtp_payload(av, TypeVideo, pkt->data.frame.buf, pkt->data.frame.sz) != -1)
|
||||
if (toxav_send_rtp_payload(av, call_index, TypeVideo, pkt->data.frame.buf, pkt->data.frame.sz) != -1)
|
||||
++sent;
|
||||
}
|
||||
}
|
||||
|
@ -488,13 +508,13 @@ inline__ int toxav_send_video ( ToxAv *av, vpx_image_t *input)
|
|||
* @retval >=0 Size of received data in frames/samples.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
inline__ int toxav_recv_audio ( ToxAv *av, int frame_size, int16_t *dest )
|
||||
inline__ int toxav_recv_audio ( ToxAv *av, uint32_t call_index, int frame_size, int16_t *dest )
|
||||
{
|
||||
if ( !dest ) return ErrorInternal;
|
||||
|
||||
uint8_t packet [RTP_PAYLOAD_SIZE];
|
||||
|
||||
int recved_size = toxav_recv_rtp_payload(av, TypeAudio, packet);
|
||||
int recved_size = toxav_recv_rtp_payload(av, call_index, TypeAudio, packet);
|
||||
|
||||
if ( recved_size == ErrorAudioPacketLost ) {
|
||||
return opus_decode(av->cs->audio_decoder, NULL, 0, dest, frame_size, 1);
|
||||
|
@ -516,7 +536,7 @@ inline__ int toxav_recv_audio ( ToxAv *av, int frame_size, int16_t *dest )
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
inline__ int toxav_send_audio ( ToxAv *av, const int16_t *frame, int frame_size)
|
||||
inline__ int toxav_send_audio ( ToxAv *av, uint32_t call_index, const int16_t *frame, int frame_size)
|
||||
{
|
||||
uint8_t temp_data[RTP_PAYLOAD_SIZE];
|
||||
int32_t ret = opus_encode(av->cs->audio_encoder, frame, frame_size, temp_data, sizeof(temp_data));
|
||||
|
@ -524,7 +544,7 @@ inline__ int toxav_send_audio ( ToxAv *av, const int16_t *frame, int frame_size)
|
|||
if (ret <= 0)
|
||||
return ErrorInternal;
|
||||
|
||||
return toxav_send_rtp_payload(av, TypeAudio, temp_data, ret);
|
||||
return toxav_send_rtp_payload(av, call_index, TypeAudio, temp_data, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -536,14 +556,14 @@ inline__ int toxav_send_audio ( ToxAv *av, const int16_t *frame, int frame_size)
|
|||
* @retval ToxAvCallType On success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_get_peer_transmission_type ( ToxAv *av, int peer )
|
||||
int toxav_get_peer_transmission_type ( ToxAv *av, uint32_t call_index, int peer )
|
||||
{
|
||||
assert(av->msi_session);
|
||||
|
||||
if ( peer < 0 || !av->msi_session->call || av->msi_session->call->peer_count <= peer )
|
||||
if ( peer < 0 || !av->msi_session->calls[call_index] || av->msi_session->calls[call_index]->peer_count <= peer )
|
||||
return ErrorInternal;
|
||||
|
||||
return av->msi_session->call->type_peer[peer];
|
||||
return av->msi_session->calls[call_index]->type_peer[peer];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -554,14 +574,14 @@ int toxav_get_peer_transmission_type ( ToxAv *av, int peer )
|
|||
* @return int
|
||||
* @retval ToxAvError No peer id
|
||||
*/
|
||||
int toxav_get_peer_id ( ToxAv* av, int peer )
|
||||
int toxav_get_peer_id ( ToxAv* av, uint32_t call_index, int peer )
|
||||
{
|
||||
assert(av->msi_session);
|
||||
|
||||
if ( peer < 0 || !av->msi_session->call || av->msi_session->call->peer_count <= peer )
|
||||
if ( peer < 0 || !av->msi_session->calls[call_index] || av->msi_session->calls[call_index]->peer_count <= peer )
|
||||
return ErrorInternal;
|
||||
|
||||
return av->msi_session->call->peers[peer];
|
||||
return av->msi_session->calls[call_index]->peers[peer];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
/* vpx_image_t */
|
||||
#include <vpx/vpx_image.h>
|
||||
|
||||
typedef void ( *ToxAVCallback ) ( void *arg );
|
||||
typedef void ( *ToxAVCallback ) ( uint32_t, void *arg );
|
||||
typedef struct _ToxAv ToxAv;
|
||||
|
||||
#ifndef __TOX_DEFINED__
|
||||
|
@ -119,17 +119,7 @@ typedef struct _ToxAvCodecSettings {
|
|||
uint32_t jbuf_capacity; /* Size of jitter buffer */
|
||||
} ToxAvCodecSettings;
|
||||
|
||||
static const ToxAvCodecSettings av_DefaultSettings = {
|
||||
1000000,
|
||||
800,
|
||||
600,
|
||||
|
||||
64000,
|
||||
20,
|
||||
48000,
|
||||
1,
|
||||
20
|
||||
};
|
||||
extern const ToxAvCodecSettings av_DefaultSettings;
|
||||
|
||||
/**
|
||||
* @brief Start new A/V session. There can only be one session at the time. If you register more
|
||||
|
@ -142,7 +132,7 @@ static const ToxAvCodecSettings av_DefaultSettings = {
|
|||
* @return ToxAv*
|
||||
* @retval NULL On error.
|
||||
*/
|
||||
ToxAv *toxav_new(Tox *messenger, ToxAvCodecSettings* codec_settings);
|
||||
ToxAv *toxav_new(Tox *messenger, ToxAvCodecSettings* codec_settings, uint32_t max_calls);
|
||||
|
||||
/**
|
||||
* @brief Remove A/V session.
|
||||
|
@ -172,7 +162,7 @@ void toxav_register_callstate_callback (ToxAVCallback callback, ToxAvCallbackID
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_call(ToxAv *av, int user, ToxAvCallType call_type, int ringing_seconds);
|
||||
int toxav_call(ToxAv *av, uint32_t* call_index, int user, ToxAvCallType call_type, int ringing_seconds);
|
||||
|
||||
/**
|
||||
* @brief Hangup active call.
|
||||
|
@ -182,7 +172,7 @@ int toxav_call(ToxAv *av, int user, ToxAvCallType call_type, int ringing_seconds
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_hangup(ToxAv *av);
|
||||
int toxav_hangup(ToxAv *av, uint32_t call_index);
|
||||
|
||||
/**
|
||||
* @brief Answer incomming call.
|
||||
|
@ -193,7 +183,7 @@ int toxav_hangup(ToxAv *av);
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_answer(ToxAv *av, ToxAvCallType call_type );
|
||||
int toxav_answer(ToxAv *av, uint32_t call_index, ToxAvCallType call_type );
|
||||
|
||||
/**
|
||||
* @brief Reject incomming call.
|
||||
|
@ -204,7 +194,7 @@ int toxav_answer(ToxAv *av, ToxAvCallType call_type );
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_reject(ToxAv *av, const char *reason);
|
||||
int toxav_reject(ToxAv *av, uint32_t call_index, const char *reason);
|
||||
|
||||
/**
|
||||
* @brief Cancel outgoing request.
|
||||
|
@ -216,7 +206,7 @@ int toxav_reject(ToxAv *av, const char *reason);
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_cancel(ToxAv* av, int peer_id, const char* reason);
|
||||
int toxav_cancel(ToxAv* av, uint32_t call_index, int peer_id, const char* reason);
|
||||
|
||||
/**
|
||||
* @brief Terminate transmission. Note that transmission will be terminated without informing remote peer.
|
||||
|
@ -226,7 +216,7 @@ int toxav_cancel(ToxAv* av, int peer_id, const char* reason);
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_stop_call(ToxAv *av);
|
||||
int toxav_stop_call(ToxAv *av, uint32_t call_index);
|
||||
|
||||
/**
|
||||
* @brief Must be call before any RTP transmission occurs.
|
||||
|
@ -237,7 +227,7 @@ int toxav_stop_call(ToxAv *av);
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_prepare_transmission(ToxAv *av, int support_video);
|
||||
int toxav_prepare_transmission(ToxAv* av, uint32_t call_index, int support_video);
|
||||
|
||||
/**
|
||||
* @brief Call this at the end of the transmission.
|
||||
|
@ -247,7 +237,7 @@ int toxav_prepare_transmission(ToxAv *av, int support_video);
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_kill_transmission(ToxAv *av);
|
||||
int toxav_kill_transmission(ToxAv *av, uint32_t call_index);
|
||||
|
||||
/**
|
||||
* @brief Receive decoded video packet.
|
||||
|
@ -258,7 +248,7 @@ int toxav_kill_transmission(ToxAv *av);
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On Error.
|
||||
*/
|
||||
int toxav_recv_video ( ToxAv *av, vpx_image_t **output);
|
||||
int toxav_recv_video ( ToxAv* av, uint32_t call_index, vpx_image_t** output);
|
||||
|
||||
/**
|
||||
* @brief Receive decoded audio frame.
|
||||
|
@ -272,7 +262,7 @@ int toxav_recv_video ( ToxAv *av, vpx_image_t **output);
|
|||
* @retval >=0 Size of received data in frames/samples.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_recv_audio( ToxAv *av, int frame_size, int16_t *dest );
|
||||
int toxav_recv_audio( ToxAv* av, uint32_t call_index, int frame_size, int16_t* dest );
|
||||
|
||||
/**
|
||||
* @brief Encode and send video packet.
|
||||
|
@ -283,7 +273,7 @@ int toxav_recv_audio( ToxAv *av, int frame_size, int16_t *dest );
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_send_video ( ToxAv *av, vpx_image_t *input);
|
||||
int toxav_send_video ( ToxAv* av, uint32_t call_index, vpx_image_t* input);
|
||||
|
||||
/**
|
||||
* @brief Encode and send audio frame.
|
||||
|
@ -296,7 +286,7 @@ int toxav_send_video ( ToxAv *av, vpx_image_t *input);
|
|||
* @retval 0 Success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_send_audio ( ToxAv *av, const int16_t *frame, int frame_size);
|
||||
int toxav_send_audio ( ToxAv* av, uint32_t call_index, const int16_t* frame, int frame_size);
|
||||
|
||||
/**
|
||||
* @brief Get peer transmission type. It can either be audio or video.
|
||||
|
@ -307,7 +297,7 @@ int toxav_send_audio ( ToxAv *av, const int16_t *frame, int frame_size);
|
|||
* @retval ToxAvCallType On success.
|
||||
* @retval ToxAvError On error.
|
||||
*/
|
||||
int toxav_get_peer_transmission_type ( ToxAv *av, int peer );
|
||||
int toxav_get_peer_transmission_type ( ToxAv *av, uint32_t call_index, int peer );
|
||||
|
||||
/**
|
||||
* @brief Get id of peer participating in conversation
|
||||
|
@ -317,7 +307,7 @@ int toxav_get_peer_transmission_type ( ToxAv *av, int peer );
|
|||
* @return int
|
||||
* @retval ToxAvError No peer id
|
||||
*/
|
||||
int toxav_get_peer_id ( ToxAv* av, int peer );
|
||||
int toxav_get_peer_id ( ToxAv* av, uint32_t call_index, int peer );
|
||||
|
||||
/**
|
||||
* @brief Is certain capability supported
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include "DHT.h"
|
||||
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
|
@ -198,18 +200,12 @@ static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t
|
|||
/* Refresh the client timestamp. */
|
||||
if (ip_port.ip.family == AF_INET) {
|
||||
|
||||
#ifdef LOGGING
|
||||
|
||||
if (!ipport_equal(&list[i].assoc4.ip_port, &ip_port)) {
|
||||
size_t x;
|
||||
x = sprintf(logbuffer, "coipil[%u]: switching ipv4 from %s:%u ", i,
|
||||
ip_ntoa(&list[i].assoc4.ip_port.ip), ntohs(list[i].assoc4.ip_port.port));
|
||||
sprintf(logbuffer + x, "to %s:%u\n",
|
||||
ip_ntoa(&ip_port.ip), ntohs(ip_port.port));
|
||||
loglog(logbuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
LOGGER_SCOPE( if (!ipport_equal(&list[i].assoc4.ip_port, &ip_port)) {
|
||||
LOGGER_INFO("coipil[%u]: switching ipv4 from %s:%u to %s:%u", i,
|
||||
ip_ntoa(&list[i].assoc4.ip_port.ip), ntohs(list[i].assoc4.ip_port.port),
|
||||
ip_ntoa(&ip_port.ip), ntohs(ip_port.port));
|
||||
}
|
||||
);
|
||||
|
||||
if (LAN_ip(list[i].assoc4.ip_port.ip) != 0 && LAN_ip(ip_port.ip) == 0)
|
||||
return 1;
|
||||
|
@ -217,19 +213,13 @@ static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t
|
|||
list[i].assoc4.ip_port = ip_port;
|
||||
list[i].assoc4.timestamp = temp_time;
|
||||
} else if (ip_port.ip.family == AF_INET6) {
|
||||
|
||||
#ifdef LOGGING
|
||||
|
||||
if (!ipport_equal(&list[i].assoc6.ip_port, &ip_port)) {
|
||||
size_t x;
|
||||
x = sprintf(logbuffer, "coipil[%u]: switching ipv6 from %s:%u ", i,
|
||||
ip_ntoa(&list[i].assoc6.ip_port.ip), ntohs(list[i].assoc6.ip_port.port));
|
||||
sprintf(logbuffer + x, "to %s:%u\n",
|
||||
ip_ntoa(&ip_port.ip), ntohs(ip_port.port));
|
||||
loglog(logbuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
LOGGER_SCOPE( if (!ipport_equal(&list[i].assoc4.ip_port, &ip_port)) {
|
||||
LOGGER_INFO("coipil[%u]: switching ipv6 from %s:%u to %s:%u", i,
|
||||
ip_ntoa(&list[i].assoc6.ip_port.ip), ntohs(list[i].assoc6.ip_port.port),
|
||||
ip_ntoa(&ip_port.ip), ntohs(ip_port.port));
|
||||
}
|
||||
);
|
||||
|
||||
if (LAN_ip(list[i].assoc6.ip_port.ip) != 0 && LAN_ip(ip_port.ip) == 0)
|
||||
return 1;
|
||||
|
@ -251,10 +241,9 @@ static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t
|
|||
/* Initialize client timestamp. */
|
||||
list[i].assoc4.timestamp = temp_time;
|
||||
memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
|
||||
#ifdef LOGGING
|
||||
sprintf(logbuffer, "coipil[%u]: switching client_id (ipv4) \n", i);
|
||||
loglog(logbuffer);
|
||||
#endif
|
||||
|
||||
LOGGER_DEBUG("coipil[%u]: switching client_id (ipv4)", i);
|
||||
|
||||
/* kill the other address, if it was set */
|
||||
memset(&list[i].assoc6, 0, sizeof(list[i].assoc6));
|
||||
return 1;
|
||||
|
@ -262,10 +251,9 @@ static int client_or_ip_port_in_list(Client_data *list, uint32_t length, uint8_t
|
|||
/* Initialize client timestamp. */
|
||||
list[i].assoc6.timestamp = temp_time;
|
||||
memcpy(list[i].client_id, client_id, CLIENT_ID_SIZE);
|
||||
#ifdef LOGGING
|
||||
sprintf(logbuffer, "coipil[%u]: switching client_id (ipv6) \n", i);
|
||||
loglog(logbuffer);
|
||||
#endif
|
||||
|
||||
LOGGER_DEBUG("coipil[%u]: switching client_id (ipv6)", i);
|
||||
|
||||
/* kill the other address, if it was set */
|
||||
memset(&list[i].assoc4, 0, sizeof(list[i].assoc4));
|
||||
return 1;
|
||||
|
@ -469,18 +457,11 @@ int get_close_nodes(DHT *dht, uint8_t *client_id, Node_format *nodes_list, sa_fa
|
|||
uint8_t num_found = Assoc_get_close_entries(dht->assoc, &request);
|
||||
|
||||
if (!num_found) {
|
||||
#ifdef LOGGING
|
||||
loglog("get_close_nodes(): Assoc_get_close_entries() returned zero nodes.\n");
|
||||
#endif
|
||||
|
||||
LOGGER_DEBUG("get_close_nodes(): Assoc_get_close_entries() returned zero nodes");
|
||||
return get_somewhat_close_nodes(dht, client_id, nodes_list, sa_family, is_LAN, want_good);
|
||||
}
|
||||
|
||||
#ifdef LOGGING
|
||||
sprintf(logbuffer, "get_close_nodes(): Assoc_get_close_entries() returned %i 'direct' and %i 'indirect' nodes.\n",
|
||||
request.count_good, num_found - request.count_good);
|
||||
loglog(logbuffer);
|
||||
#endif
|
||||
|
||||
LOGGER_DEBUG("get_close_nodes(): Assoc_get_close_entries() returned %i 'direct' and %i 'indirect' nodes", request.count_good, num_found - request.count_good);
|
||||
|
||||
uint8_t i, num_returned = 0;
|
||||
|
||||
|
|
|
@ -31,6 +31,8 @@ libtoxcore_la_SOURCES = ../toxcore/DHT.h \
|
|||
../toxcore/assoc.c \
|
||||
../toxcore/onion.h \
|
||||
../toxcore/onion.c \
|
||||
../toxcore/logger.h \
|
||||
../toxcore/logger.c \
|
||||
../toxcore/onion_announce.h \
|
||||
../toxcore/onion_announce.c \
|
||||
../toxcore/onion_client.h \
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "logger.h"
|
||||
#include "Messenger.h"
|
||||
#include "assoc.h"
|
||||
#include "network.h"
|
||||
|
@ -2245,7 +2246,7 @@ void do_messenger(Messenger *m)
|
|||
#ifdef LOGGING
|
||||
|
||||
if (unix_time() > lastdump + DUMPING_CLIENTS_FRIENDS_EVERY_N_SECONDS) {
|
||||
loglog(" = = = = = = = = \n");
|
||||
|
||||
#ifdef ENABLE_ASSOC_DHT
|
||||
Assoc_status(m->dht->assoc);
|
||||
#endif
|
||||
|
@ -2254,12 +2255,10 @@ void do_messenger(Messenger *m)
|
|||
size_t c;
|
||||
|
||||
for (c = 0; c < m->numchats; c++) {
|
||||
loglog("---------------- \n");
|
||||
Assoc_status(m->chats[c]->assoc);
|
||||
}
|
||||
}
|
||||
|
||||
loglog(" = = = = = = = = \n");
|
||||
|
||||
lastdump = unix_time();
|
||||
uint32_t client, last_pinged;
|
||||
|
@ -2276,14 +2275,12 @@ void do_messenger(Messenger *m)
|
|||
if (last_pinged > 999)
|
||||
last_pinged = 999;
|
||||
|
||||
snprintf(logbuffer, sizeof(logbuffer), "C[%2u] %s:%u [%3u] %s\n",
|
||||
client, ip_ntoa(&assoc->ip_port.ip), ntohs(assoc->ip_port.port),
|
||||
last_pinged, ID2String(cptr->client_id));
|
||||
loglog(logbuffer);
|
||||
LOGGER_DEBUG("C[%2u] %s:%u [%3u] %s",
|
||||
client, ip_ntoa(&assoc->ip_port.ip), ntohs(assoc->ip_port.port),
|
||||
last_pinged, ID2String(cptr->client_id));
|
||||
}
|
||||
}
|
||||
|
||||
loglog(" = = = = = = = = \n");
|
||||
|
||||
|
||||
uint32_t friend, dhtfriend;
|
||||
|
||||
|
@ -2311,9 +2308,7 @@ void do_messenger(Messenger *m)
|
|||
dht2m[m2dht[friend]] = friend;
|
||||
|
||||
if (m->numfriends != m->dht->num_friends) {
|
||||
sprintf(logbuffer, "Friend num in DHT %u != friend num in msger %u\n",
|
||||
m->dht->num_friends, m->numfriends);
|
||||
loglog(logbuffer);
|
||||
LOGGER_DEBUG("Friend num in DHT %u != friend num in msger %u\n", m->dht->num_friends, m->numfriends);
|
||||
}
|
||||
|
||||
uint32_t ping_lastrecv;
|
||||
|
@ -2334,14 +2329,11 @@ void do_messenger(Messenger *m)
|
|||
if (ping_lastrecv > 999)
|
||||
ping_lastrecv = 999;
|
||||
|
||||
snprintf(logbuffer, sizeof(logbuffer), "F[%2u:%2u] <%s> %02i [%03u] %s\n",
|
||||
dht2m[friend], friend, msgfptr->name, msgfptr->crypt_connection_id,
|
||||
ping_lastrecv, ID2String(msgfptr->client_id));
|
||||
loglog(logbuffer);
|
||||
LOGGER_DEBUG("F[%2u:%2u] <%s> %02i [%03u] %s",
|
||||
dht2m[friend], friend, msgfptr->name, msgfptr->crypt_connection_id,
|
||||
ping_lastrecv, ID2String(msgfptr->client_id));
|
||||
} else {
|
||||
snprintf(logbuffer, sizeof(logbuffer), "F[--:%2u] %s\n",
|
||||
friend, ID2String(dhtfptr->client_id));
|
||||
loglog(logbuffer);
|
||||
LOGGER_DEBUG("F[--:%2u] %s", friend, ID2String(dhtfptr->client_id));
|
||||
}
|
||||
|
||||
for (client = 0; client < MAX_FRIEND_CLIENTS; client++) {
|
||||
|
@ -2355,20 +2347,16 @@ void do_messenger(Messenger *m)
|
|||
|
||||
if (last_pinged > 999)
|
||||
last_pinged = 999;
|
||||
|
||||
snprintf(logbuffer, sizeof(logbuffer), "F[%2u] => C[%2u] %s:%u [%3u] %s\n",
|
||||
friend, client, ip_ntoa(&assoc->ip_port.ip),
|
||||
ntohs(assoc->ip_port.port), last_pinged,
|
||||
ID2String(cptr->client_id));
|
||||
loglog(logbuffer);
|
||||
|
||||
LOGGER_DEBUG("F[%2u] => C[%2u] %s:%u [%3u] %s",
|
||||
friend, client, ip_ntoa(&assoc->ip_port.ip),
|
||||
ntohs(assoc->ip_port.port), last_pinged,
|
||||
ID2String(cptr->client_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loglog(" = = = = = = = = \n");
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* LOGGING */
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "logger.h"
|
||||
#include "DHT.h"
|
||||
#include "assoc.h"
|
||||
#include "ping.h"
|
||||
|
@ -524,9 +525,7 @@ static void client_id_self_update(Assoc *assoc)
|
|||
assoc->self_hash = id_hash(assoc, assoc->self_client_id);
|
||||
}
|
||||
|
||||
#ifdef LOGGING
|
||||
loglog("assoc: id is now set, purging cache of self-references...\n");
|
||||
#endif
|
||||
LOGGER_DEBUG("id is now set, purging cache of self-references");
|
||||
|
||||
/* if we already added some (or loaded some) entries,
|
||||
* look and remove if we find a match
|
||||
|
@ -821,10 +820,8 @@ Assoc *new_Assoc(size_t bits, size_t entries, uint8_t *public_id)
|
|||
entries_test = prime_upto_min9(entries_test - 1);
|
||||
|
||||
if (entries_test != entries) {
|
||||
#ifdef LOGGING
|
||||
sprintf(logbuffer, "new_Assoc(): trimmed %i to %i.\n", (int)entries, (int)entries_test);
|
||||
loglog(logbuffer);
|
||||
#endif
|
||||
|
||||
LOGGER_DEBUG("trimmed %i to %i.\n", (int)entries, (int)entries_test);
|
||||
entries = (size_t)entries_test;
|
||||
}
|
||||
}
|
||||
|
@ -873,7 +870,7 @@ void Assoc_self_client_id_changed(Assoc *assoc, uint8_t *id)
|
|||
|
||||
#ifdef LOGGING
|
||||
static char *idpart2str(uint8_t *id, size_t len);
|
||||
#endif
|
||||
#endif /* LOGGING */
|
||||
|
||||
/* refresh buckets */
|
||||
void do_Assoc(Assoc *assoc, DHT *dht)
|
||||
|
@ -929,53 +926,30 @@ void do_Assoc(Assoc *assoc, DHT *dht)
|
|||
break;
|
||||
}
|
||||
|
||||
#ifdef LOGGING
|
||||
size_t total = 0, written = sprintf(logbuffer, "assoc: [%u] => ",
|
||||
(uint32_t)(candidate % assoc->candidates_bucket_count));
|
||||
|
||||
if (written > 0)
|
||||
total += written;
|
||||
|
||||
#endif
|
||||
|
||||
if (seen) {
|
||||
IPPTsPng *ippts = seen->seen_family == AF_INET ? &seen->client.assoc4 : &seen->client.assoc6;
|
||||
#ifdef LOGGING
|
||||
written = sprintf(logbuffer + total, " S[%s...] %s:%u", idpart2str(seen->client.client_id, 8),
|
||||
ip_ntoa(&ippts->ip_port.ip), htons(ippts->ip_port.port));
|
||||
|
||||
if (written > 0)
|
||||
total += written;
|
||||
|
||||
#endif
|
||||
|
||||
LOGGER_DEBUG("[%u] => S[%s...] %s:%u", (uint32_t)(candidate % assoc->candidates_bucket_count),
|
||||
idpart2str(seen->client.client_id, 8), ip_ntoa(&ippts->ip_port.ip), htons(ippts->ip_port.port));
|
||||
|
||||
DHT_getnodes(dht, &ippts->ip_port, seen->client.client_id, target_id);
|
||||
seen->getnodes = unix_time();
|
||||
}
|
||||
|
||||
if (heard && (heard != seen)) {
|
||||
IP_Port *ipp = heard->heard_family == AF_INET ? &heard->assoc_heard4 : &heard->assoc_heard6;
|
||||
#ifdef LOGGING
|
||||
written = sprintf(logbuffer + total, " H[%s...] %s:%u", idpart2str(heard->client.client_id, 8), ip_ntoa(&ipp->ip),
|
||||
htons(ipp->port));
|
||||
|
||||
if (written > 0)
|
||||
total += written;
|
||||
|
||||
#endif
|
||||
|
||||
LOGGER_DEBUG("[%u] => H[%s...] %s:%u", (uint32_t)(candidate % assoc->candidates_bucket_count),
|
||||
idpart2str(heard->client.client_id, 8), ip_ntoa(&ipp->ip), htons(ipp->port));
|
||||
|
||||
DHT_getnodes(dht, ipp, heard->client.client_id, target_id);
|
||||
heard->getnodes = unix_time();
|
||||
}
|
||||
|
||||
#ifdef LOGGING
|
||||
|
||||
if (!heard && !seen)
|
||||
sprintf(logbuffer + total, "no nodes to talk to??\n");
|
||||
else
|
||||
/* for arcane reasons, sprintf(str, "\n") doesn't function */
|
||||
sprintf(logbuffer + total, "%s", "\n");
|
||||
|
||||
loglog(logbuffer);
|
||||
#endif
|
||||
|
||||
LOGGER_SCOPE (
|
||||
if ( !heard && !seen )
|
||||
LOGGER_DEBUG("[%u] => no nodes to talk to??", (uint32_t)(candidate % assoc->candidates_bucket_count));
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1009,11 +983,11 @@ static char *idpart2str(uint8_t *id, size_t len)
|
|||
void Assoc_status(Assoc *assoc)
|
||||
{
|
||||
if (!assoc) {
|
||||
loglog("Assoc status: no assoc\n");
|
||||
LOGGER_INFO("Assoc status: no assoc");
|
||||
return;
|
||||
}
|
||||
|
||||
loglog("[b:p] hash => [id...] used, seen, heard\n");
|
||||
|
||||
LOGGER_INFO("[b:p] hash => [id...] used, seen, heard");
|
||||
|
||||
size_t bid, cid, total = 0;
|
||||
|
||||
|
@ -1024,24 +998,23 @@ void Assoc_status(Assoc *assoc)
|
|||
Client_entry *entry = &bucket->list[cid];
|
||||
|
||||
if (entry->hash) {
|
||||
sprintf(logbuffer, "[%3i:%3i] %08x => [%s...] %i, %i(%c), %i(%c)\n",
|
||||
(int)bid, (int)cid, entry->hash, idpart2str(entry->client.client_id, 8),
|
||||
entry->used_at ? (int)(unix_time() - entry->used_at) : 0,
|
||||
entry->seen_at ? (int)(unix_time() - entry->seen_at) : 0,
|
||||
entry->seen_at ? (entry->seen_family == AF_INET ? '4' : (entry->seen_family == AF_INET6 ? '6' : '?')) : '?',
|
||||
total++;
|
||||
|
||||
LOGGER_INFO("[%3i:%3i] %08x => [%s...] %i, %i(%c), %i(%c)\n",
|
||||
(int)bid, (int)cid, entry->hash, idpart2str(entry->client.client_id, 8),
|
||||
entry->used_at ? (int)(unix_time() - entry->used_at) : 0,
|
||||
entry->seen_at ? (int)(unix_time() - entry->seen_at) : 0,
|
||||
entry->seen_at ? (entry->seen_family == AF_INET ? '4' : (entry->seen_family == AF_INET6 ? '6' : '?')) : '?',
|
||||
entry->heard_at ? (int)(unix_time() - entry->heard_at) : 0,
|
||||
entry->heard_at ? (entry->heard_family == AF_INET ? '4' : (entry->heard_family == AF_INET6 ? '6' : '?')) : '?');
|
||||
loglog(logbuffer);
|
||||
total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (total) {
|
||||
sprintf(logbuffer, "Total: %i entries, table usage %i%%.\n", (int)total,
|
||||
(int)(total * 100 / (assoc->candidates_bucket_count * assoc->candidates_bucket_size)));
|
||||
loglog(logbuffer);
|
||||
LOGGER_INFO("Total: %i entries, table usage %i%%.\n", (int)total,
|
||||
(int)(total * 100 / (assoc->candidates_bucket_count * assoc->candidates_bucket_size)));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* LOGGING */
|
||||
|
|
|
@ -98,6 +98,6 @@ void kill_Assoc(Assoc *assoc);
|
|||
|
||||
#ifdef LOGGING
|
||||
void Assoc_status(Assoc *assoc);
|
||||
#endif
|
||||
#endif /* LOGGING */
|
||||
|
||||
#endif /* !__ASSOC_H__ */
|
||||
|
|
159
toxcore/logger.c
Normal file
159
toxcore/logger.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
/* logger.c
|
||||
*
|
||||
* Wrapping logger functions in nice macros
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
*
|
||||
* This file is part of Tox.
|
||||
*
|
||||
* Tox is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#ifdef LOGGING
|
||||
|
||||
#include "network.h" /* for time */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <inttypes.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
|
||||
#define strerror_r(errno,buf,len) strerror_s(buf,len,errno)
|
||||
#endif
|
||||
|
||||
static struct logger_config {
|
||||
FILE* log_file;
|
||||
LoggerLevel level;
|
||||
uint64_t start_time; /* Time when lib loaded */
|
||||
}
|
||||
logger = {
|
||||
NULL,
|
||||
DEBUG,
|
||||
0
|
||||
};
|
||||
|
||||
void __attribute__((destructor)) terminate_logger()
|
||||
{
|
||||
if ( !logger.log_file ) return;
|
||||
|
||||
time_t tim = time(NULL);
|
||||
|
||||
logger_write(ERROR, "============== Closing logger ==============\n"
|
||||
"Time: %s", asctime(localtime(&tim)));
|
||||
|
||||
fclose(logger.log_file);
|
||||
}
|
||||
|
||||
unsigned logger_get_pid()
|
||||
{
|
||||
return
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
|
||||
GetCurrentProcessId();
|
||||
#else
|
||||
getpid();
|
||||
#endif
|
||||
}
|
||||
|
||||
const char* logger_stringify_level(LoggerLevel level)
|
||||
{
|
||||
static const char* strings [] =
|
||||
{
|
||||
"INFO",
|
||||
"DEBUG",
|
||||
"WARNING",
|
||||
"ERROR"
|
||||
};
|
||||
|
||||
return strings[level];
|
||||
}
|
||||
|
||||
|
||||
int logger_init(const char* file_name, LoggerLevel level)
|
||||
{
|
||||
char* final_l = calloc(sizeof(char), strlen(file_name) + 32);
|
||||
sprintf(final_l, "%s"/*.%u"*/, file_name, logger_get_pid());
|
||||
|
||||
if ( logger.log_file ) {
|
||||
fprintf(stderr, "Error opening logger name: %s with level %d: already opened!\n", final_l, level);
|
||||
free (final_l);
|
||||
return -1;
|
||||
}
|
||||
|
||||
logger.log_file = fopen(final_l, "wb");
|
||||
|
||||
if ( logger.log_file == NULL ) {
|
||||
char error[1000];
|
||||
if ( strerror_r(errno, error, 1000) == 0 )
|
||||
fprintf(stderr, "Error opening logger file: %s; info: %s\n", final_l, error);
|
||||
else
|
||||
fprintf(stderr, "Error opening logger file: %s\n", final_l);
|
||||
|
||||
free (final_l);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
logger.level = level;
|
||||
logger.start_time = current_time();
|
||||
|
||||
|
||||
time_t tim = time(NULL);
|
||||
logger_write(ERROR, "============== Starting logger ==============\n"
|
||||
"Time: %s", asctime(localtime(&tim)));
|
||||
|
||||
|
||||
|
||||
free (final_l);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void logger_write (LoggerLevel level, const char* format, ...)
|
||||
{
|
||||
if (logger.log_file == NULL) {
|
||||
/*fprintf(stderr, "Logger file is NULL!\n");*/
|
||||
return;
|
||||
}
|
||||
|
||||
if (logger.level > level) return; /* Don't print some levels xuh */
|
||||
|
||||
va_list _arg;
|
||||
va_start (_arg, format);
|
||||
vfprintf (logger.log_file, format, _arg);
|
||||
va_end (_arg);
|
||||
|
||||
fflush(logger.log_file);
|
||||
}
|
||||
|
||||
char* logger_timestr(char* dest)
|
||||
{
|
||||
uint64_t diff = (current_time() - logger.start_time) / 1000; /* ms */
|
||||
sprintf(dest, "%"PRIu64"", diff);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
#endif /* LOGGING */
|
86
toxcore/logger.h
Normal file
86
toxcore/logger.h
Normal file
|
@ -0,0 +1,86 @@
|
|||
/* logger.h
|
||||
*
|
||||
* Wrapping logger functions in nice macros
|
||||
*
|
||||
* Copyright (C) 2013 Tox project All Rights Reserved.
|
||||
*
|
||||
* This file is part of Tox.
|
||||
*
|
||||
* Tox is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tox is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tox. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __TOXLOGGER
|
||||
#define __TOXLOGGER
|
||||
|
||||
// #define LOGGING
|
||||
|
||||
#ifdef LOGGING
|
||||
#include <string.h>
|
||||
|
||||
typedef enum _LoggerLevel
|
||||
{
|
||||
INFO,
|
||||
DEBUG,
|
||||
WARNING,
|
||||
ERROR
|
||||
} LoggerLevel;
|
||||
|
||||
/*
|
||||
* Set 'level' as the lowest printable level
|
||||
*/
|
||||
int logger_init(const char* file_name, LoggerLevel level);
|
||||
const char* logger_stringify_level(LoggerLevel level);
|
||||
unsigned logger_get_pid();
|
||||
void logger_write (LoggerLevel level, const char* format, ...);
|
||||
char* logger_timestr (char* dest);
|
||||
|
||||
#if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
|
||||
#define _SFILE (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
||||
#else
|
||||
#define _SFILE (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__)
|
||||
#endif
|
||||
|
||||
#define WRITE_FORMAT(__LEVEL__, format) char* the_str = calloc(sizeof(char), strlen(format)+ 500); sprintf(the_str, "[%u] [%s] [%s] [%s:%d %s()] %s\n", \
|
||||
logger_get_pid(), logger_stringify_level(__LEVEL__), logger_timestr(__time__), _SFILE, __LINE__, __func__, format)
|
||||
|
||||
/* Use these macros */
|
||||
|
||||
#define LOGGER_INIT(name, level) logger_init(name, level);
|
||||
#define LOGGER_INFO(format, ...) do { char __time__[20]; WRITE_FORMAT(INFO, format); logger_write( INFO, the_str, ##__VA_ARGS__ ); free(the_str); } while (0)
|
||||
#define LOGGER_DEBUG(format, ...) do { char __time__[20]; WRITE_FORMAT(DEBUG, format); logger_write( DEBUG, the_str, ##__VA_ARGS__ ); free(the_str); } while (0)
|
||||
#define LOGGER_WARNING(format, ...) do { char __time__[20]; WRITE_FORMAT(WARNING, format); logger_write( WARNING, the_str, ##__VA_ARGS__ ); free(the_str); } while (0)
|
||||
#define LOGGER_ERROR(format, ...) do { char __time__[20]; WRITE_FORMAT(ERROR, format); logger_write( ERROR, the_str, ##__VA_ARGS__ ); free(the_str); } while (0)
|
||||
|
||||
/* To do some checks or similar only when logging use this */
|
||||
#define LOGGER_SCOPE(__SCOPE_DO__) do { __SCOPE_DO__ } while(0)
|
||||
|
||||
#else
|
||||
|
||||
|
||||
#define LOGGER_INIT(name, level)
|
||||
#define LOGGER_INFO(format, ...)
|
||||
#define LOGGER_DEBUG(format, ...)
|
||||
#define LOGGER_WARNING(format, ...)
|
||||
#define LOGGER_ERROR(format, ...)
|
||||
|
||||
#define LOGGER_SCOPE(__SCOPE_DO__)
|
||||
|
||||
#endif /* LOGGING */
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* __TOXLOGGER */
|
|
@ -29,6 +29,9 @@
|
|||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#define LOGGING
|
||||
#include "logger.h"
|
||||
|
||||
#if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32)
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
@ -205,9 +208,32 @@ uint64_t random_64b(void)
|
|||
return randnum;
|
||||
}
|
||||
|
||||
#ifdef LOGGING
|
||||
static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *ip_port, ssize_t res);
|
||||
#endif
|
||||
/* In case no logging */
|
||||
#ifndef LOGGING
|
||||
|
||||
#define loglogdata(__message__, __buffer__, __buflen__, __ip_port__, __res__)
|
||||
|
||||
#else
|
||||
|
||||
#define data_0(__buflen__, __buffer__) __buflen__ > 4 ? ntohl(*(uint32_t *)&__buffer__[1]) : 0
|
||||
#define data_1(__buflen__, __buffer__) __buflen__ > 7 ? ntohl(*(uint32_t *)&__buffer__[5]) : 0
|
||||
|
||||
#define loglogdata(__message__, __buffer__, __buflen__, __ip_port__, __res__) \
|
||||
(__ip_port__) .ip; \
|
||||
if (__res__ < 0) /* Windows doesn't necessarily know %zu */ \
|
||||
LOGGER_INFO("[%2u] %s %3hu%c %s:%hu (%u: %s) | %04x%04x", \
|
||||
__buffer__[0], __message__, (__buflen__ < 999 ? (uint16_t)__buflen__ : 999), 'E', \
|
||||
ip_ntoa(&((__ip_port__).ip)), ntohs((__ip_port__).port), errno, strerror(errno), data_0(__buflen__, __buffer__), data_1(__buflen__, __buffer__)); \
|
||||
else if ((__res__ > 0) && ((size_t)__res__ <= __buflen__)) \
|
||||
LOGGER_INFO("[%2u] %s %3zu%c %s:%hu (%u: %s) | %04x%04x", \
|
||||
__buffer__[0], __message__, (__res__ < 999 ? (size_t)__res__ : 999), ((size_t)__res__ < __buflen__ ? '<' : '='), \
|
||||
ip_ntoa(&((__ip_port__).ip)), ntohs((__ip_port__).port), 0, "OK", data_0(__buflen__, __buffer__), data_1(__buflen__, __buffer__)); \
|
||||
else /* empty or overwrite */ \
|
||||
LOGGER_INFO("[%2u] %s %zu%c%zu %s:%hu (%u: %s) | %04x%04x", \
|
||||
__buffer__[0], __message__, (size_t)__res__, (!__res__ ? '!' : '>'), __buflen__, \
|
||||
ip_ntoa(&((__ip_port__).ip)), ntohs((__ip_port__).port), 0, "OK", data_0(__buflen__, __buffer__), data_1(__buflen__, __buffer__));
|
||||
|
||||
#endif /* LOGGING */
|
||||
|
||||
/* Basic network functions:
|
||||
* Function to send packet(data) of length length to ip_port.
|
||||
|
@ -266,9 +292,9 @@ int sendpacket(Networking_Core *net, IP_Port ip_port, uint8_t *data, uint32_t le
|
|||
}
|
||||
|
||||
int res = sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize);
|
||||
#ifdef LOGGING
|
||||
loglogdata("O=>", data, length, &ip_port, res);
|
||||
#endif
|
||||
|
||||
loglogdata("O=>", data, length, ip_port, res);
|
||||
|
||||
|
||||
if ((res >= 0) && ((uint32_t)res == length))
|
||||
net->send_fail_eagain = 0;
|
||||
|
@ -297,14 +323,10 @@ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t
|
|||
int fail_or_len = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen);
|
||||
|
||||
if (fail_or_len <= 0) {
|
||||
#ifdef LOGGING
|
||||
|
||||
if ((fail_or_len < 0) && (errno != EWOULDBLOCK)) {
|
||||
sprintf(logbuffer, "Unexpected error reading from socket: %u, %s\n", errno, strerror(errno));
|
||||
loglog(logbuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
LOGGER_SCOPE( if ((fail_or_len < 0) && (errno != EWOULDBLOCK))
|
||||
LOGGER_ERROR("Unexpected error reading from socket: %u, %s\n", errno, strerror(errno)); );
|
||||
|
||||
return -1; /* Nothing received or empty packet. */
|
||||
}
|
||||
|
||||
|
@ -329,9 +351,7 @@ static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t
|
|||
} else
|
||||
return -1;
|
||||
|
||||
#ifdef LOGGING
|
||||
loglogdata("=>O", data, MAX_UDP_PACKET_SIZE, ip_port, *length);
|
||||
#endif
|
||||
loglogdata("=>O", data, MAX_UDP_PACKET_SIZE, *ip_port, *length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -354,10 +374,7 @@ void networking_poll(Networking_Core *net)
|
|||
if (length < 1) continue;
|
||||
|
||||
if (!(net->packethandlers[data[0]].function)) {
|
||||
#ifdef LOGGING
|
||||
sprintf(logbuffer, "[%02u] -- Packet has no handler.\n", data[0]);
|
||||
loglog(logbuffer);
|
||||
#endif
|
||||
LOGGER_WARNING("[%02u] -- Packet has no handler.\n", data[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -460,22 +477,14 @@ int networking_wait_execute(uint8_t *data, long seconds, long microseconds)
|
|||
timeout.tv_usec = microseconds;
|
||||
}
|
||||
|
||||
#ifdef LOGGING
|
||||
errno = 0;
|
||||
#endif
|
||||
/* returns -1 on error, 0 on timeout, the socket on activity */
|
||||
int res = select(nfds, &readfds, &writefds, &exceptfds, timeout_ptr);
|
||||
#ifdef LOGGING
|
||||
|
||||
/* only dump if not timeout */
|
||||
if (res) {
|
||||
sprintf(logbuffer, "select(%d, %d): %d (%d, %s) - %d %d %d\n", microseconds, seconds, res, errno,
|
||||
strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds),
|
||||
FD_ISSET(s->sock, &exceptfds));
|
||||
loglog(logbuffer);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
LOGGER_SCOPE(
|
||||
if (res) LOGGER_INFO("select(%d, %d): %d (%d, %s) - %d %d %d\n", microseconds, seconds, res, errno,
|
||||
strerror(errno), FD_ISSET(s->sock, &readfds), FD_ISSET(s->sock, &writefds),
|
||||
FD_ISSET(s->sock, &exceptfds));
|
||||
);
|
||||
|
||||
if (FD_ISSET(s->sock, &writefds)) {
|
||||
s->send_fail_reset = 1;
|
||||
|
@ -628,20 +637,12 @@ Networking_Core *new_networking(IP ip, uint16_t port)
|
|||
}
|
||||
|
||||
if (ip.family == AF_INET6) {
|
||||
|
||||
#ifdef LOGGING
|
||||
int is_dualstack =
|
||||
#endif
|
||||
set_socket_dualstack(temp->sock);
|
||||
#ifdef LOGGING
|
||||
|
||||
if (is_dualstack) {
|
||||
loglog("Dual-stack socket: enabled.\n");
|
||||
} else {
|
||||
loglog("Dual-stack socket: Failed to enable, won't be able to receive from/send to IPv4 addresses.\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int is_dualstack =
|
||||
#endif /* LOGGING */
|
||||
set_socket_dualstack(temp->sock);
|
||||
LOGGER_DEBUG( "Dual-stack socket: %s", is_dualstack ? "enabled" : "Failed to enable, won't be able to receive from/send to IPv4 addresses" );
|
||||
/* multicast local nodes */
|
||||
struct ipv6_mreq mreq;
|
||||
memset(&mreq, 0, sizeof(mreq));
|
||||
|
@ -649,21 +650,13 @@ Networking_Core *new_networking(IP ip, uint16_t port)
|
|||
mreq.ipv6mr_multiaddr.s6_addr[ 1] = 0x02;
|
||||
mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01;
|
||||
mreq.ipv6mr_interface = 0;
|
||||
|
||||
#ifdef LOGGING
|
||||
errno = 0;
|
||||
int res =
|
||||
#endif
|
||||
setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq));
|
||||
#ifdef LOGGING
|
||||
|
||||
if (res < 0) {
|
||||
sprintf(logbuffer, "Failed to activate local multicast membership. (%u, %s)\n",
|
||||
errno, strerror(errno));
|
||||
loglog(logbuffer);
|
||||
} else
|
||||
loglog("Local multicast group FF02::1 joined successfully.\n");
|
||||
|
||||
#endif
|
||||
#endif /* LOGGING */
|
||||
setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq));
|
||||
|
||||
LOGGER_DEBUG(res < 0 ? "Failed to activate local multicast membership. (%u, %s)" : "Local multicast group FF02::1 joined successfully", errno, strerror(errno) );
|
||||
}
|
||||
|
||||
/* a hanging program or a different user might block the standard port;
|
||||
|
@ -691,13 +684,9 @@ Networking_Core *new_networking(IP ip, uint16_t port)
|
|||
|
||||
if (!res) {
|
||||
temp->port = *portptr;
|
||||
#ifdef LOGGING
|
||||
loginit(temp->port);
|
||||
|
||||
sprintf(logbuffer, "Bound successfully to %s:%u.\n", ip_ntoa(&ip), ntohs(temp->port));
|
||||
loglog(logbuffer);
|
||||
#endif
|
||||
|
||||
|
||||
LOGGER_DEBUG("Bound successfully to %s:%u", ip_ntoa(&ip), ntohs(temp->port));
|
||||
|
||||
/* errno isn't reset on success, only set on failure, the failed
|
||||
* binds with parallel clients yield a -EPERM to the outside if
|
||||
* errno isn't cleared here */
|
||||
|
@ -1038,31 +1027,3 @@ int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra)
|
|||
|
||||
return 1;
|
||||
};
|
||||
|
||||
#ifdef LOGGING
|
||||
static char errmsg_ok[3] = "OK";
|
||||
static void loglogdata(char *message, uint8_t *buffer, size_t buflen, IP_Port *ip_port, ssize_t res)
|
||||
{
|
||||
uint16_t port = ntohs(ip_port->port);
|
||||
uint32_t data[2];
|
||||
data[0] = buflen > 4 ? ntohl(*(uint32_t *)&buffer[1]) : 0;
|
||||
data[1] = buflen > 7 ? ntohl(*(uint32_t *)&buffer[5]) : 0;
|
||||
|
||||
/* Windows doesn't necessarily know %zu */
|
||||
if (res < 0) {
|
||||
snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3hu%c %s:%hu (%u: %s) | %04x%04x\n",
|
||||
buffer[0], message, (buflen < 999 ? (uint16_t)buflen : 999), 'E',
|
||||
ip_ntoa(&ip_port->ip), port, errno, strerror(errno), data[0], data[1]);
|
||||
} else if ((res > 0) && ((size_t)res <= buflen))
|
||||
snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %3zu%c %s:%hu (%u: %s) | %04x%04x\n",
|
||||
buffer[0], message, (res < 999 ? (size_t)res : 999), ((size_t)res < buflen ? '<' : '='),
|
||||
ip_ntoa(&ip_port->ip), port, 0, errmsg_ok, data[0], data[1]);
|
||||
else /* empty or overwrite */
|
||||
snprintf(logbuffer, sizeof(logbuffer), "[%2u] %s %zu%c%zu %s:%hu (%u: %s) | %04x%04x\n",
|
||||
buffer[0], message, (size_t)res, (!res ? '!' : '>'), buflen,
|
||||
ip_ntoa(&ip_port->ip), port, 0, errmsg_ok, data[0], data[1]);
|
||||
|
||||
logbuffer[sizeof(logbuffer) - 1] = 0;
|
||||
loglog(logbuffer);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#endif
|
||||
|
||||
#include "Messenger.h"
|
||||
#include "logger.h"
|
||||
|
||||
#define __TOX_DEFINED__
|
||||
typedef struct Messenger Tox;
|
||||
|
@ -773,6 +774,7 @@ int tox_isconnected(Tox *tox)
|
|||
*/
|
||||
Tox *tox_new(uint8_t ipv6enabled)
|
||||
{
|
||||
LOGGER_INIT(LOGGER_OUTPUT_FILE, LOGGER_LEVEL);
|
||||
return new_messenger(ipv6enabled);
|
||||
}
|
||||
|
||||
|
|
|
@ -134,87 +134,3 @@ int load_state(load_state_callback_func load_state_callback, void *outer,
|
|||
|
||||
return length == 0 ? 0 : -1;
|
||||
};
|
||||
|
||||
#ifdef LOGGING
|
||||
time_t starttime = 0;
|
||||
size_t logbufferprelen = 0;
|
||||
char *logbufferpredata = NULL;
|
||||
char *logbufferprehead = NULL;
|
||||
char logbuffer[512];
|
||||
static FILE *logfile = NULL;
|
||||
void loginit(uint16_t port)
|
||||
{
|
||||
if (logfile)
|
||||
fclose(logfile);
|
||||
|
||||
if (!starttime) {
|
||||
unix_time_update();
|
||||
starttime = unix_time();
|
||||
}
|
||||
|
||||
struct tm *tm = localtime(&starttime);
|
||||
|
||||
/* "%F %T" might not be Windows compatible */
|
||||
if (strftime(logbuffer + 32, sizeof(logbuffer) - 32, "%F %T", tm))
|
||||
sprintf(logbuffer, "%u-%s.log", ntohs(port), logbuffer + 32);
|
||||
else
|
||||
sprintf(logbuffer, "%u-%lu.log", ntohs(port), starttime);
|
||||
|
||||
logfile = fopen(logbuffer, "w");
|
||||
|
||||
if (logbufferpredata) {
|
||||
if (logfile)
|
||||
fprintf(logfile, "%s", logbufferpredata);
|
||||
|
||||
free(logbufferpredata);
|
||||
logbufferpredata = NULL;
|
||||
}
|
||||
|
||||
};
|
||||
void loglog(char *text)
|
||||
{
|
||||
if (logfile) {
|
||||
fprintf(logfile, "%4u %s", (uint32_t)(unix_time() - starttime), text);
|
||||
fflush(logfile);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* log messages before file was opened: store */
|
||||
|
||||
size_t len = strlen(text);
|
||||
|
||||
if (!starttime) {
|
||||
unix_time_update();
|
||||
starttime = unix_time();
|
||||
|
||||
logbufferprelen = 1024 + len - (len % 1024);
|
||||
logbufferpredata = malloc(logbufferprelen);
|
||||
logbufferprehead = logbufferpredata;
|
||||
}
|
||||
|
||||
/* loginit() called meanwhile? (but failed to open) */
|
||||
if (!logbufferpredata)
|
||||
return;
|
||||
|
||||
if (len + (logbufferprehead - logbufferpredata) + 16U < logbufferprelen) {
|
||||
size_t logpos = logbufferprehead - logbufferpredata;
|
||||
size_t lennew = logbufferprelen * 1.4;
|
||||
logbufferpredata = realloc(logbufferpredata, lennew);
|
||||
logbufferprehead = logbufferpredata + logpos;
|
||||
logbufferprelen = lennew;
|
||||
}
|
||||
|
||||
int written = sprintf(logbufferprehead, "%4u %s", (uint32_t)(unix_time() - starttime), text);
|
||||
logbufferprehead += written;
|
||||
}
|
||||
|
||||
void logexit()
|
||||
{
|
||||
if (logfile) {
|
||||
fclose(logfile);
|
||||
logfile = NULL;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -45,11 +45,4 @@ typedef int (*load_state_callback_func)(void *outer, uint8_t *data, uint32_t len
|
|||
int load_state(load_state_callback_func load_state_callback, void *outer,
|
||||
uint8_t *data, uint32_t length, uint16_t cookie_inner);
|
||||
|
||||
#ifdef LOGGING
|
||||
extern char logbuffer[512];
|
||||
void loginit(uint16_t port);
|
||||
void loglog(char *text);
|
||||
void logexit();
|
||||
#endif
|
||||
|
||||
#endif /* __UTIL_H__ */
|
||||
|
|
Loading…
Reference in New Issue
Block a user