summaryrefslogtreecommitdiff
path: root/auto_tests
diff options
context:
space:
mode:
Diffstat (limited to 'auto_tests')
-rw-r--r--auto_tests/Makefile.inc10
-rw-r--r--auto_tests/toxav_basic_test.c875
-rw-r--r--auto_tests/toxav_many_test.c459
3 files changed, 482 insertions, 862 deletions
diff --git a/auto_tests/Makefile.inc b/auto_tests/Makefile.inc
index d78a6a5a..741ca7fa 100644
--- a/auto_tests/Makefile.inc
+++ b/auto_tests/Makefile.inc
@@ -21,8 +21,8 @@ AUTOTEST_LDADD = \
21 21
22 22
23if BUILD_AV 23if BUILD_AV
24TESTS += toxav_basic_test toxav_many_test 24TESTS += toxav_basic_test #toxav_many_test
25check_PROGRAMS += toxav_basic_test toxav_many_test 25check_PROGRAMS += toxav_basic_test #toxav_many_test
26AUTOTEST_LDADD += libtoxav.la 26AUTOTEST_LDADD += libtoxav.la
27endif 27endif
28 28
@@ -90,11 +90,11 @@ toxav_basic_test_CFLAGS = $(AUTOTEST_CFLAGS)
90toxav_basic_test_LDADD = $(AUTOTEST_LDADD) $(AV_LIBS) 90toxav_basic_test_LDADD = $(AUTOTEST_LDADD) $(AV_LIBS)
91 91
92 92
93toxav_many_test_SOURCES = ../auto_tests/toxav_many_test.c 93#toxav_many_test_SOURCES = ../auto_tests/toxav_many_test.c
94 94
95toxav_many_test_CFLAGS = $(AUTOTEST_CFLAGS) 95#toxav_many_test_CFLAGS = $(AUTOTEST_CFLAGS)
96 96
97toxav_many_test_LDADD = $(AUTOTEST_LDADD) 97#toxav_many_test_LDADD = $(AUTOTEST_LDADD)
98endif 98endif
99 99
100endif 100endif
diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c
index a43b7c2f..7598c0db 100644
--- a/auto_tests/toxav_basic_test.c
+++ b/auto_tests/toxav_basic_test.c
@@ -14,6 +14,7 @@
14#include <vpx/vpx_image.h> 14#include <vpx/vpx_image.h>
15 15
16#include "../toxcore/tox.h" 16#include "../toxcore/tox.h"
17#include "../toxcore/util.h"
17#include "../toxcore/logger.h" 18#include "../toxcore/logger.h"
18#include "../toxcore/crypto_core.h" 19#include "../toxcore/crypto_core.h"
19#include "../toxav/toxav.h" 20#include "../toxav/toxav.h"
@@ -28,600 +29,406 @@
28#endif 29#endif
29 30
30 31
32#define TEST_REGULAR_AV 1
33#define TEST_REGULAR_A 1
34#define TEST_REGULAR_V 1
35#define TEST_REJECT 1
36#define TEST_CANCEL 1
37#define TEST_MUTE_UNMUTE 1
31 38
32typedef enum _CallStatus {
33 none,
34 InCall,
35 Ringing,
36 Ended,
37 Rejected,
38 Canceled,
39 TimedOut
40 39
41} CallStatus; 40typedef struct {
41 bool incoming;
42 uint32_t state;
43
44} CallControl;
42 45
43typedef struct _Party {
44 CallStatus status;
45 ToxAv *av;
46 time_t *CallStarted;
47 int call_index;
48} Party;
49 46
50typedef struct _Status { 47/**
51 Party Alice; 48 * Callbacks
52 Party Bob; 49 */
53} Status; 50void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data)
54
55/* My default settings */
56static ToxAvCSettings muhcaps;
57
58void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
59{
60 if (length == 7 && memcmp("gentoo", data, 7) == 0) {
61 tox_friend_add_norequest(m, public_key, 0);
62 }
63}
64
65
66/******************************************************************************/
67void callback_recv_invite ( void *av, int32_t call_index, void *_arg )
68{
69 Status *cast = _arg;
70
71 if (cast->Alice.av == av) {
72 // ...
73 } else if (cast->Bob.av == av) {
74 /* Bob always receives invite */
75 cast->Bob.status = Ringing;
76 cast->Bob.call_index = call_index;
77 }
78}
79void callback_recv_ringing ( void *av, int32_t call_index, void *_arg )
80{
81 Status *cast = _arg;
82
83 if (cast->Alice.av == av) {
84 /* Alice always sends invite */
85 cast->Alice.status = Ringing;
86 } else if (cast->Bob.av == av) {
87 // ...
88 }
89}
90
91
92void callback_call_started ( void *av, int32_t call_index, void *_arg )
93{
94 Status *cast = _arg;
95
96 if (cast->Alice.av == av) {
97 printf("Call started on Alices side...\n");
98 cast->Alice.status = InCall;
99 toxav_prepare_transmission(av, call_index, 1);
100 } else if (cast->Bob.av == av) {
101 printf("Call started on Bob side...\n");
102 cast->Bob.status = InCall;
103 toxav_prepare_transmission(av, call_index, 1);
104 }
105}
106void callback_call_canceled ( void *av, int32_t call_index, void *_arg )
107{ 51{
108 Status *cast = _arg; 52 printf("Handling CALL callback\n");
109 53 ((CallControl*)user_data)->incoming = true;
110 if (cast->Alice.av == av) {
111 // ...
112 } else if (cast->Bob.av == av) {
113 printf ( "Call Canceled for Bob!\n" );
114 cast->Bob.status = Canceled;
115 }
116} 54}
117void callback_call_rejected ( void *av, int32_t call_index, void *_arg ) 55void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data)
118{ 56{
119 Status *cast = _arg; 57 printf("Handling CALL STATE callback: %d\n", state);
120 58 ((CallControl*)user_data)->state = state;
121 printf ( "Call rejected by Bob!\n"
122 "Call ended for Alice!\n" );
123
124 /* If Bob rejects, call is ended for alice and she sends ending */
125 if (cast->Alice.av == av) {
126 cast->Alice.status = Rejected;
127 } else if (cast->Bob.av == av) {
128 //... ignor
129 }
130} 59}
131void callback_call_ended ( void *av, int32_t call_index, void *_arg ) 60void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number,
61 uint16_t width, uint16_t height,
62 uint8_t const *y, uint8_t const *u, uint8_t const *v,
63 int32_t ystride, int32_t ustride, int32_t vstride,
64 void *user_data)
132{ 65{
133 Status *cast = _arg; 66 (void) av;
134 67 (void) friend_number;
135 if (cast->Alice.av == av) { 68 (void) width;
136 printf ( "Call ended for Alice!\n" ); 69 (void) height;
137 cast->Alice.status = Ended; 70 (void) y;
138 } else if (cast->Bob.av == av) { 71 (void) u;
139 printf ( "Call ended for Bob!\n" ); 72 (void) v;
140 cast->Bob.status = Ended; 73 (void) ystride;
141 } 74 (void) ustride;
75 (void) vstride;
76 (void) user_data;
142} 77}
143 78void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number,
144void callback_peer_cs_change ( void *av, int32_t call_index, void *_arg ) 79 int16_t const *pcm,
80 size_t sample_count,
81 uint8_t channels,
82 uint32_t sampling_rate,
83 void *user_data)
145{ 84{
146 ToxAvCSettings csettings; 85 (void) av;
147 toxav_get_peer_csettings(av, call_index, 0, &csettings); 86 (void) friend_number;
148 87 (void) pcm;
149 printf("Peer changing settings to: \n" 88 (void) sample_count;
150 "Type: %u \n" 89 (void) channels;
151 "Video bitrate: %u \n" 90 (void) sampling_rate;
152 "Video height: %u \n" 91 (void) user_data;
153 "Video width: %u \n"
154 "Audio bitrate: %u \n"
155 "Audio framedur: %u \n"
156 "Audio sample rate: %u \n"
157 "Audio channels: %u \n",
158 csettings.call_type,
159 csettings.video_bitrate,
160 csettings.max_video_height,
161 csettings.max_video_width,
162 csettings.audio_bitrate,
163 csettings.audio_frame_duration,
164 csettings.audio_sample_rate,
165 csettings.audio_channels
166 );
167} 92}
168 93void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
169void callback_self_cs_change ( void *av, int32_t call_index, void *_arg )
170{ 94{
171 ToxAvCSettings csettings; 95 if (length == 7 && memcmp("gentoo", data, 7) == 0) {
172 toxav_get_peer_csettings(av, call_index, 0, &csettings); 96 assert(tox_friend_add_norequest(m, public_key, NULL) != (uint32_t) ~0);
173
174 printf("Changed settings to: \n"
175 "Type: %u \n"
176 "Video bitrate: %u \n"
177 "Video height: %u \n"
178 "Video width: %u \n"
179 "Audio bitrate: %u \n"
180 "Audio framedur: %u \n"
181 "Audio sample rate: %u \n"
182 "Audio channels: %u \n",
183 csettings.call_type,
184 csettings.video_bitrate,
185 csettings.max_video_height,
186 csettings.max_video_width,
187 csettings.audio_bitrate,
188 csettings.audio_frame_duration,
189 csettings.audio_sample_rate,
190 csettings.audio_channels
191 );
192}
193
194void callback_requ_timeout ( void *av, int32_t call_index, void *_arg )
195{
196 Status *cast = _arg;
197 printf("Call timed-out!\n");
198
199 if (cast->Alice.av == av) {
200 cast->Alice.status = TimedOut;
201 } else if (cast->Bob.av == av) {
202 cast->Bob.status = TimedOut;
203 } 97 }
204} 98}
205 99
206void callback_audio (void *agent, int32_t call_idx, const int16_t *PCM, uint16_t size, void *data)
207{}
208
209void callback_video (void *agent, int32_t call_idx, const vpx_image_t *img, void *data)
210{}
211 100
212void register_callbacks(ToxAv *av, void *data) 101/**
102 * Iterate helper
103 */
104int iterate_tox(Tox* bootstrap, Tox* Alice, Tox* Bob)
213{ 105{
214 toxav_register_callstate_callback(av, callback_call_started, av_OnStart, data); 106 tox_iterate(bootstrap);
215 toxav_register_callstate_callback(av, callback_call_canceled, av_OnCancel, data); 107 tox_iterate(Alice);
216 toxav_register_callstate_callback(av, callback_call_rejected, av_OnReject, data); 108 tox_iterate(Bob);
217 toxav_register_callstate_callback(av, callback_call_ended, av_OnEnd, data); 109
218 toxav_register_callstate_callback(av, callback_recv_invite, av_OnInvite, data); 110 return MIN(tox_iteration_interval(Alice), tox_iteration_interval(Bob));
219 toxav_register_callstate_callback(av, callback_recv_ringing, av_OnRinging, data);
220 toxav_register_callstate_callback(av, callback_requ_timeout, av_OnRequestTimeout, data);
221 toxav_register_callstate_callback(av, callback_peer_cs_change, av_OnPeerCSChange, data);
222 toxav_register_callstate_callback(av, callback_self_cs_change, av_OnSelfCSChange, data);
223 toxav_register_audio_callback(av, callback_audio, NULL);
224 toxav_register_video_callback(av, callback_video, NULL);
225} 111}
226 112
227 113
228/*************************************************************************************************/
229
230/* Alice calls bob and the call starts.
231 * What happens during the call is defined after. To quit the loop use: step++;
232 */
233#define CALL_AND_START_LOOP(AliceCallType, BobCallType) \
234{ int step = 0, running = 1; while (running) {\
235 tox_iterate(bootstrap_node); tox_iterate(Alice); tox_iterate(Bob); \
236 toxav_do(status_control.Bob.av); toxav_do(status_control.Alice.av); \
237 switch ( step ) {\
238 case 0: /* Alice */ printf("Alice is calling...\n");\
239 toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, &muhcaps, 10); step++; break;\
240 case 1: /* Bob */ if (status_control.Bob.status == Ringing) { printf("Bob answers...\n");\
241 cur_time = time(NULL); toxav_answer(status_control.Bob.av, status_control.Bob.call_index, &muhcaps); step++; } break; \
242 case 2: /* Rtp transmission */ \
243 if (status_control.Bob.status == InCall && status_control.Alice.status == InCall)
244
245
246#define TERMINATE_SCOPE() break;\
247case 3: /* Wait for Both to have status ended */\
248if (status_control.Alice.status == Ended && status_control.Bob.status == Ended) running = 0; break; } c_sleep(20); } } printf("\n");
249 114
250START_TEST(test_AV_flows) 115START_TEST(test_AV_flows)
251{ 116{
117 Tox* Alice, *Bob, *bootstrap;
118 ToxAV* AliceAV, *BobAV;
119
120 CallControl AliceCC, BobCC;
121
122 {
123 TOX_ERR_NEW error;
124
125 bootstrap = tox_new(NULL, NULL, 0, &error);
126 assert(error == TOX_ERR_NEW_OK);
127
128 Alice = tox_new(NULL, NULL, 0, &error);
129 assert(error == TOX_ERR_NEW_OK);
130
131 Bob = tox_new(NULL, NULL, 0, &error);
132 assert(error == TOX_ERR_NEW_OK);
133 }
134
135 printf("Created 3 instances of Tox\n");
136 printf("Preparing network...\n");
252 long long unsigned int cur_time = time(NULL); 137 long long unsigned int cur_time = time(NULL);
253 Tox *bootstrap_node = tox_new(0, 0, 0, 0); 138
254 Tox *Alice = tox_new(0, 0, 0, 0);
255 Tox *Bob = tox_new(0, 0, 0, 0);
256
257 ck_assert_msg(bootstrap_node || Alice || Bob, "Failed to create 3 tox instances");
258
259 uint32_t to_compare = 974536; 139 uint32_t to_compare = 974536;
260 tox_callback_friend_request(Alice, accept_friend_request, &to_compare);
261 uint8_t address[TOX_ADDRESS_SIZE]; 140 uint8_t address[TOX_ADDRESS_SIZE];
141
142 tox_callback_friend_request(Alice, t_accept_friend_request_cb, &to_compare);
262 tox_self_get_address(Alice, address); 143 tox_self_get_address(Alice, address);
263 uint32_t test = tox_friend_add(Bob, address, (uint8_t *)"gentoo", 7, 0); 144
264 145
265 ck_assert_msg(test == 0, "Failed to add friend error code: %i", test); 146 assert(tox_friend_add(Bob, address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0);
266 147
267 uint8_t off = 1; 148 uint8_t off = 1;
268 149
269 while (1) { 150 while (1) {
270 tox_iterate(bootstrap_node); 151 iterate_tox(bootstrap, Alice, Bob);
271 tox_iterate(Alice); 152
272 tox_iterate(Bob); 153 if (tox_self_get_connection_status(bootstrap) &&
273 154 tox_self_get_connection_status(Alice) &&
274 if (tox_self_get_connection_status(bootstrap_node) && tox_self_get_connection_status(Alice) 155 tox_self_get_connection_status(Bob) && off) {
275 && tox_self_get_connection_status(Bob)
276 && off) {
277 printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time); 156 printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time);
278 off = 0; 157 off = 0;
279 } 158 }
280 159
281 if (tox_friend_get_connection_status(Alice, 0, 0) && tox_friend_get_connection_status(Bob, 0, 0)) 160 if (tox_friend_get_connection_status(Alice, 0, NULL) == TOX_CONNECTION_UDP &&
161 tox_friend_get_connection_status(Bob, 0, NULL) == TOX_CONNECTION_UDP)
282 break; 162 break;
283 163
284 c_sleep(20); 164 c_sleep(20);
285 } 165 }
286 166
287 printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time); 167
288 168 {
289 muhcaps = av_DefaultSettings; 169 TOXAV_ERR_NEW error;
290 muhcaps.max_video_height = muhcaps.max_video_width = 128; 170 AliceAV = toxav_new(Alice, &error);
291 171 assert(error == TOXAV_ERR_NEW_OK);
292 Status status_control = { 172
293 {none, toxav_new(Alice, 1), NULL, -1}, 173 BobAV = toxav_new(Bob, &error);
294 {none, toxav_new(Bob, 1), NULL, -1}, 174 assert(error == TOXAV_ERR_NEW_OK);
295 };
296
297 ck_assert_msg(status_control.Alice.av || status_control.Bob.av, "Failed to create 2 toxav instances");
298
299
300 register_callbacks(status_control.Alice.av, &status_control);
301 register_callbacks(status_control.Bob.av, &status_control);
302
303 const int frame_size = (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000);
304 int16_t sample_payload[frame_size];
305 randombytes((uint8_t *)sample_payload, sizeof(int16_t) * frame_size);
306
307 uint8_t prepared_payload[RTP_PAYLOAD_SIZE];
308 int payload_size;
309
310 vpx_image_t *sample_image = vpx_img_alloc(NULL, VPX_IMG_FMT_I420, 128, 128, 1);
311
312 memcpy(sample_image->planes[VPX_PLANE_Y], sample_payload, 10);
313 memcpy(sample_image->planes[VPX_PLANE_U], sample_payload, 10);
314 memcpy(sample_image->planes[VPX_PLANE_V], sample_payload, 10);
315
316
317 /*************************************************************************************************
318 * Successful flows (when call starts)
319 */
320
321 /*
322 * Call with audio only on both sides. Alice calls Bob.
323 */
324
325
326 CALL_AND_START_LOOP(TypeAudio, TypeAudio) {
327 /* Both send */
328 payload_size = toxav_prepare_audio_frame(status_control.Alice.av, status_control.Alice.call_index, prepared_payload,
329 1000, sample_payload, frame_size);
330
331 if ( payload_size < 0 ) {
332 ck_assert_msg ( 0, "Failed to encode payload" );
333 }
334
335 toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, payload_size);
336
337 payload_size = toxav_prepare_audio_frame(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, 1000,
338 sample_payload, frame_size);
339
340 if ( payload_size < 0 ) {
341 ck_assert_msg ( 0, "Failed to encode payload" );
342 }
343
344 toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size);
345
346 if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
347 step++; /* This terminates the loop */
348 toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index);
349 toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index);
350
351 /* Call over Alice hangs up */
352 toxav_hangup(status_control.Alice.av, status_control.Alice.call_index);
353 }
354 } 175 }
355 TERMINATE_SCOPE() 176
356 177 toxav_callback_call(AliceAV, t_toxav_call_cb, &AliceCC);
357 178 toxav_callback_call_state(AliceAV, t_toxav_call_state_cb, &AliceCC);
358 /* 179 toxav_callback_receive_video_frame(AliceAV, t_toxav_receive_video_frame_cb, &AliceCC);
359 * Call with audio on both sides and video on one side. Alice calls Bob. 180 toxav_callback_receive_audio_frame(AliceAV, t_toxav_receive_audio_frame_cb, &AliceCC);
360 */ 181
361 CALL_AND_START_LOOP(TypeAudio, TypeVideo) { 182 toxav_callback_call(BobAV, t_toxav_call_cb, &BobCC);
362 /* Both send */ 183 toxav_callback_call_state(BobAV, t_toxav_call_state_cb, &BobCC);
363 payload_size = toxav_prepare_audio_frame(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, 184 toxav_callback_receive_video_frame(BobAV, t_toxav_receive_video_frame_cb, &BobCC);
364 1000, sample_payload, frame_size); 185 toxav_callback_receive_audio_frame(BobAV, t_toxav_receive_audio_frame_cb, &BobCC);
365 186
366 if ( payload_size < 0 ) { 187 printf("Created 2 instances of ToxAV\n");
367 ck_assert_msg ( 0, "Failed to encode payload" ); 188 printf("All set after %llu seconds!\n", time(NULL) - cur_time);
368 } 189
369 190
370 toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, payload_size); 191#define REGULAR_CALL_FLOW(A_BR, V_BR) \
371 192 do { \
372 payload_size = toxav_prepare_audio_frame(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, 1000, 193 memset(&AliceCC, 0, sizeof(CallControl)); \
373 sample_payload, frame_size); 194 memset(&BobCC, 0, sizeof(CallControl)); \
374 195 \
375 if ( payload_size < 0 ) { 196 TOXAV_ERR_CALL rc; \
376 ck_assert_msg ( 0, "Failed to encode payload" ); 197 toxav_call(AliceAV, 0, A_BR, V_BR, &rc); \
377 } 198 \
378 199 if (rc != TOXAV_ERR_CALL_OK) { \
379 toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size); 200 printf("toxav_call failed: %d\n", rc); \
380 201 exit(1); \
381// toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image); 202 } \
382 203 \
383 if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */ 204 \
384 step++; /* This terminates the loop */ 205 long long unsigned int start_time = time(NULL); \
385 toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index); 206 \
386 toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index); 207 \
387 208 while (BobCC.state != TOXAV_CALL_STATE_END) { \
388 /* Call over Alice hangs up */ 209 \
389 toxav_hangup(status_control.Alice.av, status_control.Alice.call_index); 210 if (BobCC.incoming) { \
390 } 211 TOXAV_ERR_ANSWER rc; \
212 toxav_answer(BobAV, 0, A_BR, V_BR, &rc); \
213 \
214 if (rc != TOXAV_ERR_ANSWER_OK) { \
215 printf("toxav_answer failed: %d\n", rc); \
216 exit(1); \
217 } \
218 BobCC.incoming = false; \
219 } else { \
220 /* TODO rtp */ \
221 \
222 if (time(NULL) - start_time == 5) { \
223 \
224 TOXAV_ERR_CALL_CONTROL rc; \
225 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc); \
226 \
227 if (rc != TOXAV_ERR_CALL_CONTROL_OK) { \
228 printf("toxav_call_control failed: %d\n", rc); \
229 exit(1); \
230 } \
231 } \
232 } \
233 \
234 iterate_tox(bootstrap, Alice, Bob); \
235 } \
236 printf("Success!\n");\
237 } while(0)
238
239 if (TEST_REGULAR_AV) {
240 printf("\nTrying regular call (Audio and Video)...\n");
241 REGULAR_CALL_FLOW(48, 4000);
391 } 242 }
392 TERMINATE_SCOPE() 243
393 244 if (TEST_REGULAR_A) {
394 245 printf("\nTrying regular call (Audio only)...\n");
395 /* 246 REGULAR_CALL_FLOW(48, 0);
396 * Call with audio and video on both sides. Alice calls Bob.
397 */
398 CALL_AND_START_LOOP(TypeVideo, TypeVideo) {
399 /* Both send */
400
401 payload_size = toxav_prepare_audio_frame(status_control.Alice.av, status_control.Alice.call_index, prepared_payload,
402 1000, sample_payload, frame_size);
403
404 if ( payload_size < 0 ) {
405 ck_assert_msg ( 0, "Failed to encode payload" );
406 }
407
408 toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, payload_size);
409
410 payload_size = toxav_prepare_audio_frame(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, 1000,
411 sample_payload, frame_size);
412
413 if ( payload_size < 0 ) {
414 ck_assert_msg ( 0, "Failed to encode payload" );
415 }
416
417 toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size);
418
419// toxav_send_video(status_control.Alice.av, status_control.Alice.call_index, sample_image);
420// toxav_send_video(status_control.Bob.av, status_control.Bob.call_index, sample_image);
421
422
423 if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */
424 step++; /* This terminates the loop */
425 toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index);
426 toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index);
427
428 /* Call over Alice hangs up */
429 toxav_hangup(status_control.Alice.av, status_control.Alice.call_index);
430 }
431 } 247 }
432 TERMINATE_SCOPE() 248
433 249 if (TEST_REGULAR_V) {
434 250 printf("\nTrying regular call (Video only)...\n");
435 uint64_t times_they_are_a_changin = time(NULL); 251 REGULAR_CALL_FLOW(0, 4000);
436 /* Media change */ 252 }
437 CALL_AND_START_LOOP(TypeAudio, TypeAudio) { 253
438 /* Both send */ 254#undef REGULAR_CALL_FLOW
439 payload_size = toxav_prepare_audio_frame(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, 255
440 1000, sample_payload, frame_size); 256 if (TEST_REJECT) { /* Alice calls; Bob rejects */
441 257 printf("\nTrying reject flow...\n");
442 if ( payload_size < 0 ) { 258
443 ck_assert_msg ( 0, "Failed to encode payload" ); 259 memset(&AliceCC, 0, sizeof(CallControl));
260 memset(&BobCC, 0, sizeof(CallControl));
261
262 {
263 TOXAV_ERR_CALL rc;
264 toxav_call(AliceAV, 0, 48, 0, &rc);
265
266 if (rc != TOXAV_ERR_CALL_OK) {
267 printf("toxav_call failed: %d\n", rc);
268 exit(1);
269 }
444 } 270 }
445 271
446 toxav_send_audio(status_control.Alice.av, status_control.Alice.call_index, prepared_payload, payload_size); 272 while (!BobCC.incoming)
447 273 iterate_tox(bootstrap, Alice, Bob);
448 payload_size = toxav_prepare_audio_frame(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, 1000, 274
449 sample_payload, frame_size); 275 /* Reject */
450 276 {
451 if ( payload_size < 0 ) { 277 TOXAV_ERR_CALL_CONTROL rc;
452 ck_assert_msg ( 0, "Failed to encode payload" ); 278 toxav_call_control(BobAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
279
280 if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
281 printf("toxav_call_control failed: %d\n", rc);
282 exit(1);
283 }
453 } 284 }
454 285
455 toxav_send_audio(status_control.Bob.av, status_control.Bob.call_index, prepared_payload, payload_size); 286 while (AliceCC.state != TOXAV_CALL_STATE_END)
456 287 iterate_tox(bootstrap, Alice, Bob);
457 /* Wait 2 seconds and change transmission type */ 288
458 if (time(NULL) - times_they_are_a_changin > 2) { 289 printf("Success!\n");
459 times_they_are_a_changin = time(NULL); 290 }
460 muhcaps.audio_bitrate ++; 291
461 toxav_change_settings(status_control.Alice.av, status_control.Alice.call_index, &muhcaps); 292 if (TEST_CANCEL) { /* Alice calls; Alice cancels while ringing */
293 printf("\nTrying cancel (while ringing) flow...\n");
294
295 memset(&AliceCC, 0, sizeof(CallControl));
296 memset(&BobCC, 0, sizeof(CallControl));
297
298 {
299 TOXAV_ERR_CALL rc;
300 toxav_call(AliceAV, 0, 48, 0, &rc);
301
302 if (rc != TOXAV_ERR_CALL_OK) {
303 printf("toxav_call failed: %d\n", rc);
304 exit(1);
305 }
462 } 306 }
463 307
464 if (time(NULL) - cur_time > 10) { /* Transmit for 10 seconds */ 308 while (!BobCC.incoming)
465 step++; /* This terminates the loop */ 309 iterate_tox(bootstrap, Alice, Bob);
466 toxav_kill_transmission(status_control.Alice.av, status_control.Alice.call_index); 310
467 toxav_kill_transmission(status_control.Bob.av, status_control.Bob.call_index); 311 /* Cancel */
468 312 {
469 /* Call over Alice hangs up */ 313 TOXAV_ERR_CALL_CONTROL rc;
470 toxav_hangup(status_control.Alice.av, status_control.Alice.call_index); 314 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
315
316 if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
317 printf("toxav_call_control failed: %d\n", rc);
318 exit(1);
319 }
471 } 320 }
321
322 /* Alice will not receive end state */
323 while (BobCC.state != TOXAV_CALL_STATE_END)
324 iterate_tox(bootstrap, Alice, Bob);
325
326 printf("Success!\n");
472 } 327 }
473 TERMINATE_SCOPE() 328
474 329 if (TEST_MUTE_UNMUTE) { /* Check Mute-Unmute etc */
475 330 printf("\nTrying mute functionality...\n");
476 /************************************************************************************************* 331
477 * Other flows 332 memset(&AliceCC, 0, sizeof(CallControl));
478 */ 333 memset(&BobCC, 0, sizeof(CallControl));
479 334
480 /* 335 /* Assume sending audio and video */
481 * Call and reject 336 {
482 */ 337 TOXAV_ERR_CALL rc;
483 { 338 toxav_call(AliceAV, 0, 48, 1000, &rc);
484 int step = 0; 339
485 int running = 1; 340 if (rc != TOXAV_ERR_CALL_OK) {
486 341 printf("toxav_call failed: %d\n", rc);
487 while (running) { 342 exit(1);
488 tox_iterate(bootstrap_node);
489 tox_iterate(Alice);
490 tox_iterate(Bob);
491
492 switch ( step ) {
493 case 0: /* Alice */
494 printf("Alice is calling...\n");
495 toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, &muhcaps, 10);
496 step++;
497 break;
498
499 case 1: /* Bob */
500 if (status_control.Bob.status == Ringing) {
501 printf("Bob rejects...\n");
502 toxav_reject(status_control.Bob.av, status_control.Bob.call_index, "Who likes D's anyway?");
503 step++;
504 }
505
506 break;
507
508 case 2: /* Wait for Both to have status ended */
509 if (status_control.Alice.status == Rejected && status_control.Bob.status == Ended) running = 0;
510
511 break;
512 } 343 }
513
514 c_sleep(20);
515 } 344 }
516 345
517 printf("\n"); 346 while (!BobCC.incoming)
518 } 347 iterate_tox(bootstrap, Alice, Bob);
519 348
520 349 /* At first try all stuff while in invalid state */
521 /* 350 assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL));
522 * Call and cancel 351 assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL));
523 */ 352 assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL));
524 { 353 assert(!toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO, NULL));
525 int step = 0; 354
526 int running = 1; 355 {
527 356 TOXAV_ERR_ANSWER rc;
528 while (running) { 357 toxav_answer(BobAV, 0, 48, 4000, &rc);
529 tox_iterate(bootstrap_node); 358
530 tox_iterate(Alice); 359 if (rc != TOXAV_ERR_ANSWER_OK) {
531 tox_iterate(Bob); 360 printf("toxav_answer failed: %d\n", rc);
532 361 exit(1);
533 toxav_do(status_control.Alice.av);
534 toxav_do(status_control.Bob.av);
535
536
537 switch ( step ) {
538 case 0: /* Alice */
539 printf("Alice is calling...\n");
540 toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, &muhcaps, 10);
541 step++;
542 break;
543
544
545 case 1: /* Alice again */
546 if (status_control.Bob.status == Ringing) {
547 printf("Alice cancels...\n");
548 toxav_cancel(status_control.Alice.av, status_control.Alice.call_index, 0, "Who likes D's anyway?");
549 step++;
550 }
551
552 break;
553
554 case 2: /* Wait for Both to have status ended */
555 if (status_control.Bob.status == Canceled) running = 0;
556
557 break;
558 } 362 }
559
560 c_sleep(20);
561 } 363 }
562 364
563 printf("\n"); 365 iterate_tox(bootstrap, Alice, Bob);
564 } 366
565 367 /* Pause and Resume */
566 /* 368 printf("Pause and Resume\n");
567 * Timeout 369 assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE, NULL));
568 */ 370 iterate_tox(bootstrap, Alice, Bob);
569 { 371 assert(BobCC.state == TOXAV_CALL_STATE_PAUSED);
570 int step = 0; 372 assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME, NULL));
571 int running = 1; 373 iterate_tox(bootstrap, Alice, Bob);
572 374 assert(BobCC.state & (TOXAV_CALL_STATE_SENDING_A | TOXAV_CALL_STATE_SENDING_V));
573 while (running) { 375
574 tox_iterate(bootstrap_node); 376 /* Mute/Unmute single */
575 tox_iterate(Alice); 377 printf("Mute/Unmute single\n");
576 tox_iterate(Bob); 378 assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL));
577 379 iterate_tox(bootstrap, Alice, Bob);
578 toxav_do(status_control.Alice.av); 380 assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_A);
579 toxav_do(status_control.Bob.av); 381 assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL));
580 382 iterate_tox(bootstrap, Alice, Bob);
581 switch ( step ) { 383 assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_A);
582 case 0: 384
583 printf("Alice is calling...\n"); 385 /* Mute/Unmute both */
584 toxav_call(status_control.Alice.av, &status_control.Alice.call_index, 0, &muhcaps, 10); 386 printf("Mute/Unmute both\n");
585 step++; 387 assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL));
586 break; 388 iterate_tox(bootstrap, Alice, Bob);
587 389 assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_A);
588 case 1: 390 assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO, NULL));
589 if (status_control.Alice.status == TimedOut) running = 0; 391 iterate_tox(bootstrap, Alice, Bob);
590 392 assert(BobCC.state ^ TOXAV_CALL_STATE_RECEIVING_V);
591 break; 393 assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_AUDIO, NULL));
394 iterate_tox(bootstrap, Alice, Bob);
395 assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_A);
396 assert(toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_TOGGLE_MUTE_VIDEO, NULL));
397 iterate_tox(bootstrap, Alice, Bob);
398 assert(BobCC.state & TOXAV_CALL_STATE_RECEIVING_V);
399
400 {
401 TOXAV_ERR_CALL_CONTROL rc;
402 toxav_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_CANCEL, &rc);
403
404 if (rc != TOXAV_ERR_CALL_CONTROL_OK) {
405 printf("toxav_call_control failed: %d\n", rc);
406 exit(1);
592 } 407 }
593
594 c_sleep(20);
595 } 408 }
596 409
597 printf("\n"); 410 iterate_tox(bootstrap, Alice, Bob);
411 assert(BobCC.state == TOXAV_CALL_STATE_END);
412
413 printf("Success!\n");
598 } 414 }
599 415
600 vpx_img_free(sample_image); 416 toxav_kill(BobAV);
601 toxav_kill(status_control.Alice.av); 417 toxav_kill(AliceAV);
602 toxav_kill(status_control.Bob.av);
603 tox_kill(bootstrap_node);
604 tox_kill(Alice);
605 tox_kill(Bob); 418 tox_kill(Bob);
606 419 tox_kill(Alice);
607 printf("Calls ended!\n"); 420 tox_kill(bootstrap);
421
422 printf("\nTest successful!\n");
608} 423}
609END_TEST 424END_TEST
610 425
611/*************************************************************************************************/
612
613
614/*************************************************************************************************/
615
616/*************************************************************************************************/
617
618 426
619Suite *tox_suite(void) 427Suite *tox_suite(void)
620{ 428{
621 Suite *s = suite_create("ToxAV"); 429 Suite *s = suite_create("ToxAV");
622 430
623 DEFTESTCASE_SLOW(AV_flows, 200); 431 DEFTESTCASE_SLOW(AV_flows, 200);
624
625 return s; 432 return s;
626} 433}
627int main(int argc, char *argv[]) 434int main(int argc, char *argv[])
@@ -637,6 +444,4 @@ int main(int argc, char *argv[])
637 srunner_free(test_runner); 444 srunner_free(test_runner);
638 445
639 return number_failed; 446 return number_failed;
640
641// return test_AV_flows();
642} 447}
diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c
index 4287118f..ef59b2b2 100644
--- a/auto_tests/toxav_many_test.c
+++ b/auto_tests/toxav_many_test.c
@@ -14,6 +14,7 @@
14#include <vpx/vpx_image.h> 14#include <vpx/vpx_image.h>
15 15
16#include "../toxcore/tox.h" 16#include "../toxcore/tox.h"
17#include "../toxcore/util.h"
17#include "../toxcore/logger.h" 18#include "../toxcore/logger.h"
18#include "../toxcore/crypto_core.h" 19#include "../toxcore/crypto_core.h"
19#include "../toxav/toxav.h" 20#include "../toxav/toxav.h"
@@ -26,359 +27,177 @@
26#define c_sleep(x) usleep(1000*x) 27#define c_sleep(x) usleep(1000*x)
27#endif 28#endif
28 29
29pthread_mutex_t muhmutex;
30 30
31typedef enum _CallStatus { 31typedef struct {
32 none, 32 bool incoming;
33 InCall, 33 uint32_t state;
34 Ringing, 34
35 Ended, 35} CallControl;
36 Rejected,
37 Canceled
38 36
39} CallStatus;
40 37
41typedef struct _Party { 38/**
42 CallStatus status; 39 * Callbacks
43 ToxAv *av; 40 */
44 int id; 41void t_toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled, bool video_enabled, void *user_data)
45} Party;
46
47typedef struct _ACall {
48 pthread_t tid;
49 int idx;
50
51 Party Caller;
52 Party Callee;
53} ACall;
54
55typedef struct _Status {
56 ACall calls[3]; /* Make 3 calls for this test */
57} Status;
58
59Status status_control;
60
61void accept_friend_request(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
62{
63 if (length == 7 && memcmp("gentoo", data, 7) == 0) {
64 tox_friend_add_norequest(m, public_key, 0);
65 }
66}
67
68
69/******************************************************************************/
70void callback_recv_invite ( void *av, int32_t call_index, void *_arg )
71{ 42{
72 Status *cast = _arg; 43 printf("Handling CALL callback\n");
73 cast->calls[call_index].Callee.status = Ringing; 44 ((CallControl*)user_data)->incoming = true;
74} 45}
75void callback_recv_ringing ( void *av, int32_t call_index, void *_arg ) 46void t_toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t state, void *user_data)
76{ 47{
77 Status *cast = _arg; 48 printf("Handling CALL STATE callback: %d\n", state);
78 cast->calls[call_index].Caller.status = Ringing; 49 ((CallControl*)user_data)->state = state;
79} 50}
80void callback_call_ended ( void *av, int32_t call_index, void *_arg ) 51void t_toxav_receive_video_frame_cb(ToxAV *av, uint32_t friend_number,
52 uint16_t width, uint16_t height,
53 uint8_t const *y, uint8_t const *u, uint8_t const *v,
54 int32_t ystride, int32_t ustride, int32_t vstride,
55 void *user_data)
81{ 56{
82 Status *cast = _arg; 57 (void) av;
83 58 (void) friend_number;
84 if (av == cast->calls[call_index].Caller.av) 59 (void) width;
85 cast->calls[call_index].Caller.status = Ended; 60 (void) height;
86 else 61 (void) y;
87 cast->calls[call_index].Callee.status = Ended; 62 (void) u;
63 (void) v;
64 (void) ystride;
65 (void) ustride;
66 (void) vstride;
67 (void) user_data;
88} 68}
89void callback_call_started ( void *av, int32_t call_index, void *_arg ) 69void t_toxav_receive_audio_frame_cb(ToxAV *av, uint32_t friend_number,
70 int16_t const *pcm,
71 size_t sample_count,
72 uint8_t channels,
73 uint32_t sampling_rate,
74 void *user_data)
90{ 75{
91 Status *cast = _arg; 76 (void) av;
92 77 (void) friend_number;
93 if (av == cast->calls[call_index].Caller.av) 78 (void) pcm;
94 cast->calls[call_index].Caller.status = InCall; 79 (void) sample_count;
95 else 80 (void) channels;
96 cast->calls[call_index].Callee.status = InCall; 81 (void) sampling_rate;
82 (void) user_data;
97} 83}
98void callback_call_canceled ( void *av, int32_t call_index, void *_arg ) 84void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const uint8_t *data, size_t length, void *userdata)
99{ 85{
86 if (length == 7 && memcmp("gentoo", data, 7) == 0) {
87 assert(tox_friend_add_norequest(m, public_key, NULL) != (uint32_t) ~0);
88 }
100} 89}
101void callback_call_rejected ( void *av, int32_t call_index, void *_arg )
102{
103 Status *cast = _arg;
104 cast->calls[call_index].Caller.status = Rejected;
105}
106
107void callback_requ_timeout ( void *av, int32_t call_index, void *_arg )
108{
109 ck_assert_msg(0, "No answer!");
110}
111
112void callback_audio (void *agent, int32_t call_idx, const int16_t *PCM, uint16_t size, void *data)
113{}
114 90
115void callback_video (void *agent, int32_t call_idx, const vpx_image_t *img, void *data)
116{}
117 91
118void register_callbacks(ToxAv *av, void *data) 92/**
93 * Iterate helper
94 */
95ToxAV* setup_av_instance(Tox* tox, CallControl *CC)
119{ 96{
120 toxav_register_callstate_callback(av, callback_call_started, av_OnStart, data); 97 TOXAV_ERR_NEW error;
121 toxav_register_callstate_callback(av, callback_call_canceled, av_OnCancel, data); 98
122 toxav_register_callstate_callback(av, callback_call_rejected, av_OnReject, data); 99 ToxAV* av = toxav_new(tox, &error);
123 toxav_register_callstate_callback(av, callback_call_ended, av_OnEnd, data); 100 assert(error == TOXAV_ERR_NEW_OK);
124 toxav_register_callstate_callback(av, callback_recv_invite, av_OnInvite, data); 101
125 toxav_register_callstate_callback(av, callback_recv_ringing, av_OnRinging, data); 102 toxav_callback_call(av, t_toxav_call_cb, CC);
126 toxav_register_callstate_callback(av, callback_requ_timeout, av_OnRequestTimeout, data); 103 toxav_callback_call_state(av, t_toxav_call_state_cb, CC);
127 104 toxav_callback_receive_video_frame(av, t_toxav_receive_video_frame_cb, CC);
128 105 toxav_callback_receive_audio_frame(av, t_toxav_receive_audio_frame_cb, CC);
129 toxav_register_audio_callback(av, callback_audio, NULL); 106
130 toxav_register_video_callback(av, callback_video, NULL); 107 return av;
131} 108}
132/*************************************************************************************************/ 109void* call_thread(ToxAV* Alice, ToxAV* Bob)
133
134int call_running[3];
135
136void *in_thread_call (void *arg)
137{ 110{
138#define call_print(call, what, args...) printf("[%d] " what "\n", call, ##args)
139
140 ACall *this_call = arg;
141 uint64_t start = 0;
142 int step = 0;
143 int call_idx;
144
145 const int frame_size = (av_DefaultSettings.audio_sample_rate * av_DefaultSettings.audio_frame_duration / 1000);
146 int16_t sample_payload[frame_size];
147 randombytes((uint8_t *)sample_payload, sizeof(int16_t) * frame_size);
148
149 uint8_t prepared_payload[RTP_PAYLOAD_SIZE];
150
151 register_callbacks(this_call->Caller.av, &status_control);
152 register_callbacks(this_call->Callee.av, arg);
153
154 /* NOTE: CALLEE WILL ALWAHYS NEED CALL_IDX == 0 */
155 pthread_mutex_lock(&muhmutex);
156
157 while (call_running[this_call->idx]) {
158
159 pthread_mutex_unlock(&muhmutex);
160
161 switch ( step ) {
162 case 0: /* CALLER */
163 toxav_call(this_call->Caller.av, &call_idx, this_call->Callee.id, &av_DefaultSettings, 10);
164 call_print(call_idx, "Calling ...");
165 step++;
166 break;
167
168 case 1: /* CALLEE */
169 pthread_mutex_lock(&muhmutex);
170
171 if (this_call->Caller.status == Ringing) {
172 call_print(call_idx, "Callee answers ...");
173 pthread_mutex_unlock(&muhmutex);
174 toxav_answer(this_call->Callee.av, 0, &av_DefaultSettings);
175 step++;
176 start = time(NULL);
177 pthread_mutex_lock(&muhmutex);
178 }
179
180 pthread_mutex_unlock(&muhmutex);
181 break;
182
183 case 2: /* Rtp transmission */
184 pthread_mutex_lock(&muhmutex);
185
186 if (this_call->Caller.status == InCall) { /* I think this is okay */
187 call_print(call_idx, "Sending rtp ...");
188 pthread_mutex_unlock(&muhmutex);
189
190 c_sleep(1000); /* We have race condition here */
191 toxav_prepare_transmission(this_call->Callee.av, 0, 1);
192 toxav_prepare_transmission(this_call->Caller.av, call_idx, 1);
193
194 int payload_size = toxav_prepare_audio_frame(this_call->Caller.av, call_idx, prepared_payload, RTP_PAYLOAD_SIZE,
195 sample_payload, frame_size);
196
197 if ( payload_size < 0 ) {
198 ck_assert_msg ( 0, "Failed to encode payload" );
199 }
200
201
202 while (time(NULL) - start < 10) { /* 10 seconds */
203 /* Both send */
204 toxav_send_audio(this_call->Caller.av, call_idx, prepared_payload, payload_size);
205
206 toxav_send_audio(this_call->Callee.av, 0, prepared_payload, payload_size);
207
208 /* Both receive */
209 int16_t storage[RTP_PAYLOAD_SIZE];
210 int recved;
211
212 c_sleep(20);
213 }
214
215 step++; /* This terminates the loop */
216
217 pthread_mutex_lock(&muhmutex);
218 toxav_kill_transmission(this_call->Callee.av, 0);
219 toxav_kill_transmission(this_call->Caller.av, call_idx);
220 pthread_mutex_unlock(&muhmutex);
221
222 /* Call over CALLER hangs up */
223 toxav_hangup(this_call->Caller.av, call_idx);
224 call_print(call_idx, "Hanging up ...");
225
226 pthread_mutex_lock(&muhmutex);
227 }
228
229 pthread_mutex_unlock(&muhmutex);
230 break;
231
232 case 3: /* Wait for Both to have status ended */
233 pthread_mutex_lock(&muhmutex);
234
235 if (this_call->Caller.status == Ended) {
236 pthread_mutex_unlock(&muhmutex);
237 c_sleep(1000); /* race condition */
238 pthread_mutex_lock(&muhmutex);
239 this_call->Callee.status = Ended;
240 call_running[this_call->idx] = 0;
241 }
242
243 pthread_mutex_unlock(&muhmutex);
244
245 break;
246
247 }
248
249 c_sleep(20);
250
251 pthread_mutex_lock(&muhmutex);
252 }
253
254 pthread_mutex_unlock(&muhmutex);
255 call_print(call_idx, "Call ended successfully!");
256 pthread_exit(NULL); 111 pthread_exit(NULL);
257} 112}
258 113
259
260
261
262
263START_TEST(test_AV_three_calls) 114START_TEST(test_AV_three_calls)
264// void test_AV_three_calls()
265{ 115{
266 long long unsigned int cur_time = time(NULL); 116 Tox* Alice, *bootstrap, *Bobs[3];
267 Tox *bootstrap_node = tox_new(0, 0, 0, 0); 117 ToxAV* AliceAV, *BobsAV[3];
268 Tox *caller = tox_new(0, 0, 0, 0); 118
269 Tox *callees[3] = { 119 CallControl AliceCC[3], BobsCC[3];
270 tox_new(0, 0, 0, 0), 120
271 tox_new(0, 0, 0, 0),
272 tox_new(0, 0, 0, 0),
273 };
274
275
276 ck_assert_msg(bootstrap_node != NULL, "Failed to create bootstrap node");
277
278 int i = 0; 121 int i = 0;
279 122 {
280 for (; i < 3; i ++) { 123 TOX_ERR_NEW error;
281 ck_assert_msg(callees[i] != NULL, "Failed to create 3 tox instances"); 124
282 } 125 bootstrap = tox_new(NULL, NULL, 0, &error);
283 126 assert(error == TOX_ERR_NEW_OK);
284 for ( i = 0; i < 3; i ++ ) { 127
285 uint32_t to_compare = 974536; 128 Alice = tox_new(NULL, NULL, 0, &error);
286 tox_callback_friend_request(callees[i], accept_friend_request, &to_compare); 129 assert(error == TOX_ERR_NEW_OK);
287 uint8_t address[TOX_ADDRESS_SIZE]; 130
288 tox_self_get_address(callees[i], address); 131 for (; i < 3; i ++) {
289 132 BobsAV[i] = tox_new(NULL, NULL, 0, &error);
290 uint32_t test = tox_friend_add(caller, address, (uint8_t *)"gentoo", 7, 0); 133 assert(error == TOX_ERR_NEW_OK);
291 ck_assert_msg( test == i, "Failed to add friend error code: %i", test); 134 }
292 } 135 }
293 136
137 printf("Created 5 instances of Tox\n");
138 printf("Preparing network...\n");
139 long long unsigned int cur_time = time(NULL);
140
141 uint32_t to_compare = 974536;
142 uint8_t address[TOX_ADDRESS_SIZE];
143
144 tox_callback_friend_request(Alice, t_accept_friend_request_cb, &to_compare);
145 tox_self_get_address(Alice, address);
146
147
148 assert(tox_friend_add(Bobs[0], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0);
149 assert(tox_friend_add(Bobs[1], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0);
150 assert(tox_friend_add(Bobs[2], address, (uint8_t *)"gentoo", 7, NULL) != (uint32_t) ~0);
151
294 uint8_t off = 1; 152 uint8_t off = 1;
295 153
296 while (1) { 154 while (1) {
297 tox_iterate(bootstrap_node); 155 tox_iterate(bootstrap);
298 tox_iterate(caller); 156 tox_iterate(Alice);
299 157 tox_iterate(Bobs[0]);
300 for (i = 0; i < 3; i ++) { 158 tox_iterate(Bobs[1]);
301 tox_iterate(callees[i]); 159 tox_iterate(Bobs[2]);
302 } 160
303 161 if (tox_self_get_connection_status(bootstrap) &&
304 162 tox_self_get_connection_status(Alice) &&
305 if (tox_self_get_connection_status(bootstrap_node) && 163 tox_self_get_connection_status(Bobs[0]) &&
306 tox_self_get_connection_status(caller) && 164 tox_self_get_connection_status(Bobs[1]) &&
307 tox_self_get_connection_status(callees[0]) && 165 tox_self_get_connection_status(Bobs[2]) && off) {
308 tox_self_get_connection_status(callees[1]) &&
309 tox_self_get_connection_status(callees[2]) && off) {
310 printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time); 166 printf("Toxes are online, took %llu seconds\n", time(NULL) - cur_time);
311 off = 0; 167 off = 0;
312 } 168 }
313 169
314 170 if (tox_friend_get_connection_status(Alice, 0, NULL) == TOX_CONNECTION_UDP &&
315 if (tox_friend_get_connection_status(caller, 0, 0) && 171 tox_friend_get_connection_status(Alice, 1, NULL) == TOX_CONNECTION_UDP &&
316 tox_friend_get_connection_status(caller, 1, 0) && 172 tox_friend_get_connection_status(Alice, 2, NULL) == TOX_CONNECTION_UDP &&
317 tox_friend_get_connection_status(caller, 2, 0) ) 173 tox_friend_get_connection_status(Bobs[0], 0, NULL) == TOX_CONNECTION_UDP &&
174 tox_friend_get_connection_status(Bobs[1], 0, NULL) == TOX_CONNECTION_UDP &&
175 tox_friend_get_connection_status(Bobs[2], 0, NULL) == TOX_CONNECTION_UDP)
318 break; 176 break;
319 177
320 c_sleep(20); 178 c_sleep(20);
321 } 179 }
322 180
323 printf("All set after %llu seconds! Starting call...\n", time(NULL) - cur_time); 181 AliceAV = setup_av_instance(Alice, &AliceCC);
324 182 BobsAV[0] = setup_av_instance(Bobs[0], &BobsCC[0]);
325 ToxAv *uniqcallerav = toxav_new(caller, 3); 183 BobsAV[1] = setup_av_instance(Bobs[1], &BobsCC[1]);
326 184 BobsAV[2] = setup_av_instance(Bobs[2], &BobsCC[2]);
185
186 printf("Created 4 instances of ToxAV\n");
187 printf("All set after %llu seconds!\n", time(NULL) - cur_time);
188
189
190
191 tox_kill(bootstrap);
192 tox_kill(Alice);
193 toxav_kill(AliceAV);
194
327 for (i = 0; i < 3; i ++) { 195 for (i = 0; i < 3; i ++) {
328 status_control.calls[i].idx = i; 196 tox_kill(Bobs[i]);
329 197 toxav_kill(BobsAV[i]);
330 status_control.calls[i].Caller.av = uniqcallerav;
331 status_control.calls[i].Caller.id = 0;
332 status_control.calls[i].Caller.status = none;
333
334 status_control.calls[i].Callee.av = toxav_new(callees[i], 1);
335 status_control.calls[i].Callee.id = i;
336 status_control.calls[i].Callee.status = none;
337 } 198 }
338 199
339 pthread_mutex_init(&muhmutex, NULL); 200 printf("\nTest successful!\n");
340
341 for ( i = 0; i < 3; i++ ) {
342 call_running[i] = 1;
343 pthread_create(&status_control.calls[i].tid, NULL, in_thread_call, &status_control.calls[i]);
344 }
345
346 /* Now start 3 calls and they'll run for 10 s */
347
348 for ( i = 0; i < 3; i++ )
349 pthread_detach(status_control.calls[i].tid);
350
351 while (call_running[0] || call_running[1] || call_running[2]) {
352 pthread_mutex_lock(&muhmutex);
353
354 tox_iterate(bootstrap_node);
355 tox_iterate(caller);
356 tox_iterate(callees[0]);
357 tox_iterate(callees[1]);
358 tox_iterate(callees[2]);
359
360 for ( i = 0; i < 3; i++ )
361 toxav_do(status_control.calls[0].Caller.av);
362
363 toxav_do(status_control.calls[0].Callee.av);
364 toxav_do(status_control.calls[1].Callee.av);
365 toxav_do(status_control.calls[2].Callee.av);
366
367 pthread_mutex_unlock(&muhmutex);
368 c_sleep(20);
369 }
370
371 toxav_kill(status_control.calls[0].Caller.av);
372 toxav_kill(status_control.calls[0].Callee.av);
373 toxav_kill(status_control.calls[1].Callee.av);
374 toxav_kill(status_control.calls[2].Callee.av);
375
376 tox_kill(bootstrap_node);
377 tox_kill(caller);
378
379 for ( i = 0; i < 3; i ++)
380 tox_kill(callees[i]);
381
382} 201}
383END_TEST 202END_TEST
384 203
@@ -410,8 +229,4 @@ int main(int argc, char *argv[])
410 srunner_free(test_runner); 229 srunner_free(test_runner);
411 230
412 return number_failed; 231 return number_failed;
413
414// test_AV_three_calls();
415
416// return 0;
417} 232}