This commit is contained in:
irungentoo 2014-07-22 11:20:55 -04:00
commit 6ede3e8ad4
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
10 changed files with 762 additions and 846 deletions

5
.gitignore vendored
View File

@ -53,6 +53,11 @@ libtool
.deps .deps
.libs .libs
.dirstamp .dirstamp
build/
#kdevelop
.kdev/
*.kdev*
# Netbeans # Netbeans
nbproject nbproject

View File

@ -31,7 +31,8 @@ typedef enum _CallStatus {
Ringing, Ringing,
Ended, Ended,
Rejected, Rejected,
Cancel Cancel,
TimedOut
} CallStatus; } CallStatus;
@ -59,7 +60,7 @@ void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *dat
/******************************************************************************/ /******************************************************************************/
void callback_recv_invite ( int32_t call_index, void *_arg ) void callback_recv_invite ( void *av, int32_t call_index, void *_arg )
{ {
Status *cast = _arg; Status *cast = _arg;
@ -67,23 +68,23 @@ void callback_recv_invite ( int32_t call_index, void *_arg )
cast->Bob.status = Ringing; cast->Bob.status = Ringing;
cast->Bob.call_index = call_index; cast->Bob.call_index = call_index;
} }
void callback_recv_ringing ( int32_t call_index, void *_arg ) void callback_recv_ringing ( void *av, int32_t call_index, void *_arg )
{ {
Status *cast = _arg; Status *cast = _arg;
/* Alice always sends invite */ /* Alice always sends invite */
cast->Alice.status = Ringing; cast->Alice.status = Ringing;
} }
void callback_recv_starting ( int32_t call_index, void *_arg ) void callback_recv_starting ( void *av, int32_t call_index, void *_arg )
{ {
Status *cast = _arg; Status *cast = _arg;
/* Alice always sends invite */ /* Alice always sends invite */
printf("Call started on Alice side...\n"); printf("Call started on Alice side...\n");
cast->Alice.status = InCall; cast->Alice.status = InCall;
toxav_prepare_transmission(cast->Alice.av, call_index, &muhcaps, 1); toxav_prepare_transmission(av, call_index, &muhcaps, 1);
} }
void callback_recv_ending ( int32_t call_index, void *_arg ) void callback_recv_ending ( void *av, int32_t call_index, void *_arg )
{ {
Status *cast = _arg; Status *cast = _arg;
@ -96,28 +97,24 @@ void callback_recv_ending ( int32_t call_index, void *_arg )
} }
} }
void callback_recv_error ( int32_t call_index, void *_arg )
{
ck_assert_msg(0, "AV internal error");
}
void callback_call_started ( int32_t call_index, void *_arg ) void callback_call_started ( void *av, int32_t call_index, void *_arg )
{ {
Status *cast = _arg; Status *cast = _arg;
/* Alice always sends invite */ /* Alice always sends invite */
printf("Call started on Bob side...\n"); printf("Call started on Bob side...\n");
cast->Bob.status = InCall; cast->Bob.status = InCall;
toxav_prepare_transmission(cast->Bob.av, call_index, &muhcaps, 1); toxav_prepare_transmission(av, call_index, &muhcaps, 1);
} }
void callback_call_canceled ( int32_t call_index, void *_arg ) void callback_call_canceled ( void *av, int32_t call_index, void *_arg )
{ {
Status *cast = _arg; Status *cast = _arg;
printf ( "Call Canceled for Bob!\n" ); printf ( "Call Canceled for Bob!\n" );
cast->Bob.status = Cancel; cast->Bob.status = Cancel;
} }
void callback_call_rejected ( int32_t call_index, void *_arg ) void callback_call_rejected ( void *av, int32_t call_index, void *_arg )
{ {
Status *cast = _arg; Status *cast = _arg;
@ -126,7 +123,7 @@ void callback_call_rejected ( int32_t call_index, void *_arg )
/* If Bob rejects, call is ended for alice and she sends ending */ /* If Bob rejects, call is ended for alice and she sends ending */
cast->Alice.status = Rejected; cast->Alice.status = Rejected;
} }
void callback_call_ended ( int32_t call_index, void *_arg ) void callback_call_ended ( void *av, int32_t call_index, void *_arg )
{ {
Status *cast = _arg; Status *cast = _arg;
@ -134,9 +131,17 @@ void callback_call_ended ( int32_t call_index, void *_arg )
cast->Bob.status = Ended; cast->Bob.status = Ended;
} }
void callback_requ_timeout ( int32_t call_index, void *_arg ) void callback_call_type_change ( void *av, int32_t call_index, void *_arg )
{ {
ck_assert_msg(0, "No answer!"); printf("Call type changed; new type: %s!\n", toxav_get_peer_transmission_type
(av, call_index, 0) == TypeAudio ? "audio" : "video");
}
void callback_requ_timeout ( void *av, int32_t call_index, void *_arg )
{
Status *cast = _arg;
printf("Call timed-out!\n");
cast->Alice.status = TimedOut;
} }
static void callback_audio(ToxAv *av, int32_t call_index, int16_t *data, int length) static void callback_audio(ToxAv *av, int32_t call_index, int16_t *data, int length)
@ -147,10 +152,31 @@ static void callback_video(ToxAv *av, int32_t call_index, vpx_image_t *img)
{ {
} }
void register_callbacks(ToxAv *av, void *data)
{
toxav_register_callstate_callback(av, callback_call_started, av_OnStart, data);
toxav_register_callstate_callback(av, callback_call_canceled, av_OnCancel, data);
toxav_register_callstate_callback(av, callback_call_rejected, av_OnReject, data);
toxav_register_callstate_callback(av, callback_call_ended, av_OnEnd, data);
toxav_register_callstate_callback(av, callback_recv_invite, av_OnInvite, data);
toxav_register_callstate_callback(av, callback_recv_ringing, av_OnRinging, data);
toxav_register_callstate_callback(av, callback_recv_starting, av_OnStarting, data);
toxav_register_callstate_callback(av, callback_recv_ending, av_OnEnding, data);
toxav_register_callstate_callback(av, callback_requ_timeout, av_OnRequestTimeout, data);
toxav_register_callstate_callback(av, callback_call_type_change, av_OnMediaChange, data);
toxav_register_audio_recv_callback(av, callback_audio);
toxav_register_video_recv_callback(av, callback_video);
}
/*************************************************************************************************/ /*************************************************************************************************/
/* Alice calls bob and the call starts. /* Alice calls bob and the call starts.
* What happens in the call is defined after. To quit the loop use: step++; * What happens during the call is defined after. To quit the loop use: step++;
*/ */
#define CALL_AND_START_LOOP(AliceCallType, BobCallType) \ #define CALL_AND_START_LOOP(AliceCallType, BobCallType) \
{ int step = 0, running = 1; while (running) {\ { int step = 0, running = 1; while (running) {\
@ -218,23 +244,8 @@ START_TEST(test_AV_flows)
ck_assert_msg(status_control.Alice.av || status_control.Bob.av, "Failed to create 2 toxav instances"); ck_assert_msg(status_control.Alice.av || status_control.Bob.av, "Failed to create 2 toxav instances");
toxav_register_callstate_callback(callback_call_started, av_OnStart, &status_control); register_callbacks(status_control.Alice.av, &status_control);
toxav_register_callstate_callback(callback_call_canceled, av_OnCancel, &status_control); register_callbacks(status_control.Bob.av, &status_control);
toxav_register_callstate_callback(callback_call_rejected, av_OnReject, &status_control);
toxav_register_callstate_callback(callback_call_ended, av_OnEnd, &status_control);
toxav_register_callstate_callback(callback_recv_invite, av_OnInvite, &status_control);
toxav_register_callstate_callback(callback_recv_ringing, av_OnRinging, &status_control);
toxav_register_callstate_callback(callback_recv_starting, av_OnStarting, &status_control);
toxav_register_callstate_callback(callback_recv_ending, av_OnEnding, &status_control);
toxav_register_callstate_callback(callback_recv_error, av_OnError, &status_control);
toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, &status_control);
toxav_register_audio_recv_callback(status_control.Alice.av, callback_audio);
toxav_register_video_recv_callback(status_control.Alice.av, callback_video);
toxav_register_audio_recv_callback(status_control.Bob.av, callback_audio);
toxav_register_video_recv_callback(status_control.Bob.av, callback_video);
const int frame_size = (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000); const int frame_size = (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000);
int16_t sample_payload[frame_size]; int16_t sample_payload[frame_size];
@ -279,24 +290,6 @@ START_TEST(test_AV_flows)
toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size); toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size);
/* Both receive */
/*int16_t storage[frame_size];
int recved;
/* Payload from Bob */
/*recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage);
if ( recved ) {
//ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");
}
recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage);
if ( recved ) {
//ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");
}*/
if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */ if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
step++; /* This terminates the loop */ step++; /* This terminates the loop */
toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index); toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index);
@ -334,38 +327,6 @@ START_TEST(test_AV_flows)
// toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image); // toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image);
/* Both receive */
int16_t storage[frame_size];
vpx_image_t *video_storage;
int recved;
/* Payload from Bob */
/*recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage);
if ( recved ) {
//ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");
}*/
/* Video payload */
// 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 ||
// memcmp(video_storage->planes[VPX_PLANE_U], sample_payload, 10) == 0 ||
// memcmp(video_storage->planes[VPX_PLANE_V], sample_payload, 10) == 0 , "Payload from Bob is invalid");*/
// vpx_img_free(video_storage);
// }
/* Payload from Alice */
/*recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, storage);
if ( recved ) {
//ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Alice is invalid");
}*/
if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */ if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
step++; /* This terminates the loop */ step++; /* This terminates the loop */
toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index); toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index);
@ -405,48 +366,6 @@ START_TEST(test_AV_flows)
// toxav_send_video(status_control.Alice.av, status_control.Alice.call_index, sample_image); // toxav_send_video(status_control.Alice.av, status_control.Alice.call_index, sample_image);
// toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image); // toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image);
/* Both receive */
int16_t storage[frame_size];
vpx_image_t *video_storage;
int recved;
/* Payload from Bob */
/*recved = toxav_recv_audio(status_control.Alice.av, status_control.Alice.call_index, frame_size, storage);
if ( recved ) {
//ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from Bob is invalid");
}*/
/* Video payload */
// 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 ||
// memcmp(video_storage->planes[VPX_PLANE_U], sample_payload, 10) == 0 ||
// memcmp(video_storage->planes[VPX_PLANE_V], sample_payload, 10) == 0 , "Payload from Bob is invalid");*/
// vpx_img_free(video_storage);
// }
/* Payload from Alice */
/*recved = toxav_recv_audio(status_control.Bob.av, status_control.Bob.call_index, frame_size, 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, status_control.Bob.call_index, &video_storage);
//
// if ( video_storage ) {
// /*ck_assert_msg( memcmp(video_storage->planes[VPX_PLANE_Y], sample_payload, 10) == 0 ||
// memcmp(video_storage->planes[VPX_PLANE_U], sample_payload, 10) == 0 ||
// memcmp(video_storage->planes[VPX_PLANE_V], sample_payload, 10) == 0 , "Payload from Alice is invalid");*/
// vpx_img_free(video_storage);
// }
if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */ if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
step++; /* This terminates the loop */ step++; /* This terminates the loop */
@ -460,6 +379,47 @@ START_TEST(test_AV_flows)
TERMINATE_SCOPE() TERMINATE_SCOPE()
uint64_t times_they_are_a_changin = time(NULL);
/* Media change */
CALL_AND_START_LOOP(TypeAudio, TypeAudio) {
/* Both send */
payload_size = toxav_prepare_audio_frame(status_control.Alice.av, status_control.Alice.call_index, prepared_payload,
1000, sample_payload, frame_size);
if ( payload_size < 0 ) {
ck_assert_msg ( 0, "Failed to encode payload" );
}
toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, payload_size);
payload_size = toxav_prepare_audio_frame(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, 1000,
sample_payload, frame_size);
if ( payload_size < 0 ) {
ck_assert_msg ( 0, "Failed to encode payload" );
}
toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size);
/* Wait 2 seconds and change transmission type */
if (time(NULL) - times_they_are_a_changin > 2) {
times_they_are_a_changin = time(NULL);
toxav_change_type(status_control.Alice.av, status_control.Alice.call_index,
toxav_get_peer_transmission_type(status_control.Bob.av, status_control.Bob.call_index, 0)
== TypeAudio ? TypeVideo : TypeAudio);
}
if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
step++; /* This terminates the loop */
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, status_control.Alice.call_index);
}
}
TERMINATE_SCOPE()
/************************************************************************************************* /*************************************************************************************************
* Other flows * Other flows
@ -524,7 +484,7 @@ START_TEST(test_AV_flows)
toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, TypeAudio, 10); toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, TypeAudio, 10);
step++; step++;
break; break;
\
case 1: /* Alice again */ case 1: /* Alice again */
if (status_control.Bob.status == Ringing) { if (status_control.Bob.status == Ringing) {
@ -547,6 +507,39 @@ START_TEST(test_AV_flows)
printf("\n"); printf("\n");
} }
/*
* Timeout
*/
{
int step = 0;
int running = 1;
while (running) {
tox_do(bootstrap_node);
tox_do(Alice);
tox_do(Bob);
switch ( step ) {
case 0:
printf("Alice is calling...\n");
toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, TypeAudio, 10);
step++;
break;
case 1:
if (status_control.Alice.status == TimedOut) running = 0;
break;
}
c_sleep(20);
}
printf("\n");
}
printf("Calls ended!\n"); printf("Calls ended!\n");
} }

View File

@ -44,6 +44,7 @@ typedef struct _Party {
typedef struct _ACall { typedef struct _ACall {
pthread_t tid; pthread_t tid;
int idx;
Party Caller; Party Caller;
Party Callee; Party Callee;
@ -53,6 +54,8 @@ typedef struct _Status {
ACall calls[3]; /* Make 3 calls for this test */ ACall calls[3]; /* Make 3 calls for this test */
} Status; } Status;
Status status_control;
void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata) void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, uint16_t length, void *userdata)
{ {
if (length == 7 && memcmp("gentoo", data, 7) == 0) { if (length == 7 && memcmp("gentoo", data, 7) == 0) {
@ -62,58 +65,49 @@ void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *dat
/******************************************************************************/ /******************************************************************************/
void callback_recv_invite ( int32_t call_index, void *_arg ) void callback_recv_invite ( void *av, int32_t call_index, void *_arg )
{ {
/* /*
Status *cast = _arg; Status *cast = _arg;
cast->calls[call_index].Callee.status = Ringing;*/ cast->calls[call_index].Callee.status = Ringing;*/
} }
void callback_recv_ringing ( int32_t call_index, void *_arg ) void callback_recv_ringing ( void *av, int32_t call_index, void *_arg )
{ {
Status *cast = _arg; Status *cast = _arg;
cast->calls[call_index].Caller.status = Ringing; cast->calls[call_index].Caller.status = Ringing;
} }
void callback_recv_starting ( int32_t call_index, void *_arg ) void callback_recv_starting ( void *av, int32_t call_index, void *_arg )
{ {
Status *cast = _arg; Status *cast = _arg;
cast->calls[call_index].Caller.status = InCall; cast->calls[call_index].Caller.status = InCall;
} }
void callback_recv_ending ( int32_t call_index, void *_arg ) void callback_recv_ending ( void *av, int32_t call_index, void *_arg )
{ {
Status *cast = _arg; Status *cast = _arg;
cast->calls[call_index].Caller.status = Ended; cast->calls[call_index].Caller.status = Ended;
} }
void callback_recv_error ( int32_t call_index, void *_arg ) void callback_call_started ( void *av, int32_t call_index, void *_arg )
{
ck_assert_msg(0, "AV internal error");
}
void callback_call_started ( int32_t call_index, void *_arg )
{ {
/* /*
Status *cast = _arg; Status *cast = _arg;
cast->calls[call_index].Callee.status = InCall;*/ cast->calls[call_index].Callee.status = InCall;*/
} }
void callback_call_canceled ( int32_t call_index, void *_arg ) void callback_call_canceled ( void *av, int32_t call_index, void *_arg )
{ {
/* /*
Status *cast = _arg; Status *cast = _arg;
cast->calls[call_index].Callee.status = Cancel;*/ cast->calls[call_index].Callee.status = Cancel;*/
} }
void callback_call_rejected ( int32_t call_index, void *_arg ) void callback_call_rejected ( void *av, int32_t call_index, void *_arg )
{ {
Status *cast = _arg; Status *cast = _arg;
cast->calls[call_index].Caller.status = Rejected; cast->calls[call_index].Caller.status = Rejected;
} }
void callback_call_ended ( int32_t call_index, void *_arg ) void callback_call_ended ( void *av, int32_t call_index, void *_arg )
{ {
/* /*
Status *cast = _arg; Status *cast = _arg;
@ -121,7 +115,7 @@ void callback_call_ended ( int32_t call_index, void *_arg )
cast->calls[call_index].Callee.status = Ended;*/ cast->calls[call_index].Callee.status = Ended;*/
} }
void callback_requ_timeout ( int32_t call_index, void *_arg ) void callback_requ_timeout ( void *av, int32_t call_index, void *_arg )
{ {
ck_assert_msg(0, "No answer!"); ck_assert_msg(0, "No answer!");
} }
@ -133,8 +127,27 @@ static void callback_audio(ToxAv *av, int32_t call_index, int16_t *data, int len
static void callback_video(ToxAv *av, int32_t call_index, vpx_image_t *img) static void callback_video(ToxAv *av, int32_t call_index, vpx_image_t *img)
{ {
} }
void register_callbacks(ToxAv *av, void *data)
{
toxav_register_callstate_callback(av, callback_call_started, av_OnStart, data);
toxav_register_callstate_callback(av, callback_call_canceled, av_OnCancel, data);
toxav_register_callstate_callback(av, callback_call_rejected, av_OnReject, data);
toxav_register_callstate_callback(av, callback_call_ended, av_OnEnd, data);
toxav_register_callstate_callback(av, callback_recv_invite, av_OnInvite, data);
toxav_register_callstate_callback(av, callback_recv_ringing, av_OnRinging, data);
toxav_register_callstate_callback(av, callback_recv_starting, av_OnStarting, data);
toxav_register_callstate_callback(av, callback_recv_ending, av_OnEnding, data);
toxav_register_callstate_callback(av, callback_requ_timeout, av_OnRequestTimeout, data);
toxav_register_audio_recv_callback(av, callback_audio);
toxav_register_video_recv_callback(av, callback_video);
}
/*************************************************************************************************/ /*************************************************************************************************/
int call_running[3];
void *in_thread_call (void *arg) void *in_thread_call (void *arg)
{ {
@ -142,23 +155,22 @@ void *in_thread_call (void *arg)
ACall *this_call = arg; ACall *this_call = arg;
uint64_t start = 0; uint64_t start = 0;
int step = 0, running = 1; int step = 0;
int call_idx; int call_idx;
call_running[this_call->idx] = 1;
const int frame_size = (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000); const int frame_size = (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000);
int16_t sample_payload[frame_size]; int16_t sample_payload[frame_size];
randombytes((uint8_t *)sample_payload, sizeof(int16_t) * frame_size); randombytes((uint8_t *)sample_payload, sizeof(int16_t) * frame_size);
uint8_t prepared_payload[RTP_PAYLOAD_SIZE]; uint8_t prepared_payload[RTP_PAYLOAD_SIZE];
toxav_register_audio_recv_callback(this_call->Caller.av, callback_audio); register_callbacks(this_call->Caller.av, &status_control);
toxav_register_video_recv_callback(this_call->Caller.av, callback_video); register_callbacks(this_call->Callee.av, arg);
toxav_register_audio_recv_callback(this_call->Callee.av, callback_audio);
toxav_register_video_recv_callback(this_call->Callee.av, callback_video);
/* NOTE: CALLEE WILL ALWAHYS NEED CALL_IDX == 0 */ /* NOTE: CALLEE WILL ALWAHYS NEED CALL_IDX == 0 */
while (running) { while (call_running[this_call->idx]) {
switch ( step ) { switch ( step ) {
case 0: /* CALLER */ case 0: /* CALLER */
@ -205,20 +217,6 @@ void *in_thread_call (void *arg)
int16_t storage[RTP_PAYLOAD_SIZE]; int16_t storage[RTP_PAYLOAD_SIZE];
int recved; int recved;
/* Payload from CALLER */
/*recved = toxav_recv_audio(this_call->Callee.av, 0, frame_size, storage);
if ( recved ) {
//ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLER is invalid");
}*/
/* Payload from CALLEE */
/*recved = toxav_recv_audio(this_call->Caller.av, call_idx, frame_size, storage);
if ( recved ) {
//ck_assert_msg(recved == 10 && memcmp(storage, sample_payload, 10) == 0, "Payload from CALLEE is invalid");
}*/
c_sleep(20); c_sleep(20);
} }
@ -240,7 +238,7 @@ void *in_thread_call (void *arg)
if (this_call->Caller.status == Ended) { if (this_call->Caller.status == Ended) {
c_sleep(1000); /* race condition */ c_sleep(1000); /* race condition */
this_call->Callee.status = Ended; this_call->Callee.status = Ended;
running = 0; call_running[this_call->idx] = 0;
} }
break; break;
@ -322,52 +320,29 @@ START_TEST(test_AV_three_calls)
ToxAv *uniqcallerav = toxav_new(caller, 3); ToxAv *uniqcallerav = toxav_new(caller, 3);
Status status_control = { for (i = 0; i < 3; i ++) {
0, status_control.calls[i].idx = i;
{none, uniqcallerav, 0},
{none, toxav_new(callees[0], 1), 0},
0, status_control.calls[i].Caller.av = uniqcallerav;
{none, uniqcallerav}, status_control.calls[i].Caller.id = 0;
{none, toxav_new(callees[1], 1), 1}, status_control.calls[i].Caller.status = none;
0,
{none, uniqcallerav},
{none, toxav_new(callees[2], 1), 2}
};
toxav_register_callstate_callback(callback_call_started, av_OnStart, &status_control);
toxav_register_callstate_callback(callback_call_canceled, av_OnCancel, &status_control);
toxav_register_callstate_callback(callback_call_rejected, av_OnReject, &status_control);
toxav_register_callstate_callback(callback_call_ended, av_OnEnd, &status_control);
toxav_register_callstate_callback(callback_recv_invite, av_OnInvite, &status_control);
toxav_register_callstate_callback(callback_recv_ringing, av_OnRinging, &status_control);
toxav_register_callstate_callback(callback_recv_starting, av_OnStarting, &status_control);
toxav_register_callstate_callback(callback_recv_ending, av_OnEnding, &status_control);
toxav_register_callstate_callback(callback_recv_error, av_OnError, &status_control);
toxav_register_callstate_callback(callback_requ_timeout, av_OnRequestTimeout, &status_control);
status_control.calls[i].Callee.av = toxav_new(callees[i], 1);
status_control.calls[i].Callee.id = i;
status_control.calls[i].Callee.status = none;
}
pthread_mutex_init(&muhmutex, NULL); pthread_mutex_init(&muhmutex, NULL);
for ( i = 0; i < 3; i++ ) for ( i = 0; i < 3; i++ )
pthread_create(&status_control.calls[i].tid, NULL, in_thread_call, &status_control.calls[i]); pthread_create(&status_control.calls[i].tid, NULL, in_thread_call, &status_control.calls[i]);
/* Now start 3 calls and they'll run for 10 s */ /* Now start 3 calls and they'll run for 10 s */
for ( i = 0; i < 3; i++ ) for ( i = 0; i < 3; i++ )
pthread_detach(status_control.calls[i].tid); pthread_detach(status_control.calls[i].tid);
while ( while (call_running[0] || call_running[1] || call_running[2]) {
status_control.calls[0].Callee.status != Ended && status_control.calls[0].Caller.status != Ended &&
status_control.calls[1].Callee.status != Ended && status_control.calls[1].Caller.status != Ended &&
status_control.calls[2].Callee.status != Ended && status_control.calls[2].Caller.status != Ended
) {
pthread_mutex_lock(&muhmutex); pthread_mutex_lock(&muhmutex);
tox_do(bootstrap_node); tox_do(bootstrap_node);

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/** toxmsi.h /** msi.h
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
* *
@ -27,11 +27,9 @@
#include "../toxcore/Messenger.h" #include "../toxcore/Messenger.h"
/* define size for call_id */ typedef uint8_t MSICallIDType[12];
#define CALL_ID_LEN 12 typedef uint8_t MSIReasonStrType[255];
typedef void ( *MSICallbackType ) ( void *agent, int32_t call_idx, void *arg );
typedef void ( *MSICallback ) ( int32_t, void *arg );
/** /**
@ -57,6 +55,36 @@ typedef enum {
/**
* @brief Callbacks ids that handle the states
*/
typedef enum {
/* Requests */
MSI_OnInvite,
MSI_OnStart,
MSI_OnCancel,
MSI_OnReject,
MSI_OnEnd,
/* Responses */
MSI_OnRinging,
MSI_OnStarting,
MSI_OnEnding,
/* Protocol */
MSI_OnRequestTimeout,
MSI_OnPeerTimeout,
MSI_OnMediaChange
} MSICallbackID;
/**
* @brief Callbacks container
*/
typedef struct _MSICallbackCont {
MSICallbackType function;
void *data;
} MSICallbackCont;
/** /**
* @brief The call struct. * @brief The call struct.
* *
@ -69,7 +97,7 @@ typedef struct _MSICall { /* Call info structure */
MSICallType type_local; /* Type of payload user is ending */ MSICallType type_local; /* Type of payload user is ending */
MSICallType *type_peer; /* Type of payload others are sending */ MSICallType *type_peer; /* Type of payload others are sending */
uint8_t id[CALL_ID_LEN]; /* Random value identifying the call */ MSICallIDType id; /* Random value identifying the call */
int ringing_tout_ms; /* Ringing timeout in ms */ int ringing_tout_ms; /* Ringing timeout in ms */
@ -92,56 +120,30 @@ typedef struct _MSICall { /* Call info structure */
typedef struct _MSISession { typedef struct _MSISession {
/* Call handlers */ /* Call handlers */
struct _MSICall **calls; MSICall **calls;
int32_t max_calls; int32_t max_calls;
int last_error_id; /* Determine the last error */ void *agent_handler;
const uint8_t *last_error_str; Messenger *messenger_handle;
void *agent_handler; /* Pointer to an object that is handling msi */ uint32_t frequ;
Messenger *messenger_handle; uint32_t call_timeout; /* Time of the timeout for some action to end; 0 if infinite */
uint32_t frequ;
uint32_t call_timeout; /* Time of the timeout for some action to end; 0 if infinite */
pthread_mutex_t mutex; pthread_mutex_t mutex;
void *timer_handler; void *timer_handler;
MSICallbackCont callbacks[11]; /* Callbacks used by this session */
} MSISession; } MSISession;
/**
* @brief Callbacks ids that handle the states
*/
typedef enum {
/* Requests */
MSI_OnInvite,
MSI_OnStart,
MSI_OnCancel,
MSI_OnReject,
MSI_OnEnd,
/* Responses */
MSI_OnRinging,
MSI_OnStarting,
MSI_OnEnding,
/* Protocol */
MSI_OnError,
MSI_OnRequestTimeout,
MSI_OnPeerTimeout
} MSICallbackID;
/** /**
* @brief Callback setter. * @brief Callback setter.
* *
* @param session The container.
* @param callback The callback. * @param callback The callback.
* @param id The id. * @param id The id.
* @return void * @return void
*/ */
void msi_register_callback(MSICallback callback, MSICallbackID id, void *userdata); void msi_register_callback(MSISession *session, MSICallbackType callback, MSICallbackID id, void *userdata);
/** /**
@ -220,7 +222,20 @@ int msi_cancel ( MSISession *session, int32_t call_index, uint32_t peer, const c
* @param reason Set optional reason header. Pass NULL if none. * @param reason Set optional reason header. Pass NULL if none.
* @return int * @return int
*/ */
int msi_reject ( MSISession *session, int32_t call_index, const uint8_t *reason ); int msi_reject ( MSISession *session, int32_t call_index, const char *reason );
/**
* @brief Send invite request to friend_id.
*
* @param session Control session.
* @param call_index 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_change_type ( MSISession *session, int32_t call_index, MSICallType call_type );
/** /**

View File

@ -1,4 +1,4 @@
/** toxrtp.c /** rtp.c
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
* *

View File

@ -1,4 +1,4 @@
/** toxrtp.h /** rtp.h
* *
* Copyright (C) 2013 Tox project All Rights Reserved. * Copyright (C) 2013 Tox project All Rights Reserved.
* *

View File

@ -120,10 +120,8 @@ ToxAv *toxav_new( Tox *messenger, int32_t max_calls)
} }
av->messenger = (Messenger *)messenger; av->messenger = (Messenger *)messenger;
av->msi_session = msi_init_session(av->messenger, max_calls); av->msi_session = msi_init_session(av->messenger, max_calls);
av->msi_session->agent_handler = av; av->msi_session->agent_handler = av;
av->calls = calloc(sizeof(CallSpecific), max_calls); av->calls = calloc(sizeof(CallSpecific), max_calls);
av->max_calls = max_calls; av->max_calls = max_calls;
@ -164,13 +162,14 @@ void toxav_kill ( ToxAv *av )
/** /**
* @brief Register callback for call state. * @brief Register callback for call state.
* *
* @param av Handler.
* @param callback The callback * @param callback The callback
* @param id One of the ToxAvCallbackID values * @param id One of the ToxAvCallbackID values
* @return void * @return void
*/ */
void toxav_register_callstate_callback ( ToxAVCallback callback, ToxAvCallbackID id, void *userdata ) void toxav_register_callstate_callback ( ToxAv *av, ToxAVCallback callback, ToxAvCallbackID id, void *userdata )
{ {
msi_register_callback((MSICallback)callback, (MSICallbackID) id, userdata); msi_register_callback(av->msi_session, (MSICallbackType)callback, (MSICallbackID) id, userdata);
} }
/** /**
@ -299,6 +298,24 @@ int toxav_cancel ( ToxAv *av, int32_t call_index, int peer_id, const char *reaso
return msi_cancel(av->msi_session, call_index, peer_id, reason); return msi_cancel(av->msi_session, call_index, peer_id, reason);
} }
/**
* @brief Notify peer that we are changing call type
*
* @param av Handler.
* @return int
* @param call_type Change to...
* @retval 0 Success.
* @retval ToxAvError On error.
*/
int toxav_change_type(ToxAv *av, int32_t call_index, ToxAvCallType call_type)
{
if ( cii(call_index, av->msi_session) || !av->msi_session->calls[call_index] ) {
return ErrorNoCall;
}
return msi_change_type(av->msi_session, call_index, call_type);
}
/** /**
* @brief Terminate transmission. Note that transmission will be terminated without informing remote peer. * @brief Terminate transmission. Note that transmission will be terminated without informing remote peer.
* *
@ -759,6 +776,8 @@ void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg)
int32_t call_index = _session->call_index; int32_t call_index = _session->call_index;
CallSpecific *call = &av->calls[call_index]; CallSpecific *call = &av->calls[call_index];
if (!call->call_active) return;
if (_session->payload_type == type_audio % 128) { if (_session->payload_type == type_audio % 128) {
queue(call->j_buf, _msg); queue(call->j_buf, _msg);
@ -779,7 +798,10 @@ void toxav_handle_packet(RTPSession *_session, RTPMessage *_msg)
continue; continue;
} }
av->audio_callback(av, call_index, dest, frame_size); if ( av->audio_callback )
av->audio_callback(av, call_index, dest, frame_size);
else
LOGGER_WARNING("Audio packet dropped due to missing callback!");
} }
} else { } else {
uint8_t *packet = _msg->data; uint8_t *packet = _msg->data;
@ -831,9 +853,10 @@ end:
vpx_image_t *img; vpx_image_t *img;
img = vpx_codec_get_frame(&call->cs->v_decoder, &iter); img = vpx_codec_get_frame(&call->cs->v_decoder, &iter);
if (img) { if (img && av->video_callback) {
av->video_callback(av, call_index, img); av->video_callback(av, call_index, img);
} } else
LOGGER_WARNING("Video packet dropped due to missing callback or no image!");
rtp_free_msg(NULL, _msg); rtp_free_msg(NULL, _msg);
} }

View File

@ -31,7 +31,7 @@ extern "C" {
/* vpx_image_t */ /* vpx_image_t */
#include <vpx/vpx_image.h> #include <vpx/vpx_image.h>
typedef void ( *ToxAVCallback ) ( int32_t, void *arg ); typedef void ( *ToxAVCallback ) ( void *agent, int32_t call_idx, void *arg );
typedef struct _ToxAv ToxAv; typedef struct _ToxAv ToxAv;
#ifndef __TOX_DEFINED__ #ifndef __TOX_DEFINED__
@ -59,9 +59,9 @@ typedef enum {
av_OnEnding, av_OnEnding,
/* Protocol */ /* Protocol */
av_OnError,
av_OnRequestTimeout, av_OnRequestTimeout,
av_OnPeerTimeout av_OnPeerTimeout,
av_OnMediaChange
} ToxAvCallbackID; } ToxAvCallbackID;
@ -158,11 +158,30 @@ void toxav_kill(ToxAv *av);
/** /**
* @brief Register callback for call state. * @brief Register callback for call state.
* *
* @param av Handler.
* @param callback The callback * @param callback The callback
* @param id One of the ToxAvCallbackID values * @param id One of the ToxAvCallbackID values
* @return void * @return void
*/ */
void toxav_register_callstate_callback (ToxAVCallback callback, ToxAvCallbackID id, void *userdata); void toxav_register_callstate_callback (ToxAv *av, ToxAVCallback callback, ToxAvCallbackID id, void *userdata);
/**
* @brief Register callback for recieving audio data
*
* @param av Handler.
* @param callback The callback
* @return void
*/
void toxav_register_audio_recv_callback (ToxAv *av, void (*callback)(ToxAv *, int32_t, int16_t *, int));
/**
* @brief Register callback for recieving video data
*
* @param av Handler.
* @param callback The callback
* @return void
*/
void toxav_register_video_recv_callback (ToxAv *av, void (*callback)(ToxAv *, int32_t, vpx_image_t *));
/** /**
* @brief Register callback for recieving audio data * @brief Register callback for recieving audio data
@ -237,6 +256,16 @@ int toxav_reject(ToxAv *av, int32_t call_index, const char *reason);
*/ */
int toxav_cancel(ToxAv *av, int32_t call_index, int peer_id, const char *reason); int toxav_cancel(ToxAv *av, int32_t call_index, int peer_id, const char *reason);
/**
* @brief Notify peer that we are changing call type
*
* @param av Handler.
* @return int
* @retval 0 Success.
* @retval ToxAvError On error.
*/
int toxav_change_type(ToxAv *av, int32_t call_index, ToxAvCallType call_type);
/** /**
* @brief Terminate transmission. Note that transmission will be terminated without informing remote peer. * @brief Terminate transmission. Note that transmission will be terminated without informing remote peer.
* *

View File

@ -26,7 +26,6 @@
#define __TOXLOGGER #define __TOXLOGGER
#include <string.h> #include <string.h>
// #define LOGGING
#ifdef LOGGING #ifdef LOGGING