summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--auto_tests/toxav_basic_test.c80
-rw-r--r--auto_tests/toxav_many_test.c38
-rw-r--r--other/apidsl/tox.in.h4
-rw-r--r--other/apidsl/toxav.in.h12
-rw-r--r--other/toktok-rebase48
-rw-r--r--testing/av_test.c53
-rw-r--r--toxav/audio.c13
-rw-r--r--toxav/audio.h6
-rw-r--r--toxav/bwcontroller.c21
-rw-r--r--toxav/bwcontroller.h4
-rw-r--r--toxav/msi.c50
-rw-r--r--toxav/msi.h2
-rw-r--r--toxav/rtp.c6
-rw-r--r--toxav/toxav.c124
-rw-r--r--toxav/toxav.h12
-rw-r--r--toxav/video.c15
-rw-r--r--toxav/video.h6
-rw-r--r--toxcore/Messenger.c24
-rw-r--r--toxcore/Messenger.h19
-rw-r--r--toxcore/tox.h4
-rw-r--r--toxcore/util.h1
21 files changed, 232 insertions, 310 deletions
diff --git a/auto_tests/toxav_basic_test.c b/auto_tests/toxav_basic_test.c
index 3904141f..da874849 100644
--- a/auto_tests/toxav_basic_test.c
+++ b/auto_tests/toxav_basic_test.c
@@ -133,12 +133,12 @@ static void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const
133/** 133/**
134 * Iterate helper 134 * Iterate helper
135 */ 135 */
136static int iterate_tox(Tox *bootstrap, Tox *Alice, void *ACC, Tox *Bob, void *BCC) 136static int iterate_tox(Tox *bootstrap, Tox *Alice, Tox *Bob)
137{ 137{
138 c_sleep(100); 138 c_sleep(100);
139 tox_iterate(bootstrap, NULL); 139 tox_iterate(bootstrap, NULL);
140 tox_iterate(Alice, ACC); 140 tox_iterate(Alice, NULL);
141 tox_iterate(Bob, BCC); 141 tox_iterate(Bob, NULL);
142 142
143 return MIN(tox_iteration_interval(Alice), tox_iteration_interval(Bob)); 143 return MIN(tox_iteration_interval(Alice), tox_iteration_interval(Bob));
144} 144}
@@ -181,7 +181,7 @@ START_TEST(test_AV_flows)
181 uint8_t off = 1; 181 uint8_t off = 1;
182 182
183 while (1) { 183 while (1) {
184 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 184 iterate_tox(bootstrap, Alice, Bob);
185 185
186 if (tox_self_get_connection_status(bootstrap) && 186 if (tox_self_get_connection_status(bootstrap) &&
187 tox_self_get_connection_status(Alice) && 187 tox_self_get_connection_status(Alice) &&
@@ -208,15 +208,15 @@ START_TEST(test_AV_flows)
208 ck_assert(error == TOXAV_ERR_NEW_OK); 208 ck_assert(error == TOXAV_ERR_NEW_OK);
209 } 209 }
210 210
211 toxav_callback_call(AliceAV, t_toxav_call_cb); 211 toxav_callback_call(AliceAV, t_toxav_call_cb, &AliceCC);
212 toxav_callback_call_state(AliceAV, t_toxav_call_state_cb); 212 toxav_callback_call_state(AliceAV, t_toxav_call_state_cb, &AliceCC);
213 toxav_callback_video_receive_frame(AliceAV, t_toxav_receive_video_frame_cb); 213 toxav_callback_video_receive_frame(AliceAV, t_toxav_receive_video_frame_cb, &AliceCC);
214 toxav_callback_audio_receive_frame(AliceAV, t_toxav_receive_audio_frame_cb); 214 toxav_callback_audio_receive_frame(AliceAV, t_toxav_receive_audio_frame_cb, &AliceCC);
215 215
216 toxav_callback_call(BobAV, t_toxav_call_cb); 216 toxav_callback_call(BobAV, t_toxav_call_cb, &BobCC);
217 toxav_callback_call_state(BobAV, t_toxav_call_state_cb); 217 toxav_callback_call_state(BobAV, t_toxav_call_state_cb, &BobCC);
218 toxav_callback_video_receive_frame(BobAV, t_toxav_receive_video_frame_cb); 218 toxav_callback_video_receive_frame(BobAV, t_toxav_receive_video_frame_cb, &BobCC);
219 toxav_callback_audio_receive_frame(BobAV, t_toxav_receive_audio_frame_cb); 219 toxav_callback_audio_receive_frame(BobAV, t_toxav_receive_audio_frame_cb, &BobCC);
220 220
221 printf("Created 2 instances of ToxAV\n"); 221 printf("Created 2 instances of ToxAV\n");
222 printf("All set after %llu seconds!\n", time(NULL) - cur_time); 222 printf("All set after %llu seconds!\n", time(NULL) - cur_time);
@@ -265,7 +265,7 @@ START_TEST(test_AV_flows)
265 } \ 265 } \
266 } \ 266 } \
267 \ 267 \
268 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); \ 268 iterate_tox(bootstrap, Alice, Bob); \
269 } \ 269 } \
270 printf("Success!\n");\ 270 printf("Success!\n");\
271 } while(0) 271 } while(0)
@@ -304,7 +304,7 @@ START_TEST(test_AV_flows)
304 } 304 }
305 305
306 while (!BobCC.incoming) { 306 while (!BobCC.incoming) {
307 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 307 iterate_tox(bootstrap, Alice, Bob);
308 } 308 }
309 309
310 /* Reject */ 310 /* Reject */
@@ -319,7 +319,7 @@ START_TEST(test_AV_flows)
319 } 319 }
320 320
321 while (AliceCC.state != TOXAV_FRIEND_CALL_STATE_FINISHED) { 321 while (AliceCC.state != TOXAV_FRIEND_CALL_STATE_FINISHED) {
322 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 322 iterate_tox(bootstrap, Alice, Bob);
323 } 323 }
324 324
325 printf("Success!\n"); 325 printf("Success!\n");
@@ -342,7 +342,7 @@ START_TEST(test_AV_flows)
342 } 342 }
343 343
344 while (!BobCC.incoming) { 344 while (!BobCC.incoming) {
345 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 345 iterate_tox(bootstrap, Alice, Bob);
346 } 346 }
347 347
348 /* Cancel */ 348 /* Cancel */
@@ -358,7 +358,7 @@ START_TEST(test_AV_flows)
358 358
359 /* Alice will not receive end state */ 359 /* Alice will not receive end state */
360 while (BobCC.state != TOXAV_FRIEND_CALL_STATE_FINISHED) { 360 while (BobCC.state != TOXAV_FRIEND_CALL_STATE_FINISHED) {
361 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 361 iterate_tox(bootstrap, Alice, Bob);
362 } 362 }
363 363
364 printf("Success!\n"); 364 printf("Success!\n");
@@ -382,7 +382,7 @@ START_TEST(test_AV_flows)
382 } 382 }
383 383
384 while (!BobCC.incoming) { 384 while (!BobCC.incoming) {
385 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 385 iterate_tox(bootstrap, Alice, Bob);
386 } 386 }
387 387
388 /* At first try all stuff while in invalid state */ 388 /* At first try all stuff while in invalid state */
@@ -403,39 +403,39 @@ START_TEST(test_AV_flows)
403 } 403 }
404 } 404 }
405 405
406 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 406 iterate_tox(bootstrap, Alice, Bob);
407 407
408 /* Pause and Resume */ 408 /* Pause and Resume */
409 printf("Pause and Resume\n"); 409 printf("Pause and Resume\n");
410 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE); 410 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE);
411 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 411 iterate_tox(bootstrap, Alice, Bob);
412 ck_assert(BobCC.state == 0); 412 ck_assert(BobCC.state == 0);
413 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME); 413 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME);
414 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 414 iterate_tox(bootstrap, Alice, Bob);
415 ck_assert(BobCC.state & (TOXAV_FRIEND_CALL_STATE_SENDING_A | TOXAV_FRIEND_CALL_STATE_SENDING_V)); 415 ck_assert(BobCC.state & (TOXAV_FRIEND_CALL_STATE_SENDING_A | TOXAV_FRIEND_CALL_STATE_SENDING_V));
416 416
417 /* Mute/Unmute single */ 417 /* Mute/Unmute single */
418 printf("Mute/Unmute single\n"); 418 printf("Mute/Unmute single\n");
419 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO); 419 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO);
420 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 420 iterate_tox(bootstrap, Alice, Bob);
421 ck_assert(BobCC.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); 421 ck_assert(BobCC.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_A);
422 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO); 422 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO);
423 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 423 iterate_tox(bootstrap, Alice, Bob);
424 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); 424 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A);
425 425
426 /* Mute/Unmute both */ 426 /* Mute/Unmute both */
427 printf("Mute/Unmute both\n"); 427 printf("Mute/Unmute both\n");
428 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO); 428 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_MUTE_AUDIO);
429 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 429 iterate_tox(bootstrap, Alice, Bob);
430 ck_assert(BobCC.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); 430 ck_assert(BobCC.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_A);
431 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_HIDE_VIDEO); 431 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_HIDE_VIDEO);
432 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 432 iterate_tox(bootstrap, Alice, Bob);
433 ck_assert(BobCC.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_V); 433 ck_assert(BobCC.state ^ TOXAV_FRIEND_CALL_STATE_ACCEPTING_V);
434 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO); 434 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_UNMUTE_AUDIO);
435 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 435 iterate_tox(bootstrap, Alice, Bob);
436 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A); 436 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_A);
437 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_SHOW_VIDEO); 437 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_SHOW_VIDEO);
438 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 438 iterate_tox(bootstrap, Alice, Bob);
439 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V); 439 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_ACCEPTING_V);
440 440
441 { 441 {
@@ -448,7 +448,7 @@ START_TEST(test_AV_flows)
448 } 448 }
449 } 449 }
450 450
451 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 451 iterate_tox(bootstrap, Alice, Bob);
452 ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); 452 ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED);
453 453
454 printf("Success!\n"); 454 printf("Success!\n");
@@ -472,7 +472,7 @@ START_TEST(test_AV_flows)
472 } 472 }
473 473
474 while (!BobCC.incoming) { 474 while (!BobCC.incoming) {
475 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 475 iterate_tox(bootstrap, Alice, Bob);
476 } 476 }
477 477
478 { 478 {
@@ -485,25 +485,25 @@ START_TEST(test_AV_flows)
485 } 485 }
486 } 486 }
487 487
488 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 488 iterate_tox(bootstrap, Alice, Bob);
489 489
490 printf("Call started as audio only\n"); 490 printf("Call started as audio only\n");
491 printf("Turning on video for Alice...\n"); 491 printf("Turning on video for Alice...\n");
492 ck_assert(toxav_bit_rate_set(AliceAV, 0, -1, 1000, NULL)); 492 ck_assert(toxav_bit_rate_set(AliceAV, 0, -1, 1000, NULL));
493 493
494 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 494 iterate_tox(bootstrap, Alice, Bob);
495 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V); 495 ck_assert(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V);
496 496
497 printf("Turning off video for Alice...\n"); 497 printf("Turning off video for Alice...\n");
498 ck_assert(toxav_bit_rate_set(AliceAV, 0, -1, 0, NULL)); 498 ck_assert(toxav_bit_rate_set(AliceAV, 0, -1, 0, NULL));
499 499
500 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 500 iterate_tox(bootstrap, Alice, Bob);
501 ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V)); 501 ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_V));
502 502
503 printf("Turning off audio for Alice...\n"); 503 printf("Turning off audio for Alice...\n");
504 ck_assert(toxav_bit_rate_set(AliceAV, 0, 0, -1, NULL)); 504 ck_assert(toxav_bit_rate_set(AliceAV, 0, 0, -1, NULL));
505 505
506 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 506 iterate_tox(bootstrap, Alice, Bob);
507 ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_A)); 507 ck_assert(!(BobCC.state & TOXAV_FRIEND_CALL_STATE_SENDING_A));
508 508
509 { 509 {
@@ -516,7 +516,7 @@ START_TEST(test_AV_flows)
516 } 516 }
517 } 517 }
518 518
519 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 519 iterate_tox(bootstrap, Alice, Bob);
520 ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); 520 ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED);
521 521
522 printf("Success!\n"); 522 printf("Success!\n");
@@ -540,7 +540,7 @@ START_TEST(test_AV_flows)
540 } 540 }
541 541
542 while (!BobCC.incoming) { 542 while (!BobCC.incoming) {
543 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 543 iterate_tox(bootstrap, Alice, Bob);
544 } 544 }
545 545
546 { 546 {
@@ -555,16 +555,16 @@ START_TEST(test_AV_flows)
555 555
556 int16_t PCM[5670]; 556 int16_t PCM[5670];
557 557
558 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 558 iterate_tox(bootstrap, Alice, Bob);
559 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE); 559 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_PAUSE);
560 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 560 iterate_tox(bootstrap, Alice, Bob);
561 ck_assert(!toxav_audio_send_frame(AliceAV, 0, PCM, 960, 1, 48000, NULL)); 561 ck_assert(!toxav_audio_send_frame(AliceAV, 0, PCM, 960, 1, 48000, NULL));
562 ck_assert(!toxav_audio_send_frame(BobAV, 0, PCM, 960, 1, 48000, NULL)); 562 ck_assert(!toxav_audio_send_frame(BobAV, 0, PCM, 960, 1, 48000, NULL));
563 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME); 563 ck_assert_call_control(AliceAV, 0, TOXAV_CALL_CONTROL_RESUME);
564 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 564 iterate_tox(bootstrap, Alice, Bob);
565 ck_assert(toxav_audio_send_frame(AliceAV, 0, PCM, 960, 1, 48000, NULL)); 565 ck_assert(toxav_audio_send_frame(AliceAV, 0, PCM, 960, 1, 48000, NULL));
566 ck_assert(toxav_audio_send_frame(BobAV, 0, PCM, 960, 1, 48000, NULL)); 566 ck_assert(toxav_audio_send_frame(BobAV, 0, PCM, 960, 1, 48000, NULL));
567 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 567 iterate_tox(bootstrap, Alice, Bob);
568 568
569 { 569 {
570 TOXAV_ERR_CALL_CONTROL rc; 570 TOXAV_ERR_CALL_CONTROL rc;
@@ -576,7 +576,7 @@ START_TEST(test_AV_flows)
576 } 576 }
577 } 577 }
578 578
579 iterate_tox(bootstrap, Alice, &AliceCC, Bob, &BobCC); 579 iterate_tox(bootstrap, Alice, Bob);
580 ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); 580 ck_assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED);
581 581
582 printf("Success!\n"); 582 printf("Success!\n");
diff --git a/auto_tests/toxav_many_test.c b/auto_tests/toxav_many_test.c
index a1688ac8..bdb5445b 100644
--- a/auto_tests/toxav_many_test.c
+++ b/auto_tests/toxav_many_test.c
@@ -113,17 +113,17 @@ static void t_accept_friend_request_cb(Tox *m, const uint8_t *public_key, const
113/** 113/**
114 * Iterate helper 114 * Iterate helper
115 */ 115 */
116static ToxAV *setup_av_instance(Tox *tox) 116static ToxAV *setup_av_instance(Tox *tox, CallControl *CC)
117{ 117{
118 TOXAV_ERR_NEW error; 118 TOXAV_ERR_NEW error;
119 119
120 ToxAV *av = toxav_new(tox, &error); 120 ToxAV *av = toxav_new(tox, &error);
121 ck_assert(error == TOXAV_ERR_NEW_OK); 121 ck_assert(error == TOXAV_ERR_NEW_OK);
122 122
123 toxav_callback_call(av, t_toxav_call_cb); 123 toxav_callback_call(av, t_toxav_call_cb, CC);
124 toxav_callback_call_state(av, t_toxav_call_state_cb); 124 toxav_callback_call_state(av, t_toxav_call_state_cb, CC);
125 toxav_callback_video_receive_frame(av, t_toxav_receive_video_frame_cb); 125 toxav_callback_video_receive_frame(av, t_toxav_receive_video_frame_cb, CC);
126 toxav_callback_audio_receive_frame(av, t_toxav_receive_audio_frame_cb); 126 toxav_callback_audio_receive_frame(av, t_toxav_receive_audio_frame_cb, CC);
127 127
128 return av; 128 return av;
129} 129}
@@ -172,8 +172,8 @@ static void *call_thread(void *pd)
172 time_t start_time = time(NULL); 172 time_t start_time = time(NULL);
173 173
174 while (time(NULL) - start_time < 4) { 174 while (time(NULL) - start_time < 4) {
175 toxav_iterate(AliceAV, &AliceCC); 175 toxav_iterate(AliceAV);
176 toxav_iterate(BobAV, &BobCC); 176 toxav_iterate(BobAV);
177 177
178 toxav_audio_send_frame(AliceAV, friend_number, PCM, 960, 1, 48000, NULL); 178 toxav_audio_send_frame(AliceAV, friend_number, PCM, 960, 1, 48000, NULL);
179 toxav_audio_send_frame(BobAV, 0, PCM, 960, 1, 48000, NULL); 179 toxav_audio_send_frame(BobAV, 0, PCM, 960, 1, 48000, NULL);
@@ -250,10 +250,10 @@ START_TEST(test_AV_three_calls)
250 250
251 while (1) { 251 while (1) {
252 tox_iterate(bootstrap, NULL); 252 tox_iterate(bootstrap, NULL);
253 tox_iterate(Alice, &AliceCC); 253 tox_iterate(Alice, NULL);
254 tox_iterate(Bobs[0], &BobsCC[0]); 254 tox_iterate(Bobs[0], NULL);
255 tox_iterate(Bobs[1], &BobsCC[1]); 255 tox_iterate(Bobs[1], NULL);
256 tox_iterate(Bobs[2], &BobsCC[2]); 256 tox_iterate(Bobs[2], NULL);
257 257
258 if (tox_self_get_connection_status(bootstrap) && 258 if (tox_self_get_connection_status(bootstrap) &&
259 tox_self_get_connection_status(Alice) && 259 tox_self_get_connection_status(Alice) &&
@@ -276,10 +276,10 @@ START_TEST(test_AV_three_calls)
276 c_sleep(20); 276 c_sleep(20);
277 } 277 }
278 278
279 AliceAV = setup_av_instance(Alice); 279 AliceAV = setup_av_instance(Alice, AliceCC);
280 BobsAV[0] = setup_av_instance(Bobs[0]); 280 BobsAV[0] = setup_av_instance(Bobs[0], BobsCC + 0);
281 BobsAV[1] = setup_av_instance(Bobs[1]); 281 BobsAV[1] = setup_av_instance(Bobs[1], BobsCC + 1);
282 BobsAV[2] = setup_av_instance(Bobs[2]); 282 BobsAV[2] = setup_av_instance(Bobs[2], BobsCC + 2);
283 283
284 printf("Created 4 instances of ToxAV\n"); 284 printf("Created 4 instances of ToxAV\n");
285 printf("All set after %llu seconds!\n", time(NULL) - cur_time); 285 printf("All set after %llu seconds!\n", time(NULL) - cur_time);
@@ -315,10 +315,10 @@ START_TEST(test_AV_three_calls)
315 time_t start_time = time(NULL); 315 time_t start_time = time(NULL);
316 316
317 while (time(NULL) - start_time < 5) { 317 while (time(NULL) - start_time < 5) {
318 tox_iterate(Alice, AliceCC); 318 tox_iterate(Alice, NULL);
319 tox_iterate(Bobs[0], &BobsCC[0]); 319 tox_iterate(Bobs[0], NULL);
320 tox_iterate(Bobs[1], &BobsCC[1]); 320 tox_iterate(Bobs[1], NULL);
321 tox_iterate(Bobs[2], &BobsCC[2]); 321 tox_iterate(Bobs[2], NULL);
322 c_sleep(20); 322 c_sleep(20);
323 } 323 }
324 324
diff --git a/other/apidsl/tox.in.h b/other/apidsl/tox.in.h
index b35dc38a..f3a06623 100644
--- a/other/apidsl/tox.in.h
+++ b/other/apidsl/tox.in.h
@@ -1089,10 +1089,6 @@ namespace friend {
1089 * function, this client will appear offline to the friend and no communication 1089 * function, this client will appear offline to the friend and no communication
1090 * can occur between the two. 1090 * can occur between the two.
1091 * 1091 *
1092 * WARNING, calling ${friend.delete} while there's an active ToxAV call will
1093 * result in undefined behavior. It's the client's responsibility to end all
1094 * ToxAV calls before deleting a friend.
1095 *
1096 * @param friend_number Friend number for the friend to be deleted. 1092 * @param friend_number Friend number for the friend to be deleted.
1097 * 1093 *
1098 * @return true on success. 1094 * @return true on success.
diff --git a/other/apidsl/toxav.in.h b/other/apidsl/toxav.in.h
index 67b670dc..8a7d5358 100644
--- a/other/apidsl/toxav.in.h
+++ b/other/apidsl/toxav.in.h
@@ -216,7 +216,7 @@ const uint32_t iteration_interval();
216 * toxav_iteration_interval() milliseconds. It is best called in the separate 216 * toxav_iteration_interval() milliseconds. It is best called in the separate
217 * thread from tox_iterate. 217 * thread from tox_iterate.
218 */ 218 */
219void iterate(any userdata); 219void iterate();
220 220
221 221
222/******************************************************************************* 222/*******************************************************************************
@@ -269,7 +269,7 @@ bool call(uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_ra
269 INVALID_BIT_RATE, 269 INVALID_BIT_RATE,
270} 270}
271 271
272event call const { 272event call {
273 /** 273 /**
274 * The function type for the ${event call} callback. 274 * The function type for the ${event call} callback.
275 * 275 *
@@ -359,7 +359,7 @@ bitmask FRIEND_CALL_STATE {
359 ACCEPTING_V, 359 ACCEPTING_V,
360} 360}
361 361
362event call_state const { 362event call_state {
363 /** 363 /**
364 * The function type for the ${event call_state} callback. 364 * The function type for the ${event call_state} callback.
365 * 365 *
@@ -490,7 +490,7 @@ namespace bit_rate {
490 FRIEND_NOT_IN_CALL, 490 FRIEND_NOT_IN_CALL,
491 } 491 }
492 492
493 event status const { 493 event status {
494 /** 494 /**
495 * The function type for the ${event status} callback. The event is triggered 495 * The function type for the ${event status} callback. The event is triggered
496 * when the network becomes too saturated for current bit rates at which 496 * when the network becomes too saturated for current bit rates at which
@@ -601,7 +601,7 @@ namespace video {
601 601
602 602
603namespace audio { 603namespace audio {
604 event receive_frame const { 604 event receive_frame {
605 /** 605 /**
606 * The function type for the ${event receive_frame} callback. The callback can be 606 * The function type for the ${event receive_frame} callback. The callback can be
607 * called multiple times per single iteration depending on the amount of queued 607 * called multiple times per single iteration depending on the amount of queued
@@ -620,7 +620,7 @@ namespace audio {
620} 620}
621 621
622namespace video { 622namespace video {
623 event receive_frame const { 623 event receive_frame {
624 /** 624 /**
625 * The function type for the ${event receive_frame} callback. 625 * The function type for the ${event receive_frame} callback.
626 * 626 *
diff --git a/other/toktok-rebase b/other/toktok-rebase
deleted file mode 100644
index c6f9f38a..00000000
--- a/other/toktok-rebase
+++ /dev/null
@@ -1,48 +0,0 @@
1#!/usr/bin/zsh
2
3if [[ $1 == '-v' ]]; then
4 set -u -x
5fi
6
7PREHEAD=`git rev-parse --abbrev-ref HEAD`
8TRGT=`git show-ref toktok/master --hash`
9EXCLD=`git branch --contains $TRGT`
10
11FAILED=()
12SUCCESS=()
13EXCLUDED=()
14
15echo "Auto Rebaseing!"
16git fetch --all > /dev/null 2>&1
17
18if [[ $1 == '-v' ]]; then
19 git branch --no-merged=toktok/master
20fi
21
22for i in `git branch --no-merged=toktok/master`; do
23 each=`echo $i | sed 's/*//'`
24
25 # quick exclude
26 if [[ ${EXCLD[(i)${each}]} -le ${#EXCLD} ]]; then
27 EXCLUDED+=$each
28 continue
29 fi
30
31 git checkout $each > /dev/null 2>&1
32 git rebase toktok/master > /dev/null 2>&1
33 if [[ $? != 0 ]]; then
34 git rebase --abort > /dev/null 2>&1
35 FAILED+=($each)
36 else
37 SUCCESS+=($each)
38 fi
39done
40
41echo "Was able to rebase (Don't forget to git push --force)"
42echo "\t $SUCCESS"
43echo "These branches failed"
44echo "\t $FAILED"
45echo "These branches were skipped without changes"
46echo "\t $EXCLUDED"
47
48git checkout $PREHEAD > /dev/null 2>&1
diff --git a/testing/av_test.c b/testing/av_test.c
index 46212255..28796abb 100644
--- a/testing/av_test.c
+++ b/testing/av_test.c
@@ -80,9 +80,7 @@ typedef struct {
80 80
81struct toxav_thread_data { 81struct toxav_thread_data {
82 ToxAV *AliceAV; 82 ToxAV *AliceAV;
83 void *AliceCC;
84 ToxAV *BobAV; 83 ToxAV *BobAV;
85 void *BobCC;
86 int32_t sig; 84 int32_t sig;
87}; 85};
88 86
@@ -272,32 +270,31 @@ static void initialize_tox(Tox **bootstrap, ToxAV **AliceAV, CallControl *AliceC
272 270
273 271
274 /* Alice */ 272 /* Alice */
275 toxav_callback_call(*AliceAV, t_toxav_call_cb); 273 toxav_callback_call(*AliceAV, t_toxav_call_cb, AliceCC);
276 toxav_callback_call_state(*AliceAV, t_toxav_call_state_cb); 274 toxav_callback_call_state(*AliceAV, t_toxav_call_state_cb, AliceCC);
277 toxav_callback_bit_rate_status(*AliceAV, t_toxav_bit_rate_status_cb); 275 toxav_callback_bit_rate_status(*AliceAV, t_toxav_bit_rate_status_cb, AliceCC);
278 toxav_callback_video_receive_frame(*AliceAV, t_toxav_receive_video_frame_cb); 276 toxav_callback_video_receive_frame(*AliceAV, t_toxav_receive_video_frame_cb, AliceCC);
279 toxav_callback_audio_receive_frame(*AliceAV, t_toxav_receive_audio_frame_cb); 277 toxav_callback_audio_receive_frame(*AliceAV, t_toxav_receive_audio_frame_cb, AliceCC);
280 278
281 /* Bob */ 279 /* Bob */
282 toxav_callback_call(*BobAV, t_toxav_call_cb); 280 toxav_callback_call(*BobAV, t_toxav_call_cb, BobCC);
283 toxav_callback_call_state(*BobAV, t_toxav_call_state_cb); 281 toxav_callback_call_state(*BobAV, t_toxav_call_state_cb, BobCC);
284 toxav_callback_bit_rate_status(*BobAV, t_toxav_bit_rate_status_cb); 282 toxav_callback_bit_rate_status(*BobAV, t_toxav_bit_rate_status_cb, BobCC);
285 toxav_callback_video_receive_frame(*BobAV, t_toxav_receive_video_frame_cb); 283 toxav_callback_video_receive_frame(*BobAV, t_toxav_receive_video_frame_cb, BobCC);
286 toxav_callback_audio_receive_frame(*BobAV, t_toxav_receive_audio_frame_cb); 284 toxav_callback_audio_receive_frame(*BobAV, t_toxav_receive_audio_frame_cb, BobCC);
287 285
288 286
289 printf("Created 2 instances of ToxAV\n"); 287 printf("Created 2 instances of ToxAV\n");
290 printf("All set after %llu seconds!\n", time(NULL) - cur_time); 288 printf("All set after %llu seconds!\n", time(NULL) - cur_time);
291} 289}
292static int iterate_tox(Tox *bootstrap, ToxAV *AliceAV, void *aCC, ToxAV *BobAV, void *bCC) 290static int iterate_tox(Tox *bootstrap, ToxAV *AliceAV, ToxAV *BobAV, void *userdata)
293{ 291{
294 tox_iterate(bootstrap, NULL); 292 tox_iterate(bootstrap, userdata);
295 tox_iterate(toxav_get_tox(AliceAV), aCC); 293 tox_iterate(toxav_get_tox(AliceAV), userdata);
296 tox_iterate(toxav_get_tox(BobAV), bCC); 294 tox_iterate(toxav_get_tox(BobAV), userdata);
297 295
298 return MIN(tox_iteration_interval(toxav_get_tox(AliceAV)), tox_iteration_interval(toxav_get_tox(BobAV))); 296 return MIN(tox_iteration_interval(toxav_get_tox(AliceAV)), tox_iteration_interval(toxav_get_tox(BobAV)));
299} 297}
300
301static void *iterate_toxav(void *data) 298static void *iterate_toxav(void *data)
302{ 299{
303 struct toxav_thread_data *data_cast = data; 300 struct toxav_thread_data *data_cast = data;
@@ -306,8 +303,8 @@ static void *iterate_toxav(void *data)
306#endif 303#endif
307 304
308 while (data_cast->sig == 0) { 305 while (data_cast->sig == 0) {
309 toxav_iterate(data_cast->AliceAV, data_cast->AliceCC); 306 toxav_iterate(data_cast->AliceAV);
310 toxav_iterate(data_cast->BobAV, data_cast->BobCC); 307 toxav_iterate(data_cast->BobAV);
311 int rc = MIN(toxav_iteration_interval(data_cast->AliceAV), toxav_iteration_interval(data_cast->BobAV)); 308 int rc = MIN(toxav_iteration_interval(data_cast->AliceAV), toxav_iteration_interval(data_cast->BobAV));
312 309
313 printf("\rIteration interval: %d ", rc); 310 printf("\rIteration interval: %d ", rc);
@@ -552,7 +549,7 @@ CHECK_ARG:
552 } 549 }
553 550
554 while (!BobCC.incoming) { 551 while (!BobCC.incoming) {
555 iterate_tox(bootstrap, AliceAV, &AliceCC, BobAV, &BobCC); 552 iterate_tox(bootstrap, AliceAV, BobAV, NULL);
556 } 553 }
557 554
558 { /* Answer */ 555 { /* Answer */
@@ -566,7 +563,7 @@ CHECK_ARG:
566 } 563 }
567 564
568 while (AliceCC.state == 0) { 565 while (AliceCC.state == 0) {
569 iterate_tox(bootstrap, AliceAV, &AliceCC, BobAV, &BobCC); 566 iterate_tox(bootstrap, AliceAV, BobAV, NULL);
570 } 567 }
571 568
572 /* Open audio file */ 569 /* Open audio file */
@@ -631,7 +628,7 @@ CHECK_ARG:
631 } 628 }
632 } 629 }
633 630
634 iterate_tox(bootstrap, AliceAV, &AliceCC, BobAV, &BobCC); 631 iterate_tox(bootstrap, AliceAV, BobAV, NULL);
635 c_sleep((audio_frame_duration - (current_time_monotonic() - enc_start_time) - 1)); 632 c_sleep((audio_frame_duration - (current_time_monotonic() - enc_start_time) - 1));
636 } 633 }
637 634
@@ -650,7 +647,7 @@ CHECK_ARG:
650 } 647 }
651 } 648 }
652 649
653 iterate_tox(bootstrap, AliceAV, &AliceCC, BobAV, &BobCC); 650 iterate_tox(bootstrap, AliceAV, BobAV, NULL);
654 assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); 651 assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED);
655 652
656 /* Stop decode thread */ 653 /* Stop decode thread */
@@ -693,7 +690,7 @@ CHECK_ARG:
693 } 690 }
694 691
695 while (!BobCC.incoming) { 692 while (!BobCC.incoming) {
696 iterate_tox(bootstrap, AliceAV, &AliceCC, BobAV, &BobCC); 693 iterate_tox(bootstrap, AliceAV, BobAV, NULL);
697 } 694 }
698 695
699 { /* Answer */ 696 { /* Answer */
@@ -706,14 +703,12 @@ CHECK_ARG:
706 } 703 }
707 } 704 }
708 705
709 iterate_tox(bootstrap, AliceAV, &AliceCC, BobAV, &BobCC); 706 iterate_tox(bootstrap, AliceAV, BobAV, NULL);
710 707
711 /* Start decode thread */ 708 /* Start decode thread */
712 struct toxav_thread_data data = { 709 struct toxav_thread_data data = {
713 .AliceAV = AliceAV, 710 .AliceAV = AliceAV,
714 .AliceCC = &AliceCC,
715 .BobAV = BobAV, 711 .BobAV = BobAV,
716 .BobCC = &BobCC,
717 .sig = 0 712 .sig = 0
718 }; 713 };
719 714
@@ -740,7 +735,7 @@ CHECK_ARG:
740 } 735 }
741 736
742 send_opencv_img(AliceAV, 0, frame); 737 send_opencv_img(AliceAV, 0, frame);
743 iterate_tox(bootstrap, AliceAV, &AliceCC, BobAV, &BobCC); 738 iterate_tox(bootstrap, AliceAV, BobAV, NULL);
744 c_sleep(10); 739 c_sleep(10);
745 } 740 }
746 741
@@ -756,7 +751,7 @@ CHECK_ARG:
756 } 751 }
757 } 752 }
758 753
759 iterate_tox(bootstrap, AliceAV, &AliceCC, BobAV, &BobCC); 754 iterate_tox(bootstrap, AliceAV, BobAV, NULL);
760 assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED); 755 assert(BobCC.state == TOXAV_FRIEND_CALL_STATE_FINISHED);
761 756
762 /* Stop decode thread */ 757 /* Stop decode thread */
diff --git a/toxav/audio.c b/toxav/audio.c
index 3fb0985e..59d1554e 100644
--- a/toxav/audio.c
+++ b/toxav/audio.c
@@ -43,7 +43,7 @@ bool reconfigure_audio_decoder(ACSession *ac, int32_t sampling_rate, int8_t chan
43 43
44 44
45 45
46ACSession *ac_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_audio_receive_frame_cb *cb) 46ACSession *ac_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_audio_receive_frame_cb *cb, void *cb_data)
47{ 47{
48 ACSession *ac = calloc(sizeof(ACSession), 1); 48 ACSession *ac = calloc(sizeof(ACSession), 1);
49 49
@@ -97,7 +97,8 @@ ACSession *ac_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_audio_re
97 97
98 ac->av = av; 98 ac->av = av;
99 ac->friend_number = friend_number; 99 ac->friend_number = friend_number;
100 ac->on_audio_frame = cb; 100 ac->acb.first = cb;
101 ac->acb.second = cb_data;
101 102
102 return ac; 103 return ac;
103 104
@@ -124,7 +125,7 @@ void ac_kill(ACSession *ac)
124 LOGGER_DEBUG(ac->log, "Terminated audio handler: %p", ac); 125 LOGGER_DEBUG(ac->log, "Terminated audio handler: %p", ac);
125 free(ac); 126 free(ac);
126} 127}
127void ac_iterate(ACSession *ac, void *userdata) 128void ac_iterate(ACSession *ac)
128{ 129{
129 if (!ac) { 130 if (!ac) {
130 return; 131 return;
@@ -185,11 +186,11 @@ void ac_iterate(ACSession *ac, void *userdata)
185 186
186 if (rc < 0) { 187 if (rc < 0) {
187 LOGGER_WARNING(ac->log, "Decoding error: %s", opus_strerror(rc)); 188 LOGGER_WARNING(ac->log, "Decoding error: %s", opus_strerror(rc));
188 } else if (ac->on_audio_frame) { 189 } else if (ac->acb.first) {
189 ac->lp_frame_duration = (rc * 1000) / ac->lp_sampling_rate; 190 ac->lp_frame_duration = (rc * 1000) / ac->lp_sampling_rate;
190 191
191 ac->on_audio_frame(ac->av, ac->friend_number, tmp, rc, ac->lp_channel_count, 192 ac->acb.first(ac->av, ac->friend_number, tmp, rc, ac->lp_channel_count,
192 ac->lp_sampling_rate, userdata); 193 ac->lp_sampling_rate, ac->acb.second);
193 } 194 }
194 195
195 return; 196 return;
diff --git a/toxav/audio.h b/toxav/audio.h
index 60bad163..5f9d7f7d 100644
--- a/toxav/audio.h
+++ b/toxav/audio.h
@@ -55,12 +55,12 @@ typedef struct ACSession_s {
55 55
56 ToxAV *av; 56 ToxAV *av;
57 uint32_t friend_number; 57 uint32_t friend_number;
58 toxav_audio_receive_frame_cb *on_audio_frame; /* Audio frame receive callback */ 58 PAIR(toxav_audio_receive_frame_cb *, void *) acb; /* Audio frame receive callback */
59} ACSession; 59} ACSession;
60 60
61ACSession *ac_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_audio_receive_frame_cb *cb); 61ACSession *ac_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_audio_receive_frame_cb *cb, void *cb_data);
62void ac_kill(ACSession *ac); 62void ac_kill(ACSession *ac);
63void ac_iterate(ACSession *ac, void *userdata); 63void ac_iterate(ACSession *ac);
64int ac_queue_message(void *acp, struct RTPMessage *msg); 64int ac_queue_message(void *acp, struct RTPMessage *msg);
65int ac_reconfigure_encoder(ACSession *ac, int32_t bit_rate, int32_t sampling_rate, uint8_t channels); 65int ac_reconfigure_encoder(ACSession *ac, int32_t bit_rate, int32_t sampling_rate, uint8_t channels);
66 66
diff --git a/toxav/bwcontroller.c b/toxav/bwcontroller.c
index 63350f17..b97135d6 100644
--- a/toxav/bwcontroller.c
+++ b/toxav/bwcontroller.c
@@ -40,7 +40,7 @@
40 */ 40 */
41 41
42struct BWController_s { 42struct BWController_s {
43 void (*mcb)(BWController *, uint32_t, float, void *, void *); 43 void (*mcb)(BWController *, uint32_t, float, void *);
44 void *mcb_data; 44 void *mcb_data;
45 45
46 Messenger *m; 46 Messenger *m;
@@ -61,18 +61,17 @@ struct BWController_s {
61 } rcvpkt; /* To calculate average received packet */ 61 } rcvpkt; /* To calculate average received packet */
62}; 62};
63 63
64int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object, 64int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object);
65 void *userdata);
66void send_update(BWController *bwc); 65void send_update(BWController *bwc);
67 66
68BWController *bwc_new(Messenger *m, uint32_t friendnumber, 67BWController *bwc_new(Messenger *m, uint32_t friendnumber,
69 void (*mcb)(BWController *, uint32_t, float, void *, void *), 68 void (*mcb)(BWController *, uint32_t, float, void *),
70 void *call_data) 69 void *udata)
71{ 70{
72 BWController *retu = calloc(sizeof(struct BWController_s), 1); 71 BWController *retu = calloc(sizeof(struct BWController_s), 1);
73 72
74 retu->mcb = mcb; 73 retu->mcb = mcb;
75 retu->mcb_data = call_data; 74 retu->mcb_data = udata;
76 retu->m = m; 75 retu->m = m;
77 retu->friend_number = friendnumber; 76 retu->friend_number = friendnumber;
78 retu->cycle.lsu = retu->cycle.lfu = current_time_monotonic(); 77 retu->cycle.lsu = retu->cycle.lfu = current_time_monotonic();
@@ -180,7 +179,7 @@ void send_update(BWController *bwc)
180 bwc->cycle.lsu = current_time_monotonic(); 179 bwc->cycle.lsu = current_time_monotonic();
181 } 180 }
182} 181}
183static int on_update(BWController *bwc, const struct BWCMessage *msg, void *userdata) 182static int on_update(BWController *bwc, const struct BWCMessage *msg)
184{ 183{
185 LOGGER_DEBUG(bwc->m->log, "%p Got update from peer", bwc); 184 LOGGER_DEBUG(bwc->m->log, "%p Got update from peer", bwc);
186 185
@@ -200,18 +199,16 @@ static int on_update(BWController *bwc, const struct BWCMessage *msg, void *user
200 if (lost && bwc->mcb) { 199 if (lost && bwc->mcb) {
201 bwc->mcb(bwc, bwc->friend_number, 200 bwc->mcb(bwc, bwc->friend_number,
202 ((float) lost / (recv + lost)), 201 ((float) lost / (recv + lost)),
203 bwc->mcb_data, 202 bwc->mcb_data);
204 userdata);
205 } 203 }
206 204
207 return 0; 205 return 0;
208} 206}
209int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object, 207int bwc_handle_data(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object)
210 void *userdata)
211{ 208{
212 if (length - 1 != sizeof(struct BWCMessage)) { 209 if (length - 1 != sizeof(struct BWCMessage)) {
213 return -1; 210 return -1;
214 } 211 }
215 212
216 return on_update(object, (const struct BWCMessage *)(data + 1), userdata); 213 return on_update(object, (const struct BWCMessage *)(data + 1));
217} 214}
diff --git a/toxav/bwcontroller.h b/toxav/bwcontroller.h
index e2a7229b..9542cde5 100644
--- a/toxav/bwcontroller.h
+++ b/toxav/bwcontroller.h
@@ -27,8 +27,8 @@
27typedef struct BWController_s BWController; 27typedef struct BWController_s BWController;
28 28
29BWController *bwc_new(Messenger *m, uint32_t friendnumber, 29BWController *bwc_new(Messenger *m, uint32_t friendnumber,
30 void (*mcb)(BWController *, uint32_t, float, void *, void *), 30 void (*mcb)(BWController *, uint32_t, float, void *),
31 void *call_data); 31 void *udata);
32void bwc_kill(BWController *bwc); 32void bwc_kill(BWController *bwc);
33 33
34void bwc_feed_avg(BWController *bwc, uint32_t bytes); 34void bwc_feed_avg(BWController *bwc, uint32_t bytes);
diff --git a/toxav/msi.c b/toxav/msi.c
index be467512..d80d7c76 100644
--- a/toxav/msi.c
+++ b/toxav/msi.c
@@ -81,16 +81,15 @@ int msg_parse_in(Logger *log, MSIMessage *dest, const uint8_t *data, uint16_t le
81uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const void *value, uint8_t value_len, uint16_t *length); 81uint8_t *msg_parse_header_out(MSIHeaderID id, uint8_t *dest, const void *value, uint8_t value_len, uint16_t *length);
82static int send_message(Messenger *m, uint32_t friend_number, const MSIMessage *msg); 82static int send_message(Messenger *m, uint32_t friend_number, const MSIMessage *msg);
83int send_error(Messenger *m, uint32_t friend_number, MSIError error); 83int send_error(Messenger *m, uint32_t friend_number, MSIError error);
84static int invoke_callback(MSICall *call, MSICallbackID cb, void *userdata); 84static int invoke_callback(MSICall *call, MSICallbackID cb);
85static MSICall *get_call(MSISession *session, uint32_t friend_number); 85static MSICall *get_call(MSISession *session, uint32_t friend_number);
86MSICall *new_call(MSISession *session, uint32_t friend_number); 86MSICall *new_call(MSISession *session, uint32_t friend_number);
87void kill_call(MSICall *call); 87void kill_call(MSICall *call);
88void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data, void *userdata); 88void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data);
89void handle_init(MSICall *call, const MSIMessage *msg, void *userdata); 89void handle_init(MSICall *call, const MSIMessage *msg);
90void handle_push(MSICall *call, const MSIMessage *msg, void *userdata); 90void handle_push(MSICall *call, const MSIMessage *msg);
91void handle_pop(MSICall *call, const MSIMessage *msg, void *userdata); 91void handle_pop(MSICall *call, const MSIMessage *msg);
92void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object, 92void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object);
93 void *userdata);
94 93
95 94
96/** 95/**
@@ -480,14 +479,14 @@ int send_error(Messenger *m, uint32_t friend_number, MSIError error)
480 send_message(m, friend_number, &msg); 479 send_message(m, friend_number, &msg);
481 return 0; 480 return 0;
482} 481}
483int invoke_callback(MSICall *call, MSICallbackID cb, void *userdata) 482int invoke_callback(MSICall *call, MSICallbackID cb)
484{ 483{
485 assert(call); 484 assert(call);
486 485
487 if (call->session->callbacks[cb]) { 486 if (call->session->callbacks[cb]) {
488 LOGGER_DEBUG(call->session->messenger->log, "Invoking callback function: %d", cb); 487 LOGGER_DEBUG(call->session->messenger->log, "Invoking callback function: %d", cb);
489 488
490 if (call->session->callbacks[cb](call->session->av, call, userdata) != 0) { 489 if (call->session->callbacks[cb](call->session->av, call) != 0) {
491 LOGGER_WARNING(call->session->messenger->log, 490 LOGGER_WARNING(call->session->messenger->log,
492 "Callback state handling failed, sending error"); 491 "Callback state handling failed, sending error");
493 goto FAILURE; 492 goto FAILURE;
@@ -609,7 +608,7 @@ CLEAR_CONTAINER:
609 free(call); 608 free(call);
610 session->calls = NULL; 609 session->calls = NULL;
611} 610}
612void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data, void *userdata) 611void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *data)
613{ 612{
614 (void)m; 613 (void)m;
615 MSISession *session = data; 614 MSISession *session = data;
@@ -626,7 +625,7 @@ void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *
626 return; 625 return;
627 } 626 }
628 627
629 invoke_callback(call, msi_OnPeerTimeout, userdata); /* Failure is ignored */ 628 invoke_callback(call, msi_OnPeerTimeout); /* Failure is ignored */
630 kill_call(call); 629 kill_call(call);
631 pthread_mutex_unlock(session->mutex); 630 pthread_mutex_unlock(session->mutex);
632 } 631 }
@@ -636,7 +635,7 @@ void on_peer_status(Messenger *m, uint32_t friend_number, uint8_t status, void *
636 break; 635 break;
637 } 636 }
638} 637}
639void handle_init(MSICall *call, const MSIMessage *msg, void *userdata) 638void handle_init(MSICall *call, const MSIMessage *msg)
640{ 639{
641 assert(call); 640 assert(call);
642 LOGGER_DEBUG(call->session->messenger->log, 641 LOGGER_DEBUG(call->session->messenger->log,
@@ -654,7 +653,7 @@ void handle_init(MSICall *call, const MSIMessage *msg, void *userdata)
654 call->peer_capabilities = msg->capabilities.value; 653 call->peer_capabilities = msg->capabilities.value;
655 call->state = msi_CallRequested; 654 call->state = msi_CallRequested;
656 655
657 if (invoke_callback(call, msi_OnInvite, userdata) == -1) { 656 if (invoke_callback(call, msi_OnInvite) == -1) {
658 goto FAILURE; 657 goto FAILURE;
659 } 658 }
660 } 659 }
@@ -698,7 +697,7 @@ FAILURE:
698 send_error(call->session->messenger, call->friend_number, call->error); 697 send_error(call->session->messenger, call->friend_number, call->error);
699 kill_call(call); 698 kill_call(call);
700} 699}
701void handle_push(MSICall *call, const MSIMessage *msg, void *userdata) 700void handle_push(MSICall *call, const MSIMessage *msg)
702{ 701{
703 assert(call); 702 assert(call);
704 703
@@ -719,7 +718,7 @@ void handle_push(MSICall *call, const MSIMessage *msg, void *userdata)
719 718
720 call->peer_capabilities = msg->capabilities.value; 719 call->peer_capabilities = msg->capabilities.value;
721 720
722 if (invoke_callback(call, msi_OnCapabilities, userdata) == -1) { 721 if (invoke_callback(call, msi_OnCapabilities) == -1) {
723 goto FAILURE; 722 goto FAILURE;
724 } 723 }
725 } 724 }
@@ -733,7 +732,7 @@ void handle_push(MSICall *call, const MSIMessage *msg, void *userdata)
733 call->peer_capabilities = msg->capabilities.value; 732 call->peer_capabilities = msg->capabilities.value;
734 call->state = msi_CallActive; 733 call->state = msi_CallActive;
735 734
736 if (invoke_callback(call, msi_OnStart, userdata) == -1) { 735 if (invoke_callback(call, msi_OnStart) == -1) {
737 goto FAILURE; 736 goto FAILURE;
738 } 737 }
739 } 738 }
@@ -753,7 +752,7 @@ FAILURE:
753 send_error(call->session->messenger, call->friend_number, call->error); 752 send_error(call->session->messenger, call->friend_number, call->error);
754 kill_call(call); 753 kill_call(call);
755} 754}
756void handle_pop(MSICall *call, const MSIMessage *msg, void *userdata) 755void handle_pop(MSICall *call, const MSIMessage *msg)
757{ 756{
758 assert(call); 757 assert(call);
759 758
@@ -765,7 +764,7 @@ void handle_pop(MSICall *call, const MSIMessage *msg, void *userdata)
765 if (msg->error.exists) { 764 if (msg->error.exists) {
766 LOGGER_WARNING(call->session->messenger->log, "Friend detected an error: %d", msg->error.value); 765 LOGGER_WARNING(call->session->messenger->log, "Friend detected an error: %d", msg->error.value);
767 call->error = msg->error.value; 766 call->error = msg->error.value;
768 invoke_callback(call, msi_OnError, userdata); 767 invoke_callback(call, msi_OnError);
769 } else { 768 } else {
770 switch (call->state) { 769 switch (call->state) {
771 case msi_CallInactive: { 770 case msi_CallInactive: {
@@ -777,21 +776,21 @@ void handle_pop(MSICall *call, const MSIMessage *msg, void *userdata)
777 case msi_CallActive: { 776 case msi_CallActive: {
778 /* Hangup */ 777 /* Hangup */
779 LOGGER_INFO(call->session->messenger->log, "Friend hung up on us"); 778 LOGGER_INFO(call->session->messenger->log, "Friend hung up on us");
780 invoke_callback(call, msi_OnEnd, userdata); 779 invoke_callback(call, msi_OnEnd);
781 } 780 }
782 break; 781 break;
783 782
784 case msi_CallRequesting: { 783 case msi_CallRequesting: {
785 /* Reject */ 784 /* Reject */
786 LOGGER_INFO(call->session->messenger->log, "Friend rejected our call"); 785 LOGGER_INFO(call->session->messenger->log, "Friend rejected our call");
787 invoke_callback(call, msi_OnEnd, userdata); 786 invoke_callback(call, msi_OnEnd);
788 } 787 }
789 break; 788 break;
790 789
791 case msi_CallRequested: { 790 case msi_CallRequested: {
792 /* Cancel */ 791 /* Cancel */
793 LOGGER_INFO(call->session->messenger->log, "Friend canceled call invite"); 792 LOGGER_INFO(call->session->messenger->log, "Friend canceled call invite");
794 invoke_callback(call, msi_OnEnd, userdata); 793 invoke_callback(call, msi_OnEnd);
795 } 794 }
796 break; 795 break;
797 } 796 }
@@ -799,8 +798,7 @@ void handle_pop(MSICall *call, const MSIMessage *msg, void *userdata)
799 798
800 kill_call(call); 799 kill_call(call);
801} 800}
802void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object, 801void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data, uint16_t length, void *object)
803 void *userdata)
804{ 802{
805 LOGGER_DEBUG(m->log, "Got msi message"); 803 LOGGER_DEBUG(m->log, "Got msi message");
806 804
@@ -836,15 +834,15 @@ void handle_msi_packet(Messenger *m, uint32_t friend_number, const uint8_t *data
836 834
837 switch (msg.request.value) { 835 switch (msg.request.value) {
838 case requ_init: 836 case requ_init:
839 handle_init(call, &msg, userdata); 837 handle_init(call, &msg);
840 break; 838 break;
841 839
842 case requ_push: 840 case requ_push:
843 handle_push(call, &msg, userdata); 841 handle_push(call, &msg);
844 break; 842 break;
845 843
846 case requ_pop: 844 case requ_pop:
847 handle_pop(call, &msg, userdata); /* always kills the call */ 845 handle_pop(call, &msg); /* always kills the call */
848 break; 846 break;
849 } 847 }
850 848
diff --git a/toxav/msi.h b/toxav/msi.h
index 05583239..bf611d34 100644
--- a/toxav/msi.h
+++ b/toxav/msi.h
@@ -102,7 +102,7 @@ typedef struct MSICall_s {
102 * returned the call is considered errored and will be handled 102 * returned the call is considered errored and will be handled
103 * as such which means it will be terminated without any notice. 103 * as such which means it will be terminated without any notice.
104 */ 104 */
105typedef int msi_action_cb(void *av, MSICall *call, void *userdata); 105typedef int msi_action_cb(void *av, MSICall *call);
106 106
107/** 107/**
108 * Control session struct. Please do not modify outside msi.c 108 * Control session struct. Please do not modify outside msi.c
diff --git a/toxav/rtp.c b/toxav/rtp.c
index 8c5f0dfb..534efc1a 100644
--- a/toxav/rtp.c
+++ b/toxav/rtp.c
@@ -35,8 +35,7 @@
35#include <stdlib.h> 35#include <stdlib.h>
36 36
37 37
38int handle_rtp_packet(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object, 38int handle_rtp_packet(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object);
39 void *userdata);
40 39
41 40
42RTPSession *rtp_new(int payload_type, Messenger *m, uint32_t friendnumber, 41RTPSession *rtp_new(int payload_type, Messenger *m, uint32_t friendnumber,
@@ -234,8 +233,7 @@ static struct RTPMessage *new_message(size_t allocate_len, const uint8_t *data,
234 233
235 return msg; 234 return msg;
236} 235}
237int handle_rtp_packet(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object, 236int handle_rtp_packet(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t length, void *object)
238 void *userdata)
239{ 237{
240 (void) m; 238 (void) m;
241 (void) friendnumber; 239 (void) friendnumber;
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 29046265..1ae914e8 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -42,16 +42,10 @@ typedef struct ToxAVCall_s {
42 ToxAV *av; 42 ToxAV *av;
43 43
44 pthread_mutex_t mutex_audio[1]; 44 pthread_mutex_t mutex_audio[1];
45 struct { 45 PAIR(RTPSession *, ACSession *) audio;
46 RTPSession *first;
47 ACSession *second;
48 } audio;
49 46
50 pthread_mutex_t mutex_video[1]; 47 pthread_mutex_t mutex_video[1];
51 struct { 48 PAIR(RTPSession *, VCSession *) video;
52 RTPSession *first;
53 VCSession *second;
54 } video;
55 49
56 BWController *bwc; 50 BWController *bwc;
57 51
@@ -81,12 +75,11 @@ struct ToxAV {
81 uint32_t calls_head; 75 uint32_t calls_head;
82 pthread_mutex_t mutex[1]; 76 pthread_mutex_t mutex[1];
83 77
84 toxav_call_cb *on_call; 78 PAIR(toxav_call_cb *, void *) ccb; /* Call callback */
85 toxav_call_state_cb *on_call_state; 79 PAIR(toxav_call_state_cb *, void *) scb; /* Call state callback */
86 toxav_bit_rate_status_cb *on_bit_rate_status_change; 80 PAIR(toxav_audio_receive_frame_cb *, void *) acb; /* Audio frame receive callback */
87 81 PAIR(toxav_video_receive_frame_cb *, void *) vcb; /* Video frame receive callback */
88 toxav_audio_receive_frame_cb *on_audio_frame; 82 PAIR(toxav_bit_rate_status_cb *, void *) bcb; /* Bit rate control callback */
89 toxav_video_receive_frame_cb *on_video_frame;
90 83
91 /** Decode time measures */ 84 /** Decode time measures */
92 int32_t dmssc; /** Measure count */ 85 int32_t dmssc; /** Measure count */
@@ -96,17 +89,17 @@ struct ToxAV {
96 uint32_t interval; /** Calculated interval */ 89 uint32_t interval; /** Calculated interval */
97}; 90};
98 91
99void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *call_data, void *userdata); 92void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *user_data);
100 93
101int callback_invite(void *toxav_inst, MSICall *call, void *userdata); 94int callback_invite(void *toxav_inst, MSICall *call);
102int callback_start(void *toxav_inst, MSICall *call, void *userdata); 95int callback_start(void *toxav_inst, MSICall *call);
103int callback_end(void *toxav_inst, MSICall *call, void *userdata); 96int callback_end(void *toxav_inst, MSICall *call);
104int callback_error(void *toxav_inst, MSICall *call, void *userdata); 97int callback_error(void *toxav_inst, MSICall *call);
105int callback_capabilites(void *toxav_inst, MSICall *call, void *userdata); 98int callback_capabilites(void *toxav_inst, MSICall *call);
106 99
107bool audio_bit_rate_invalid(uint32_t bit_rate); 100bool audio_bit_rate_invalid(uint32_t bit_rate);
108bool video_bit_rate_invalid(uint32_t bit_rate); 101bool video_bit_rate_invalid(uint32_t bit_rate);
109bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state, void *userdata); 102bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state);
110ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error); 103ToxAVCall *call_new(ToxAV *av, uint32_t friend_number, TOXAV_ERR_CALL *error);
111ToxAVCall *call_get(ToxAV *av, uint32_t friend_number); 104ToxAVCall *call_get(ToxAV *av, uint32_t friend_number);
112ToxAVCall *call_remove(ToxAVCall *call); 105ToxAVCall *call_remove(ToxAVCall *call);
@@ -237,7 +230,7 @@ uint32_t toxav_iteration_interval(const ToxAV *av)
237 /* If no call is active interval is 200 */ 230 /* If no call is active interval is 200 */
238 return av->calls ? av->interval : 200; 231 return av->calls ? av->interval : 200;
239} 232}
240void toxav_iterate(ToxAV *av, void *userdata) 233void toxav_iterate(ToxAV *av)
241{ 234{
242 pthread_mutex_lock(av->mutex); 235 pthread_mutex_lock(av->mutex);
243 236
@@ -256,8 +249,8 @@ void toxav_iterate(ToxAV *av, void *userdata)
256 pthread_mutex_lock(i->mutex); 249 pthread_mutex_lock(i->mutex);
257 pthread_mutex_unlock(av->mutex); 250 pthread_mutex_unlock(av->mutex);
258 251
259 ac_iterate(i->audio.second, userdata); 252 ac_iterate(i->audio.second);
260 vc_iterate(i->video.second, userdata); 253 vc_iterate(i->video.second);
261 254
262 if (i->msi_call->self_capabilities & msi_CapRAudio && 255 if (i->msi_call->self_capabilities & msi_CapRAudio &&
263 i->msi_call->peer_capabilities & msi_CapSAudio) { 256 i->msi_call->peer_capabilities & msi_CapSAudio) {
@@ -336,10 +329,11 @@ END:
336 329
337 return rc == TOXAV_ERR_CALL_OK; 330 return rc == TOXAV_ERR_CALL_OK;
338} 331}
339void toxav_callback_call(ToxAV *av, toxav_call_cb *callback) 332void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data)
340{ 333{
341 pthread_mutex_lock(av->mutex); 334 pthread_mutex_lock(av->mutex);
342 av->on_call = callback; 335 av->ccb.first = callback;
336 av->ccb.second = user_data;
343 pthread_mutex_unlock(av->mutex); 337 pthread_mutex_unlock(av->mutex);
344} 338}
345bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, 339bool toxav_answer(ToxAV *av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate,
@@ -394,10 +388,11 @@ END:
394 388
395 return rc == TOXAV_ERR_ANSWER_OK; 389 return rc == TOXAV_ERR_ANSWER_OK;
396} 390}
397void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback) 391void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *user_data)
398{ 392{
399 pthread_mutex_lock(av->mutex); 393 pthread_mutex_lock(av->mutex);
400 av->on_call_state = callback; 394 av->scb.first = callback;
395 av->scb.second = user_data;
401 pthread_mutex_unlock(av->mutex); 396 pthread_mutex_unlock(av->mutex);
402} 397}
403bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL *error) 398bool toxav_call_control(ToxAV *av, uint32_t friend_number, TOXAV_CALL_CONTROL control, TOXAV_ERR_CALL_CONTROL *error)
@@ -669,10 +664,11 @@ END:
669 664
670 return rc == TOXAV_ERR_BIT_RATE_SET_OK; 665 return rc == TOXAV_ERR_BIT_RATE_SET_OK;
671} 666}
672void toxav_callback_bit_rate_status(ToxAV *av, toxav_bit_rate_status_cb *callback) 667void toxav_callback_bit_rate_status(ToxAV *av, toxav_bit_rate_status_cb *callback, void *user_data)
673{ 668{
674 pthread_mutex_lock(av->mutex); 669 pthread_mutex_lock(av->mutex);
675 av->on_bit_rate_status_change = callback; 670 av->bcb.first = callback;
671 av->bcb.second = user_data;
676 pthread_mutex_unlock(av->mutex); 672 pthread_mutex_unlock(av->mutex);
677} 673}
678bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count, 674bool toxav_audio_send_frame(ToxAV *av, uint32_t friend_number, const int16_t *pcm, size_t sample_count,
@@ -860,16 +856,18 @@ END:
860 856
861 return rc == TOXAV_ERR_SEND_FRAME_OK; 857 return rc == TOXAV_ERR_SEND_FRAME_OK;
862} 858}
863void toxav_callback_audio_receive_frame(ToxAV *av, toxav_audio_receive_frame_cb *callback) 859void toxav_callback_audio_receive_frame(ToxAV *av, toxav_audio_receive_frame_cb *callback, void *user_data)
864{ 860{
865 pthread_mutex_lock(av->mutex); 861 pthread_mutex_lock(av->mutex);
866 av->on_audio_frame = callback; 862 av->acb.first = callback;
863 av->acb.second = user_data;
867 pthread_mutex_unlock(av->mutex); 864 pthread_mutex_unlock(av->mutex);
868} 865}
869void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb *callback) 866void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb *callback, void *user_data)
870{ 867{
871 pthread_mutex_lock(av->mutex); 868 pthread_mutex_lock(av->mutex);
872 av->on_video_frame = callback; 869 av->vcb.first = callback;
870 av->vcb.second = user_data;
873 pthread_mutex_unlock(av->mutex); 871 pthread_mutex_unlock(av->mutex);
874} 872}
875 873
@@ -879,7 +877,7 @@ void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb
879 * :: Internal 877 * :: Internal
880 * 878 *
881 ******************************************************************************/ 879 ******************************************************************************/
882void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *call_data, void *userdata) 880void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *user_data)
883{ 881{
884 /* Callback which is called when the internal measure mechanism reported packet loss. 882 /* Callback which is called when the internal measure mechanism reported packet loss.
885 * We report suggested lowered bitrate to an app. If app is sending both audio and video, 883 * We report suggested lowered bitrate to an app. If app is sending both audio and video,
@@ -888,7 +886,7 @@ void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *c
888 * The application may choose to disable video totally if the stream is too bad. 886 * The application may choose to disable video totally if the stream is too bad.
889 */ 887 */
890 888
891 ToxAVCall *call = call_data; 889 ToxAVCall *call = user_data;
892 assert(call); 890 assert(call);
893 891
894 LOGGER_DEBUG(call->av->m->log, "Reported loss of %f%%", loss * 100); 892 LOGGER_DEBUG(call->av->m->log, "Reported loss of %f%%", loss * 100);
@@ -899,25 +897,25 @@ void callback_bwc(BWController *bwc, uint32_t friend_number, float loss, void *c
899 897
900 pthread_mutex_lock(call->av->mutex); 898 pthread_mutex_lock(call->av->mutex);
901 899
902 if (!call->av->on_bit_rate_status_change) { 900 if (!call->av->bcb.first) {
903 pthread_mutex_unlock(call->av->mutex); 901 pthread_mutex_unlock(call->av->mutex);
904 LOGGER_WARNING(call->av->m->log, "No callback to report loss on"); 902 LOGGER_WARNING(call->av->m->log, "No callback to report loss on");
905 return; 903 return;
906 } 904 }
907 905
908 if (call->video_bit_rate) { 906 if (call->video_bit_rate) {
909 (*call->av->on_bit_rate_status_change)(call->av, friend_number, call->audio_bit_rate, 907 (*call->av->bcb.first)(call->av, friend_number, call->audio_bit_rate,
910 call->video_bit_rate - (call->video_bit_rate * loss), 908 call->video_bit_rate - (call->video_bit_rate * loss),
911 userdata); 909 call->av->bcb.second);
912 } else if (call->audio_bit_rate) { 910 } else if (call->audio_bit_rate) {
913 (*call->av->on_bit_rate_status_change)(call->av, friend_number, 911 (*call->av->bcb.first)(call->av, friend_number,
914 call->audio_bit_rate - (call->audio_bit_rate * loss), 912 call->audio_bit_rate - (call->audio_bit_rate * loss),
915 0, userdata); 913 0, call->av->bcb.second);
916 } 914 }
917 915
918 pthread_mutex_unlock(call->av->mutex); 916 pthread_mutex_unlock(call->av->mutex);
919} 917}
920int callback_invite(void *toxav_inst, MSICall *call, void *userdata) 918int callback_invite(void *toxav_inst, MSICall *call)
921{ 919{
922 ToxAV *toxav = toxav_inst; 920 ToxAV *toxav = toxav_inst;
923 pthread_mutex_lock(toxav->mutex); 921 pthread_mutex_lock(toxav->mutex);
@@ -933,9 +931,9 @@ int callback_invite(void *toxav_inst, MSICall *call, void *userdata)
933 call->av_call = av_call; 931 call->av_call = av_call;
934 av_call->msi_call = call; 932 av_call->msi_call = call;
935 933
936 if (toxav->on_call) { 934 if (toxav->ccb.first) {
937 toxav->on_call(toxav, call->friend_number, call->peer_capabilities & msi_CapSAudio, 935 toxav->ccb.first(toxav, call->friend_number, call->peer_capabilities & msi_CapSAudio,
938 call->peer_capabilities & msi_CapSVideo, userdata); 936 call->peer_capabilities & msi_CapSVideo, toxav->ccb.second);
939 } else { 937 } else {
940 /* No handler to capture the call request, send failure */ 938 /* No handler to capture the call request, send failure */
941 pthread_mutex_unlock(toxav->mutex); 939 pthread_mutex_unlock(toxav->mutex);
@@ -945,7 +943,7 @@ int callback_invite(void *toxav_inst, MSICall *call, void *userdata)
945 pthread_mutex_unlock(toxav->mutex); 943 pthread_mutex_unlock(toxav->mutex);
946 return 0; 944 return 0;
947} 945}
948int callback_start(void *toxav_inst, MSICall *call, void *userdata) 946int callback_start(void *toxav_inst, MSICall *call)
949{ 947{
950 ToxAV *toxav = toxav_inst; 948 ToxAV *toxav = toxav_inst;
951 pthread_mutex_lock(toxav->mutex); 949 pthread_mutex_lock(toxav->mutex);
@@ -959,13 +957,13 @@ int callback_start(void *toxav_inst, MSICall *call, void *userdata)
959 } 957 }
960 958
961 if (!call_prepare_transmission(av_call)) { 959 if (!call_prepare_transmission(av_call)) {
962 callback_error(toxav_inst, call, userdata); 960 callback_error(toxav_inst, call);
963 pthread_mutex_unlock(toxav->mutex); 961 pthread_mutex_unlock(toxav->mutex);
964 return -1; 962 return -1;
965 } 963 }
966 964
967 if (!invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities, userdata)) { 965 if (!invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities)) {
968 callback_error(toxav_inst, call, userdata); 966 callback_error(toxav_inst, call);
969 pthread_mutex_unlock(toxav->mutex); 967 pthread_mutex_unlock(toxav->mutex);
970 return -1; 968 return -1;
971 } 969 }
@@ -973,12 +971,12 @@ int callback_start(void *toxav_inst, MSICall *call, void *userdata)
973 pthread_mutex_unlock(toxav->mutex); 971 pthread_mutex_unlock(toxav->mutex);
974 return 0; 972 return 0;
975} 973}
976int callback_end(void *toxav_inst, MSICall *call, void *userdata) 974int callback_end(void *toxav_inst, MSICall *call)
977{ 975{
978 ToxAV *toxav = toxav_inst; 976 ToxAV *toxav = toxav_inst;
979 pthread_mutex_lock(toxav->mutex); 977 pthread_mutex_lock(toxav->mutex);
980 978
981 invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_FINISHED, userdata); 979 invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_FINISHED);
982 980
983 if (call->av_call) { 981 if (call->av_call) {
984 call_kill_transmission(call->av_call); 982 call_kill_transmission(call->av_call);
@@ -988,12 +986,12 @@ int callback_end(void *toxav_inst, MSICall *call, void *userdata)
988 pthread_mutex_unlock(toxav->mutex); 986 pthread_mutex_unlock(toxav->mutex);
989 return 0; 987 return 0;
990} 988}
991int callback_error(void *toxav_inst, MSICall *call, void *userdata) 989int callback_error(void *toxav_inst, MSICall *call)
992{ 990{
993 ToxAV *toxav = toxav_inst; 991 ToxAV *toxav = toxav_inst;
994 pthread_mutex_lock(toxav->mutex); 992 pthread_mutex_lock(toxav->mutex);
995 993
996 invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_ERROR, userdata); 994 invoke_call_state_callback(toxav, call->friend_number, TOXAV_FRIEND_CALL_STATE_ERROR);
997 995
998 if (call->av_call) { 996 if (call->av_call) {
999 call_kill_transmission(call->av_call); 997 call_kill_transmission(call->av_call);
@@ -1003,7 +1001,7 @@ int callback_error(void *toxav_inst, MSICall *call, void *userdata)
1003 pthread_mutex_unlock(toxav->mutex); 1001 pthread_mutex_unlock(toxav->mutex);
1004 return 0; 1002 return 0;
1005} 1003}
1006int callback_capabilites(void *toxav_inst, MSICall *call, void *userdata) 1004int callback_capabilites(void *toxav_inst, MSICall *call)
1007{ 1005{
1008 ToxAV *toxav = toxav_inst; 1006 ToxAV *toxav = toxav_inst;
1009 pthread_mutex_lock(toxav->mutex); 1007 pthread_mutex_lock(toxav->mutex);
@@ -1020,7 +1018,7 @@ int callback_capabilites(void *toxav_inst, MSICall *call, void *userdata)
1020 rtp_stop_receiving(((ToxAVCall *)call->av_call)->video.first); 1018 rtp_stop_receiving(((ToxAVCall *)call->av_call)->video.first);
1021 } 1019 }
1022 1020
1023 invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities, userdata); 1021 invoke_call_state_callback(toxav, call->friend_number, call->peer_capabilities);
1024 1022
1025 pthread_mutex_unlock(toxav->mutex); 1023 pthread_mutex_unlock(toxav->mutex);
1026 return 0; 1024 return 0;
@@ -1038,10 +1036,10 @@ bool video_bit_rate_invalid(uint32_t bit_rate)
1038 /* TODO(mannol): If anyone knows the answer to this one please fill it up */ 1036 /* TODO(mannol): If anyone knows the answer to this one please fill it up */
1039 return false; 1037 return false;
1040} 1038}
1041bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state, void *userdata) 1039bool invoke_call_state_callback(ToxAV *av, uint32_t friend_number, uint32_t state)
1042{ 1040{
1043 if (av->on_call_state) { 1041 if (av->scb.first) {
1044 av->on_call_state(av, friend_number, state, userdata); 1042 av->scb.first(av, friend_number, state, av->scb.second);
1045 } else { 1043 } else {
1046 return false; 1044 return false;
1047 } 1045 }
@@ -1196,7 +1194,7 @@ bool call_prepare_transmission(ToxAVCall *call)
1196 1194
1197 ToxAV *av = call->av; 1195 ToxAV *av = call->av;
1198 1196
1199 if (!av->on_audio_frame && !av->on_video_frame) { 1197 if (!av->acb.first && !av->vcb.first) {
1200 /* It makes no sense to have CSession without callbacks */ 1198 /* It makes no sense to have CSession without callbacks */
1201 return false; 1199 return false;
1202 } 1200 }
@@ -1222,7 +1220,7 @@ bool call_prepare_transmission(ToxAVCall *call)
1222 call->bwc = bwc_new(av->m, call->friend_number, callback_bwc, call); 1220 call->bwc = bwc_new(av->m, call->friend_number, callback_bwc, call);
1223 1221
1224 { /* Prepare audio */ 1222 { /* Prepare audio */
1225 call->audio.second = ac_new(av->m->log, av, call->friend_number, av->on_audio_frame); 1223 call->audio.second = ac_new(av->m->log, av, call->friend_number, av->acb.first, av->acb.second);
1226 1224
1227 if (!call->audio.second) { 1225 if (!call->audio.second) {
1228 LOGGER_ERROR(av->m->log, "Failed to create audio codec session"); 1226 LOGGER_ERROR(av->m->log, "Failed to create audio codec session");
@@ -1238,7 +1236,7 @@ bool call_prepare_transmission(ToxAVCall *call)
1238 } 1236 }
1239 } 1237 }
1240 { /* Prepare video */ 1238 { /* Prepare video */
1241 call->video.second = vc_new(av->m->log, av, call->friend_number, av->on_video_frame); 1239 call->video.second = vc_new(av->m->log, av, call->friend_number, av->vcb.first, av->vcb.second);
1242 1240
1243 if (!call->video.second) { 1241 if (!call->video.second) {
1244 LOGGER_ERROR(av->m->log, "Failed to create video codec session"); 1242 LOGGER_ERROR(av->m->log, "Failed to create video codec session");
diff --git a/toxav/toxav.h b/toxav/toxav.h
index da0c4c35..38ba354e 100644
--- a/toxav/toxav.h
+++ b/toxav/toxav.h
@@ -232,7 +232,7 @@ uint32_t toxav_iteration_interval(const ToxAV *av);
232 * toxav_iteration_interval() milliseconds. It is best called in the separate 232 * toxav_iteration_interval() milliseconds. It is best called in the separate
233 * thread from tox_iterate. 233 * thread from tox_iterate.
234 */ 234 */
235void toxav_iterate(ToxAV *av, void *userdata); 235void toxav_iterate(ToxAV *av);
236 236
237 237
238/******************************************************************************* 238/*******************************************************************************
@@ -316,7 +316,7 @@ typedef void toxav_call_cb(ToxAV *av, uint32_t friend_number, bool audio_enabled
316 * Set the callback for the `call` event. Pass NULL to unset. 316 * Set the callback for the `call` event. Pass NULL to unset.
317 * 317 *
318 */ 318 */
319void toxav_callback_call(ToxAV *av, toxav_call_cb *callback); 319void toxav_callback_call(ToxAV *av, toxav_call_cb *callback, void *user_data);
320 320
321typedef enum TOXAV_ERR_ANSWER { 321typedef enum TOXAV_ERR_ANSWER {
322 322
@@ -437,7 +437,7 @@ typedef void toxav_call_state_cb(ToxAV *av, uint32_t friend_number, uint32_t sta
437 * Set the callback for the `call_state` event. Pass NULL to unset. 437 * Set the callback for the `call_state` event. Pass NULL to unset.
438 * 438 *
439 */ 439 */
440void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback); 440void toxav_callback_call_state(ToxAV *av, toxav_call_state_cb *callback, void *user_data);
441 441
442 442
443/******************************************************************************* 443/*******************************************************************************
@@ -613,7 +613,7 @@ typedef void toxav_bit_rate_status_cb(ToxAV *av, uint32_t friend_number, uint32_
613 * Set the callback for the `bit_rate_status` event. Pass NULL to unset. 613 * Set the callback for the `bit_rate_status` event. Pass NULL to unset.
614 * 614 *
615 */ 615 */
616void toxav_callback_bit_rate_status(ToxAV *av, toxav_bit_rate_status_cb *callback); 616void toxav_callback_bit_rate_status(ToxAV *av, toxav_bit_rate_status_cb *callback, void *user_data);
617 617
618 618
619/******************************************************************************* 619/*******************************************************************************
@@ -742,7 +742,7 @@ typedef void toxav_audio_receive_frame_cb(ToxAV *av, uint32_t friend_number, con
742 * Set the callback for the `audio_receive_frame` event. Pass NULL to unset. 742 * Set the callback for the `audio_receive_frame` event. Pass NULL to unset.
743 * 743 *
744 */ 744 */
745void toxav_callback_audio_receive_frame(ToxAV *av, toxav_audio_receive_frame_cb *callback); 745void toxav_callback_audio_receive_frame(ToxAV *av, toxav_audio_receive_frame_cb *callback, void *user_data);
746 746
747/** 747/**
748 * The function type for the video_receive_frame callback. 748 * The function type for the video_receive_frame callback.
@@ -774,7 +774,7 @@ typedef void toxav_video_receive_frame_cb(ToxAV *av, uint32_t friend_number, uin
774 * Set the callback for the `video_receive_frame` event. Pass NULL to unset. 774 * Set the callback for the `video_receive_frame` event. Pass NULL to unset.
775 * 775 *
776 */ 776 */
777void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb *callback); 777void toxav_callback_video_receive_frame(ToxAV *av, toxav_video_receive_frame_cb *callback, void *user_data);
778 778
779/** 779/**
780 * NOTE Compatibility with old toxav group calls. TODO(iphydf): remove 780 * NOTE Compatibility with old toxav group calls. TODO(iphydf): remove
diff --git a/toxav/video.c b/toxav/video.c
index e786bc4c..de028c7c 100644
--- a/toxav/video.c
+++ b/toxav/video.c
@@ -37,7 +37,7 @@
37#define MAX_DECODE_TIME_US 0 /* Good quality encode. */ 37#define MAX_DECODE_TIME_US 0 /* Good quality encode. */
38#define VIDEO_DECODE_BUFFER_SIZE 20 38#define VIDEO_DECODE_BUFFER_SIZE 20
39 39
40VCSession *vc_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb) 40VCSession *vc_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb, void *cb_data)
41{ 41{
42 VCSession *vc = calloc(sizeof(VCSession), 1); 42 VCSession *vc = calloc(sizeof(VCSession), 1);
43 43
@@ -104,7 +104,8 @@ VCSession *vc_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_video_re
104 104
105 vc->linfts = current_time_monotonic(); 105 vc->linfts = current_time_monotonic();
106 vc->lcfd = 60; 106 vc->lcfd = 60;
107 vc->on_video_frame = cb; 107 vc->vcb.first = cb;
108 vc->vcb.second = cb_data;
108 vc->friend_number = friend_number; 109 vc->friend_number = friend_number;
109 vc->av = av; 110 vc->av = av;
110 vc->log = log; 111 vc->log = log;
@@ -141,7 +142,7 @@ void vc_kill(VCSession *vc)
141 LOGGER_DEBUG(vc->log, "Terminated video handler: %p", vc); 142 LOGGER_DEBUG(vc->log, "Terminated video handler: %p", vc);
142 free(vc); 143 free(vc);
143} 144}
144void vc_iterate(VCSession *vc, void *userdata) 145void vc_iterate(VCSession *vc)
145{ 146{
146 if (!vc) { 147 if (!vc) {
147 return; 148 return;
@@ -167,10 +168,10 @@ void vc_iterate(VCSession *vc, void *userdata)
167 168
168 /* Play decoded images */ 169 /* Play decoded images */
169 for (; dest; dest = vpx_codec_get_frame(vc->decoder, &iter)) { 170 for (; dest; dest = vpx_codec_get_frame(vc->decoder, &iter)) {
170 if (vc->on_video_frame) { 171 if (vc->vcb.first) {
171 vc->on_video_frame(vc->av, vc->friend_number, dest->d_w, dest->d_h, 172 vc->vcb.first(vc->av, vc->friend_number, dest->d_w, dest->d_h,
172 (const uint8_t *)dest->planes[0], (const uint8_t *)dest->planes[1], (const uint8_t *)dest->planes[2], 173 (const uint8_t *)dest->planes[0], (const uint8_t *)dest->planes[1], (const uint8_t *)dest->planes[2],
173 dest->stride[0], dest->stride[1], dest->stride[2], userdata); 174 dest->stride[0], dest->stride[1], dest->stride[2], vc->vcb.second);
174 } 175 }
175 176
176 vpx_img_free(dest); 177 vpx_img_free(dest);
diff --git a/toxav/video.h b/toxav/video.h
index e24d98c9..335240c7 100644
--- a/toxav/video.h
+++ b/toxav/video.h
@@ -56,14 +56,14 @@ typedef struct VCSession_s {
56 ToxAV *av; 56 ToxAV *av;
57 uint32_t friend_number; 57 uint32_t friend_number;
58 58
59 toxav_video_receive_frame_cb *on_video_frame; /* Video frame receive callback */ 59 PAIR(toxav_video_receive_frame_cb *, void *) vcb; /* Video frame receive callback */
60 60
61 pthread_mutex_t queue_mutex[1]; 61 pthread_mutex_t queue_mutex[1];
62} VCSession; 62} VCSession;
63 63
64VCSession *vc_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb); 64VCSession *vc_new(Logger *log, ToxAV *av, uint32_t friend_number, toxav_video_receive_frame_cb *cb, void *cb_data);
65void vc_kill(VCSession *vc); 65void vc_kill(VCSession *vc);
66void vc_iterate(VCSession *vc, void *userdata); 66void vc_iterate(VCSession *vc);
67int vc_queue_message(void *vcp, struct RTPMessage *msg); 67int vc_queue_message(void *vcp, struct RTPMessage *msg);
68int vc_reconfigure_encoder(VCSession *vc, uint32_t bit_rate, uint16_t width, uint16_t height); 68int vc_reconfigure_encoder(VCSession *vc, uint32_t bit_rate, uint16_t width, uint16_t height);
69 69
diff --git a/toxcore/Messenger.c b/toxcore/Messenger.c
index 9edf2132..def05449 100644
--- a/toxcore/Messenger.c
+++ b/toxcore/Messenger.c
@@ -413,12 +413,7 @@ int m_delfriend(Messenger *m, int32_t friendnumber)
413 } 413 }
414 414
415 if (m->friend_connectionstatuschange_internal) { 415 if (m->friend_connectionstatuschange_internal) {
416 // This is a direct callback to tell ToxAV that the friend has disconnected. 416 m->friend_connectionstatuschange_internal(m, friendnumber, 0, m->friend_connectionstatuschange_internal_userdata);
417 // The userdata in this callback is set to NULL, which will be passed back
418 // to the user if there is an active call. This behavior is expected, as the
419 // plan as of this commit is to update toxcore to ONLY send callbacks with
420 // tox_iterate().
421 m->friend_connectionstatuschange_internal(m, friendnumber, 0, m->friend_connectionstatuschange_internal_userdata, NULL);
422 } 417 }
423 418
424 clear_receipts(m, friendnumber); 419 clear_receipts(m, friendnumber);
@@ -890,8 +885,7 @@ void m_callback_core_connection(Messenger *m, void (*function)(Messenger *m, uns
890 m->core_connection_change = function; 885 m->core_connection_change = function;
891} 886}
892 887
893void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, void *, 888void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, void *),
894 void *),
895 void *userdata) 889 void *userdata)
896{ 890{
897 m->friend_connectionstatuschange_internal = function; 891 m->friend_connectionstatuschange_internal = function;
@@ -952,7 +946,7 @@ static void check_friend_connectionstatus(Messenger *m, int32_t friendnumber, ui
952 946
953 if (m->friend_connectionstatuschange_internal) { 947 if (m->friend_connectionstatuschange_internal) {
954 m->friend_connectionstatuschange_internal(m, friendnumber, is_online, 948 m->friend_connectionstatuschange_internal(m, friendnumber, is_online,
955 m->friend_connectionstatuschange_internal_userdata, userdata); 949 m->friend_connectionstatuschange_internal_userdata);
956 } 950 }
957 } 951 }
958} 952}
@@ -1717,11 +1711,11 @@ static int handle_filecontrol(Messenger *m, int32_t friendnumber, uint8_t receiv
1717 * 1711 *
1718 * Function(Messenger *m, int friendnumber, uint8_t *data, uint16_t length, void *userdata) 1712 * Function(Messenger *m, int friendnumber, uint8_t *data, uint16_t length, void *userdata)
1719 */ 1713 */
1720void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, uint16_t, void *, 1714void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, uint16_t, void *),
1721 void *), void *object) 1715 void *userdata)
1722{ 1716{
1723 m->msi_packet = function; 1717 m->msi_packet = function;
1724 m->msi_packet_userdata = object; 1718 m->msi_packet_userdata = userdata;
1725} 1719}
1726 1720
1727/* Send an msi packet. 1721/* Send an msi packet.
@@ -1747,7 +1741,7 @@ static int handle_custom_lossy_packet(void *object, int friend_num, const uint8_
1747 if (m->friendlist[friend_num].lossy_rtp_packethandlers[packet[0] % PACKET_LOSSY_AV_RESERVED].function) { 1741 if (m->friendlist[friend_num].lossy_rtp_packethandlers[packet[0] % PACKET_LOSSY_AV_RESERVED].function) {
1748 return m->friendlist[friend_num].lossy_rtp_packethandlers[packet[0] % PACKET_LOSSY_AV_RESERVED].function( 1742 return m->friendlist[friend_num].lossy_rtp_packethandlers[packet[0] % PACKET_LOSSY_AV_RESERVED].function(
1749 m, friend_num, packet, length, m->friendlist[friend_num].lossy_rtp_packethandlers[packet[0] % 1743 m, friend_num, packet, length, m->friendlist[friend_num].lossy_rtp_packethandlers[packet[0] %
1750 PACKET_LOSSY_AV_RESERVED].object, userdata); 1744 PACKET_LOSSY_AV_RESERVED].object);
1751 } 1745 }
1752 1746
1753 return 1; 1747 return 1;
@@ -1767,7 +1761,7 @@ void custom_lossy_packet_registerhandler(Messenger *m, void (*packet_handler_cal
1767} 1761}
1768 1762
1769int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, int (*packet_handler_callback)(Messenger *m, 1763int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, int (*packet_handler_callback)(Messenger *m,
1770 uint32_t friendnumber, const uint8_t *data, uint16_t len, void *object, void *userdata), void *object) 1764 uint32_t friendnumber, const uint8_t *data, uint16_t len, void *object), void *object)
1771{ 1765{
1772 if (friend_not_valid(m, friendnumber)) { 1766 if (friend_not_valid(m, friendnumber)) {
1773 return -1; 1767 return -1;
@@ -2339,7 +2333,7 @@ static int handle_packet(void *object, int i, const uint8_t *temp, uint16_t len,
2339 } 2333 }
2340 2334
2341 if (m->msi_packet) { 2335 if (m->msi_packet) {
2342 (*m->msi_packet)(m, i, data, data_length, m->msi_packet_userdata, userdata); 2336 (*m->msi_packet)(m, i, data, data_length, m->msi_packet_userdata);
2343 } 2337 }
2344 2338
2345 break; 2339 break;
diff --git a/toxcore/Messenger.h b/toxcore/Messenger.h
index 6f99f15b..2317eb8b 100644
--- a/toxcore/Messenger.h
+++ b/toxcore/Messenger.h
@@ -200,11 +200,8 @@ typedef struct {
200 unsigned int num_sending_files; 200 unsigned int num_sending_files;
201 struct File_Transfers file_receiving[MAX_CONCURRENT_FILE_PIPES]; 201 struct File_Transfers file_receiving[MAX_CONCURRENT_FILE_PIPES];
202 202
203 /* ToxAV, *object is the internal session data for the active call, userdata is the *pointer provided in
204 * tox_iterate()
205 */
206 struct { 203 struct {
207 int (*function)(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t len, void *object, void *userdata); 204 int (*function)(Messenger *m, uint32_t friendnumber, const uint8_t *data, uint16_t len, void *object);
208 void *object; 205 void *object;
209 } lossy_rtp_packethandlers[PACKET_LOSSY_AV_RESERVED]; 206 } lossy_rtp_packethandlers[PACKET_LOSSY_AV_RESERVED];
210 207
@@ -248,8 +245,7 @@ struct Messenger {
248 void (*friend_typingchange)(struct Messenger *m, uint32_t, bool, void *); 245 void (*friend_typingchange)(struct Messenger *m, uint32_t, bool, void *);
249 void (*read_receipt)(struct Messenger *m, uint32_t, uint32_t, void *); 246 void (*read_receipt)(struct Messenger *m, uint32_t, uint32_t, void *);
250 void (*friend_connectionstatuschange)(struct Messenger *m, uint32_t, unsigned int, void *); 247 void (*friend_connectionstatuschange)(struct Messenger *m, uint32_t, unsigned int, void *);
251 void (*friend_connectionstatuschange_internal)(struct Messenger *m, uint32_t, uint8_t, void *, void *); 248 void (*friend_connectionstatuschange_internal)(struct Messenger *m, uint32_t, uint8_t, void *);
252 /* ToxAV internal session data */
253 void *friend_connectionstatuschange_internal_userdata; 249 void *friend_connectionstatuschange_internal_userdata;
254 250
255 void *group_chat_object; /* Set by new_groupchats()*/ 251 void *group_chat_object; /* Set by new_groupchats()*/
@@ -262,7 +258,7 @@ struct Messenger {
262 void (*file_filedata)(struct Messenger *m, uint32_t, uint32_t, uint64_t, const uint8_t *, size_t, void *); 258 void (*file_filedata)(struct Messenger *m, uint32_t, uint32_t, uint64_t, const uint8_t *, size_t, void *);
263 void (*file_reqchunk)(struct Messenger *m, uint32_t, uint32_t, uint64_t, size_t, void *); 259 void (*file_reqchunk)(struct Messenger *m, uint32_t, uint32_t, uint64_t, size_t, void *);
264 260
265 void (*msi_packet)(struct Messenger *m, uint32_t, const uint8_t *, uint16_t, void *, void *); 261 void (*msi_packet)(struct Messenger *m, uint32_t, const uint8_t *, uint16_t, void *);
266 void *msi_packet_userdata; 262 void *msi_packet_userdata;
267 263
268 void (*lossy_packethandler)(struct Messenger *m, uint32_t, const uint8_t *, size_t, void *); 264 void (*lossy_packethandler)(struct Messenger *m, uint32_t, const uint8_t *, size_t, void *);
@@ -527,8 +523,7 @@ void m_callback_read_receipt(Messenger *m, void (*function)(Messenger *m, uint32
527void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, uint32_t, unsigned int, void *)); 523void m_callback_connectionstatus(Messenger *m, void (*function)(Messenger *m, uint32_t, unsigned int, void *));
528 524
529/* Same as previous but for internal A/V core usage only */ 525/* Same as previous but for internal A/V core usage only */
530void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, void *, 526void m_callback_connectionstatus_internal_av(Messenger *m, void (*function)(Messenger *m, uint32_t, uint8_t, void *),
531 void *),
532 void *userdata); 527 void *userdata);
533 528
534 529
@@ -662,8 +657,8 @@ uint64_t file_dataremaining(const Messenger *m, int32_t friendnumber, uint8_t fi
662 * 657 *
663 * Function(Messenger *m, uint32_t friendnumber, uint8_t *data, uint16_t length, void *userdata) 658 * Function(Messenger *m, uint32_t friendnumber, uint8_t *data, uint16_t length, void *userdata)
664 */ 659 */
665void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, uint16_t, void *, 660void m_callback_msi_packet(Messenger *m, void (*function)(Messenger *m, uint32_t, const uint8_t *, uint16_t, void *),
666 void *), void *toxav_session); 661 void *userdata);
667 662
668/* Send an msi packet. 663/* Send an msi packet.
669 * 664 *
@@ -678,7 +673,7 @@ int m_msi_packet(const Messenger *m, int32_t friendnumber, const uint8_t *data,
678 * return 0 on success. 673 * return 0 on success.
679 */ 674 */
680int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, int (*packet_handler_callback)(Messenger *m, 675int m_callback_rtp_packet(Messenger *m, int32_t friendnumber, uint8_t byte, int (*packet_handler_callback)(Messenger *m,
681 uint32_t friendnumber, const uint8_t *data, uint16_t len, void *object, void *userdata), void *object); 676 uint32_t friendnumber, const uint8_t *data, uint16_t len, void *object), void *object);
682 677
683/**********************************************/ 678/**********************************************/
684 679
diff --git a/toxcore/tox.h b/toxcore/tox.h
index 268ae779..47573302 100644
--- a/toxcore/tox.h
+++ b/toxcore/tox.h
@@ -1237,10 +1237,6 @@ typedef enum TOX_ERR_FRIEND_DELETE {
1237 * function, this client will appear offline to the friend and no communication 1237 * function, this client will appear offline to the friend and no communication
1238 * can occur between the two. 1238 * can occur between the two.
1239 * 1239 *
1240 * WARNING, calling tox_friend_delete while there's an active ToxAV call will
1241 * result in undefined behavior. It's the client's responsibility to end all
1242 * ToxAV calls before deleting a friend.
1243 *
1244 * @param friend_number Friend number for the friend to be deleted. 1240 * @param friend_number Friend number for the friend to be deleted.
1245 * 1241 *
1246 * @return true on success. 1242 * @return true on success.
diff --git a/toxcore/util.h b/toxcore/util.h
index d7ad7beb..840f0a3e 100644
--- a/toxcore/util.h
+++ b/toxcore/util.h
@@ -30,6 +30,7 @@
30#include <stdint.h> 30#include <stdint.h>
31 31
32#define MIN(a,b) (((a)<(b))?(a):(b)) 32#define MIN(a,b) (((a)<(b))?(a):(b))
33#define PAIR(TYPE1__, TYPE2__) struct { TYPE1__ first; TYPE2__ second; }
33 34
34void unix_time_update(void); 35void unix_time_update(void);
35uint64_t unix_time(void); 36uint64_t unix_time(void);