diff options
Diffstat (limited to 'toxav/toxav.c')
-rw-r--r-- | toxav/toxav.c | 187 |
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 | ||
83 | void i_toxav_msi_callback_invite(void* toxav_inst, int32_t call_idx, void *data); | 83 | void i_callback_invite(void* toxav_inst, MSICall* call); |
84 | void i_toxav_msi_callback_ringing(void* toxav_inst, int32_t call_idx, void *data); | 84 | void i_callback_ringing(void* toxav_inst, MSICall* call); |
85 | void i_toxav_msi_callback_start(void* toxav_inst, int32_t call_idx, void *data); | 85 | void i_callback_start(void* toxav_inst, MSICall* call); |
86 | void i_toxav_msi_callback_reject(void* toxav_inst, int32_t call_idx, void *data); | 86 | void i_callback_end(void* toxav_inst, MSICall* call); |
87 | void i_toxav_msi_callback_end(void* toxav_inst, int32_t call_idx, void *data); | 87 | void i_callback_error(void* toxav_inst, MSICall* call); |
88 | void i_toxav_msi_callback_request_to(void* toxav_inst, int32_t call_idx, void *data); /* TODO remove */ | 88 | void i_callback_capabilites(void* toxav_inst, MSICall* call); |
89 | void i_toxav_msi_callback_peer_to(void* toxav_inst, int32_t call_idx, void *data); | ||
90 | void i_toxav_msi_callback_state_change(void* toxav_inst, int32_t call_idx, void *data); | ||
91 | 89 | ||
90 | TOXAV_CALL_STATE capabilities_to_state(uint8_t capabilities); | ||
92 | IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number); | 91 | IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number); |
93 | IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number); | 92 | IToxAVCall* i_toxav_add_call(ToxAV* av, uint32_t friend_number); |
94 | void i_toxav_remove_call(ToxAV* av, uint32_t friend_number); | 93 | void i_toxav_remove_call(ToxAV* av, uint32_t friend_number); |
94 | IToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, TOXAV_ERR_CALL* error); | ||
95 | bool i_toxav_audio_bitrate_invalid(uint32_t bitrate); | 95 | bool i_toxav_audio_bitrate_invalid(uint32_t bitrate); |
96 | bool i_toxav_video_bitrate_invalid(uint32_t bitrate); | 96 | bool i_toxav_video_bitrate_invalid(uint32_t bitrate); |
97 | IToxAVCall* i_toxav_init_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error); | ||
98 | bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call); | 97 | bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call); |
99 | void i_toxav_kill_transmission(ToxAV* av, uint32_t friend_number); | 98 | void 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 | ||
210 | bool toxav_call(ToxAV* av, uint32_t friend_number, uint32_t audio_bit_rate, uint32_t video_bit_rate, TOXAV_ERR_CALL* error) | 208 | bool 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 | */ |
536 | void i_toxav_msi_callback_invite(void* toxav_inst, int32_t call_idx, void* data) | 532 | void 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 | ||
555 | void i_toxav_msi_callback_ringing(void* toxav_inst, int32_t call_idx, void* data) | 551 | void 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 | ||
563 | void i_toxav_msi_callback_start(void* toxav_inst, int32_t call_idx, void* data) | 558 | void 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 | |||
589 | void 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 | ||
601 | void i_toxav_msi_callback_end(void* toxav_inst, int32_t call_idx, void* data) | 576 | void 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 | ||
613 | void i_toxav_msi_callback_request_to(void* toxav_inst, int32_t call_idx, void* data) | 587 | void 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 | ||
622 | void i_toxav_msi_callback_peer_to(void* toxav_inst, int32_t call_idx, void* data) | 594 | void 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 | ||
630 | void i_toxav_msi_callback_state_change(void* toxav_inst, int32_t call_idx, void* data) | 600 | TOXAV_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 | ||
636 | IToxAVCall* i_toxav_get_call(ToxAV* av, uint32_t friend_number) | 612 | IToxAVCall* 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 | ||
745 | bool i_toxav_audio_bitrate_invalid(uint32_t bitrate) | 721 | IToxAVCall* 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 | |||
753 | bool 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 | |||
759 | IToxAVCall* 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 | ||
791 | END: | 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 | ||
753 | bool 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 | |||
761 | bool 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 | |||
798 | bool i_toxav_prepare_transmission(ToxAV* av, IToxAVCall* call) | 767 | bool 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 |