summaryrefslogtreecommitdiff
path: root/toxav/toxav.c
diff options
context:
space:
mode:
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r--toxav/toxav.c187
1 files changed, 78 insertions, 109 deletions
diff --git a/toxav/toxav.c b/toxav/toxav.c
index 864d16cf..12a65737 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -49,8 +49,8 @@ typedef struct iToxAVCall
49 RTPSession *rtps[2]; /** Audio is first and video is second */ 49 RTPSession *rtps[2]; /** Audio is first and video is second */
50 CSSession *cs; 50 CSSession *cs;
51 bool active; 51 bool active;
52 int32_t friend_number; 52 int32_t friend_id;
53 int32_t call_idx; /* FIXME msi compat, remove */ 53 MSICall* msi_call;
54 54
55 struct iToxAVCall *prev; 55 struct iToxAVCall *prev;
56 struct iToxAVCall *next; 56 struct iToxAVCall *next;
@@ -80,21 +80,20 @@ struct toxAV
80}; 80};
81 81
82 82
83void i_toxav_msi_callback_invite(void* toxav_inst, int32_t call_idx, void *data); 83void i_callback_invite(void* toxav_inst, MSICall* call);
84void i_toxav_msi_callback_ringing(void* toxav_inst, int32_t call_idx, void *data); 84void i_callback_ringing(void* toxav_inst, MSICall* call);
85void i_toxav_msi_callback_start(void* toxav_inst, int32_t call_idx, void *data); 85void i_callback_start(void* toxav_inst, MSICall* call);
86void i_toxav_msi_callback_reject(void* toxav_inst, int32_t call_idx, void *data); 86void i_callback_end(void* toxav_inst, MSICall* call);
87void i_toxav_msi_callback_end(void* toxav_inst, int32_t call_idx, void *data); 87void i_callback_error(void* toxav_inst, MSICall* call);
88void i_toxav_msi_callback_request_to(void* toxav_inst, int32_t call_idx, void *data); /* TODO remove */ 88void i_callback_capabilites(void* toxav_inst, MSICall* call);
89void i_toxav_msi_callback_peer_to(void* toxav_inst, int32_t call_idx, void *data);
90void i_toxav_msi_callback_state_change(void* toxav_inst, int32_t call_idx, void *data);
91 89
90TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities);
92IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number); 91IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number);
93IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number); 92IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number);
94void i_toxav_remove_call(ToxAV* av, uint32_t friend_number); 93void i_toxav_remove_call(ToxAV* av, uint32_t friend_number);
94IToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error);
95bool i_toxav_audio_bitrate_invalid(uint32_t bitrate); 95bool i_toxav_audio_bitrate_invalid(uint32_t bitrate);
96bool i_toxav_video_bitrate_invalid(uint32_t bitrate); 96bool i_toxav_video_bitrate_invalid(uint32_t bitrate);
97IToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error);
98bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call); 97bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call);
99void i_toxav_kill_transmission(ToxAV* av, uint32_t friend_number); 98void i_toxav_kill_transmission(ToxAV* av, uint32_t friend_number);
100 99
@@ -124,7 +123,7 @@ ToxAV* toxav_new(Tox* tox, TOXAV_ERR_NEW* error)
124 } 123 }
125 124
126 av->m = (Messenger *)tox; 125 av->m = (Messenger *)tox;
127 av->msi = msi_new(av->m, 100); /* TODO remove max calls */ 126 av->msi = msi_new(av->m);
128 127
129 if (av->msi == NULL) { 128 if (av->msi == NULL) {
130 rc = TOXAV_ERR_NEW_MALLOC; 129 rc = TOXAV_ERR_NEW_MALLOC;
@@ -132,17 +131,16 @@ ToxAV* toxav_new(Tox* tox, TOXAV_ERR_NEW* error)
132 } 131 }
133 132
134 av->interval = 200; 133 av->interval = 200;
135 av->msi->agent_handler = av; 134 av->msi->av = av;
136 135
137 msi_register_callback(av->msi, i_toxav_msi_callback_invite, msi_OnInvite, NULL); 136 msi_register_callback(av->msi, i_callback_invite, msi_OnInvite);
138 msi_register_callback(av->msi, i_toxav_msi_callback_ringing, msi_OnRinging, NULL); 137 msi_register_callback(av->msi, i_callback_ringing, msi_OnRinging);
139 msi_register_callback(av->msi, i_toxav_msi_callback_start, msi_OnStart, NULL); 138 msi_register_callback(av->msi, i_callback_start, msi_OnStart);
140 msi_register_callback(av->msi, i_toxav_msi_callback_reject, msi_OnReject, NULL); 139 msi_register_callback(av->msi, i_callback_end, msi_OnReject);
141 msi_register_callback(av->msi, i_toxav_msi_callback_end, msi_OnEnd, NULL); 140 msi_register_callback(av->msi, i_callback_end, msi_OnEnd);
142 msi_register_callback(av->msi, i_toxav_msi_callback_request_to, msi_OnRequestTimeout, NULL); 141 msi_register_callback(av->msi, i_callback_error, msi_OnError);
143 msi_register_callback(av->msi, i_toxav_msi_callback_peer_to, msi_OnPeerTimeout, NULL); 142 msi_register_callback(av->msi, i_callback_error, msi_OnPeerTimeout);
144 msi_register_callback(av->msi, i_toxav_msi_callback_state_change, msi_OnPeerCSChange, NULL); 143 msi_register_callback(av->msi, i_callback_capabilites, msi_OnCapabilities);
145 msi_register_callback(av->msi, i_toxav_msi_callback_state_change, msi_OnSelfCSChange, NULL);
146 144
147 145
148 if (error) 146 if (error)
@@ -209,7 +207,7 @@ void toxav_iteration(ToxAV* av)
209 207
210bool toxav_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error) 208bool toxav_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error)
211{ 209{
212 IToxAVCall* call = i_toxav_init_call(av, friend_number, audio_bit_rate, video_bit_rate, error); 210 IToxAVCall* call = i_toxav_init_call(av, friend_number, error);
213 if (call == NULL) { 211 if (call == NULL) {
214 return false; 212 return false;
215 } 213 }
@@ -528,109 +526,87 @@ void toxav_callback_receive_audio_frame(ToxAV* av, toxav_receive_audio_frame_cb*
528 * 526 *
529 ******************************************************************************/ 527 ******************************************************************************/
530/** TODO: 528/** TODO:
531 * - In msi call_idx can be the same as friend id 529 * - If crutial callback not present send error.
532 * - If crutial callback not present send error 530 * - Error handling by return values from callbacks and setting 'error'.
533 * - Remove *data from msi
534 * - Remove CSettings from msi
535 */ 531 */
536void i_toxav_msi_callback_invite(void* toxav_inst, int32_t call_idx, void* data) 532void i_callback_invite(void* toxav_inst, MSICall* call)
537{ 533{
538 ToxAV* toxav = toxav_inst; 534 ToxAV* toxav = toxav_inst;
539 535
540 uint32_t ab = toxav->msi->calls[call_idx]->csettings_peer[0].audio_bitrate; 536 IToxAVCall* av_call = i_toxav_init_call(toxav, call->friend_id, NULL);
541 uint32_t vb = toxav->msi->calls[call_idx]->csettings_peer[0].video_bitrate; 537 if (av_call == NULL) {
542 538 LOGGER_WARNING("Failed to start call, rejecting...");
543 IToxAVCall* call = i_toxav_init_call(toxav, toxav->msi->calls[call_idx]->peers[0], ab, vb, NULL); 539 msi_reject(toxav->msi, call);
544 if (call == NULL) { 540 return;
545 LOGGER_WARNING("No call, rejecting...");
546 msi_reject(toxav->msi, call_idx, NULL);
547 } 541 }
548 542
549 call->call_idx = call_idx; 543 call->av_call = av_call;
544 av_call->msi_call = call;
550 545
551 if (toxav->ccb.first) 546 if (toxav->ccb.first)
552 toxav->ccb.first(toxav, toxav->msi->calls[call_idx]->peers[0], true, true, toxav->ccb.second); 547 toxav->ccb.first(toxav, call->friend_id, call->peer_capabilities & msi_CapSAudio,
548 call->peer_capabilities & msi_CapSVideo, toxav->ccb.second);
553} 549}
554 550
555void i_toxav_msi_callback_ringing(void* toxav_inst, int32_t call_idx, void* data) 551void i_callback_ringing(void* toxav_inst, MSICall* call)
556{ 552{
557 ToxAV* toxav = toxav_inst; 553 ToxAV* toxav = toxav_inst;
558 if (toxav->scb.first) 554 if (toxav->scb.first)
559 toxav->scb.first(toxav, toxav->msi->calls[call_idx]->peers[0], 555 toxav->scb.first(toxav, call->friend_id, TOXAV_CALL_STATE_RINGING, toxav->scb.second);
560 TOXAV_CALL_STATE_RINGING, toxav->scb.second);
561} 556}
562 557
563void i_toxav_msi_callback_start(void* toxav_inst, int32_t call_idx, void* data) 558void i_callback_start(void* toxav_inst, MSICall* call)
564{ 559{
565 ToxAV* toxav = toxav_inst; 560 ToxAV* toxav = toxav_inst;
566 561
567 IToxAVCall* call = i_toxav_get_call(toxav, toxav->msi->calls[call_idx]->peers[0]); 562 IToxAVCall* call = i_toxav_get_call(toxav, call->friend_id);
568 563
569 if (call == NULL || !i_toxav_prepare_transmission(toxav, call)) { 564 if (call == NULL || !i_toxav_prepare_transmission(toxav, call)) {
570 /* TODO send error */ 565 /* TODO send error */
571 i_toxav_remove_call(toxav, toxav->msi->calls[call_idx]->peers[0]); 566 i_toxav_remove_call(toxav, call->friend_id);
572 return; 567 return;
573 } 568 }
574 569
575 TOXAV_CALL_STATE state; 570 TOXAV_CALL_STATE state = capabilities_to_state(call->msi_call->peer_capabilities);
576 const MSICSettings* csets = &toxav->msi->calls[call_idx]->csettings_peer[0];
577
578 if (csets->audio_bitrate && csets->video_bitrate)
579 state = TOXAV_CALL_STATE_SENDING_AV;
580 else if (csets->video_bitrate == 0)
581 state = TOXAV_CALL_STATE_SENDING_A;
582 else
583 state = TOXAV_CALL_STATE_SENDING_V;
584
585 if (toxav->scb.first) /* TODO this */
586 toxav->scb.first(toxav, call->friend_number, state, toxav->scb.second);
587}
588
589void i_toxav_msi_callback_reject(void* toxav_inst, int32_t call_idx, void* data)
590{
591 ToxAV* toxav = toxav_inst;
592
593 i_toxav_kill_transmission(toxav, toxav->msi->calls[call_idx]->peers[0]);
594 i_toxav_remove_call(toxav, toxav->msi->calls[call_idx]->peers[0]);
595 571
596 if (toxav->scb.first) 572 if (toxav->scb.first)
597 toxav->scb.first(toxav, toxav->msi->calls[call_idx]->peers[0], 573 toxav->scb.first(toxav, call->friend_id, state, toxav->scb.second);
598 TOXAV_CALL_STATE_END, toxav->scb.second);
599} 574}
600 575
601void i_toxav_msi_callback_end(void* toxav_inst, int32_t call_idx, void* data) 576void i_callback_end(void* toxav_inst, MSICall* call)
602{ 577{
603 ToxAV* toxav = toxav_inst; 578 ToxAV* toxav = toxav_inst;
604 579
605 i_toxav_kill_transmission(toxav, toxav->msi->calls[call_idx]->peers[0]); 580 i_toxav_kill_transmission(toxav, call->friend_id);
606 i_toxav_remove_call(toxav, toxav->msi->calls[call_idx]->peers[0]); 581 i_toxav_remove_call(toxav, call->friend_id);
607 582
608 if (toxav->scb.first) 583 if (toxav->scb.first)
609 toxav->scb.first(toxav, toxav->msi->calls[call_idx]->peers[0], 584 toxav->scb.first(toxav, call->friend_id, TOXAV_CALL_STATE_END, toxav->scb.second);
610 TOXAV_CALL_STATE_END, toxav->scb.second);
611} 585}
612 586
613void i_toxav_msi_callback_request_to(void* toxav_inst, int32_t call_idx, void* data) 587void i_callback_error(void* toxav_inst, MSICall* call)
614{ 588{
615 /* TODO remove */
616 ToxAV* toxav = toxav_inst; 589 ToxAV* toxav = toxav_inst;
617 if (toxav->scb.first) 590 if (toxav->scb.first)
618 toxav->scb.first(toxav, toxav->msi->calls[call_idx]->peers[0], 591 toxav->scb.first(toxav, call->friend_id, TOXAV_CALL_STATE_ERROR, toxav->scb.second);
619 TOXAV_CALL_STATE_ERROR, toxav->scb.second);
620} 592}
621 593
622void i_toxav_msi_callback_peer_to(void* toxav_inst, int32_t call_idx, void* data) 594void i_callback_capabilites(void* toxav_inst, MSICall* call)
623{ 595{
624 ToxAV* toxav = toxav_inst; 596 ToxAV* toxav = toxav_inst;
625 if (toxav->scb.first) 597 /* TODO something something msi */
626 toxav->scb.first(toxav, toxav->msi->calls[call_idx]->peers[0],
627 TOXAV_CALL_STATE_ERROR, toxav->scb.second);
628} 598}
629 599
630void i_toxav_msi_callback_state_change(void* toxav_inst, int32_t call_idx, void* data) 600TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities)
631{ 601{
632 ToxAV* toxav = toxav_inst; 602 if ((capabilities & msi_CapSAudio) && (capabilities & msi_CapSVideo))
633 /* TODO something something msi */ 603 return TOXAV_CALL_STATE_SENDING_AV;
604 else if (capabilities & msi_CapSAudio)
605 return TOXAV_CALL_STATE_SENDING_A;
606 else if (capabilities & msi_CapSVideo)
607 return TOXAV_CALL_STATE_SENDING_V;
608 else
609 return TOXAV_CALL_STATE_PAUSED;
634} 610}
635 611
636IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number) 612IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number)
@@ -648,7 +624,7 @@ IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number)
648 if (rc == NULL) 624 if (rc == NULL)
649 return NULL; 625 return NULL;
650 626
651 rc->friend_number = friend_number; 627 rc->friend_id = friend_number;
652 628
653 if (create_recursive_mutex(rc->mutex_control) != 0) { 629 if (create_recursive_mutex(rc->mutex_control) != 0) {
654 free(rc); 630 free(rc);
@@ -724,13 +700,13 @@ void i_toxav_remove_call(ToxAV* av, uint32_t friend_number)
724 if (prev) 700 if (prev)
725 prev->next = next; 701 prev->next = next;
726 else if (next) 702 else if (next)
727 av->calls_head = next->friend_number; 703 av->calls_head = next->friend_id;
728 else goto CLEAR; 704 else goto CLEAR;
729 705
730 if (next) 706 if (next)
731 next->prev = prev; 707 next->prev = prev;
732 else if (prev) 708 else if (prev)
733 av->calls_tail = prev->friend_number; 709 av->calls_tail = prev->friend_id;
734 else goto CLEAR; 710 else goto CLEAR;
735 711
736 av->calls[friend_number] = NULL; 712 av->calls[friend_number] = NULL;
@@ -742,21 +718,7 @@ CLEAR:
742 av->calls = NULL; 718 av->calls = NULL;
743} 719}
744 720
745bool i_toxav_audio_bitrate_invalid(uint32_t bitrate) 721IToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error)
746{
747 /* Opus RFC 6716 section-2.1.1 dictates the following:
748 * Opus supports all bitrates from 6 kbit/s to 510 kbit/s.
749 */
750 return bitrate < 6 || bitrate > 510;
751}
752
753bool i_toxav_video_bitrate_invalid(uint32_t bitrate)
754{
755 /* TODO: If anyone knows the answer to this one please fill it up */
756 return false;
757}
758
759IToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error)
760{ 722{
761 TOXAV_ERR_CALL rc = TOXAV_ERR_CALL_OK; 723 TOXAV_ERR_CALL rc = TOXAV_ERR_CALL_OK;
762 IToxAVCall* call = NULL; 724 IToxAVCall* call = NULL;
@@ -776,25 +738,32 @@ IToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, uint32_t audio_
776 goto END; 738 goto END;
777 } 739 }
778 740
779 if ((audio_bit_rate && i_toxav_audio_bitrate_invalid(audio_bit_rate))
780 ||(video_bit_rate && i_toxav_video_bitrate_invalid(video_bit_rate))
781 ) {
782 rc = TOXAV_ERR_CALL_INVALID_BIT_RATE;
783 goto END;
784 }
785
786 call = i_toxav_add_call(av, friend_number); 741 call = i_toxav_add_call(av, friend_number);
787 if (call == NULL) { 742 if (call == NULL) {
788 rc = TOXAV_ERR_CALL_MALLOC; 743 rc = TOXAV_ERR_CALL_MALLOC;
789 } 744 }
790 745
791END: 746 END:
792 if (error) 747 if (error)
793 *error = rc; 748 *error = rc;
794 749
795 return call; 750 return call;
796} 751}
797 752
753bool i_toxav_audio_bitrate_invalid(uint32_t bitrate)
754{
755 /* Opus RFC 6716 section-2.1.1 dictates the following:
756 * Opus supports all bitrates from 6 kbit/s to 510 kbit/s.
757 */
758 return bitrate < 6 || bitrate > 510;
759}
760
761bool i_toxav_video_bitrate_invalid(uint32_t bitrate)
762{
763 /* TODO: If anyone knows the answer to this one please fill it up */
764 return false;
765}
766
798bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call) 767bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call)
799{ 768{
800 pthread_mutex_lock(call->mutex_control); 769 pthread_mutex_lock(call->mutex_control);
@@ -838,7 +807,7 @@ bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call)
838 memcpy(&call->cs->acb, &av->acb, sizeof(av->acb)); 807 memcpy(&call->cs->acb, &av->acb, sizeof(av->acb));
839 memcpy(&call->cs->vcb, &av->vcb, sizeof(av->vcb)); 808 memcpy(&call->cs->vcb, &av->vcb, sizeof(av->vcb));
840 809
841 call->cs->friend_number = call->friend_number; 810 call->cs->friend_number = call->friend_id;
842 call->cs->call_idx = call->call_idx; 811 call->cs->call_idx = call->call_idx;
843 812
844 813
@@ -929,4 +898,4 @@ void i_toxav_kill_transmission(ToxAV* av, uint32_t friend_number)
929 pthread_mutex_destroy(call->mutex_do); 898 pthread_mutex_destroy(call->mutex_do);
930 899
931 pthread_mutex_unlock(call->mutex_control); 900 pthread_mutex_unlock(call->mutex_control);
932} 901} \ No newline at end of file