diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index 2f56f6bbf..15abe2ca6 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -33,15 +33,15 @@ static bool_t only_telephone_event(const MSList *l){ typedef struct _PayloadTypeMatcher{ const char *mime_type; - PayloadType *(*match_func)(const MSList *l, const PayloadType *refpt); + PayloadType *(*match_func)(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads); }PayloadTypeMatcher; -static PayloadType * opus_match(const MSList *l, const PayloadType *refpt){ +static PayloadType * opus_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){ PayloadType *pt; const MSList *elem; PayloadType *candidate=NULL; - for (elem=l;elem!=NULL;elem=elem->next){ + for (elem=local_payloads;elem!=NULL;elem=elem->next){ pt=(PayloadType*)elem->data; /*workaround a bug in earlier versions of linphone where opus/48000/1 is offered, which is uncompliant with opus rtp draft*/ @@ -58,12 +58,12 @@ static PayloadType * opus_match(const MSList *l, const PayloadType *refpt){ } /* the reason for this matcher is for some stupid uncompliant phone that offer G729a mime type !*/ -static PayloadType * g729A_match(const MSList *l, const PayloadType *refpt){ +static PayloadType * g729A_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){ PayloadType *pt; const MSList *elem; PayloadType *candidate=NULL; - for (elem=l;elem!=NULL;elem=elem->next){ + for (elem=local_payloads;elem!=NULL;elem=elem->next){ pt=(PayloadType*)elem->data; if (strcasecmp(pt->mime_type,"G729")==0 && refpt->channels==pt->channels){ @@ -73,13 +73,13 @@ static PayloadType * g729A_match(const MSList *l, const PayloadType *refpt){ return candidate; } -static PayloadType * amr_match(const MSList *l, const PayloadType *refpt){ +static PayloadType * amr_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){ PayloadType *pt; char value[10]; const MSList *elem; PayloadType *candidate=NULL; - for (elem=l;elem!=NULL;elem=elem->next){ + for (elem=local_payloads;elem!=NULL;elem=elem->next){ pt=(PayloadType*)elem->data; if ( pt->mime_type && refpt->mime_type @@ -102,11 +102,11 @@ static PayloadType * amr_match(const MSList *l, const PayloadType *refpt){ return candidate; } -static PayloadType * generic_match(const MSList *l, const PayloadType *refpt){ +static PayloadType * generic_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){ PayloadType *pt; const MSList *elem; - for (elem=l;elem!=NULL;elem=elem->next){ + for (elem=local_payloads;elem!=NULL;elem=elem->next){ pt=(PayloadType*)elem->data; if ( pt->mime_type && refpt->mime_type @@ -118,11 +118,37 @@ static PayloadType * generic_match(const MSList *l, const PayloadType *refpt){ return NULL; } +static PayloadType * red_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads) { + const MSList *elem_local, *elem_remote; + PayloadType *red = NULL; + + for (elem_local = local_payloads; elem_local != NULL; elem_local = elem_local->next) { + PayloadType *pt = (PayloadType*)elem_local->data; + + if (strcasecmp(pt->mime_type, payload_type_t140_red.mime_type) == 0) { + red = pt; + + for (elem_remote = remote_payloads; elem_remote != NULL; elem_remote = elem_remote->next) { + PayloadType *pt2 = (PayloadType*)elem_remote->data; + if (strcasecmp(pt2->mime_type, payload_type_t140.mime_type) == 0) { + int t140_payload_number = payload_type_get_number(pt2); + const char *red_fmtp = ms_strdup_printf("%i/%i/%i", t140_payload_number, t140_payload_number, t140_payload_number); + payload_type_set_recv_fmtp(red, red_fmtp); + break; + } + } + break; + } + } + return red; +} + static PayloadTypeMatcher matchers[]={ {"opus", opus_match}, {"G729A", g729A_match}, {"AMR", amr_match}, {"AMR-WB", amr_match}, + {"red", red_match}, {NULL, NULL} }; @@ -130,14 +156,14 @@ static PayloadTypeMatcher matchers[]={ /* * Returns a PayloadType from the local list that matches a PayloadType offered or answered in the remote list */ -static PayloadType * find_payload_type_best_match(const MSList *l, const PayloadType *refpt){ +static PayloadType * find_payload_type_best_match(const MSList *local_payloads, const PayloadType *refpt, const MSList *remote_payloads){ PayloadTypeMatcher *m; for(m=matchers;m->mime_type!=NULL;++m){ if (refpt->mime_type && strcasecmp(m->mime_type,refpt->mime_type)==0){ - return m->match_func(l,refpt); + return m->match_func(local_payloads, refpt, remote_payloads); } } - return generic_match(l,refpt); + return generic_match(local_payloads, refpt, remote_payloads); } @@ -149,7 +175,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t for(e2=remote;e2!=NULL;e2=e2->next){ PayloadType *p2=(PayloadType*)e2->data; - matched=find_payload_type_best_match(local,p2); + matched=find_payload_type_best_match(local,p2,remote); if (matched){ PayloadType *newp; int local_number=payload_type_get_number(matched); diff --git a/tester/message_tester.c b/tester/message_tester.c index 0e9aa0adf..25e56b8d7 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -1289,13 +1289,33 @@ static void file_transfer_io_error_after_destroying_chatroom(void) { file_transfer_io_error_base("https://www.linphone.org:444/lft.php", TRUE); } -static void real_time_text(bool_t audio_stream_enabled, bool_t srtp_enabled) { +static void real_time_text(bool_t audio_stream_enabled, bool_t srtp_enabled, bool_t mess_with_marie_payload_number, bool_t mess_with_pauline_payload_number) { LinphoneChatRoom *pauline_chat_room; LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCallParams *marie_params = NULL; LinphoneCall *pauline_call, *marie_call; + if (mess_with_marie_payload_number) { + MSList *elem; + for (elem = marie->lc->codecs_conf.text_codecs; elem != NULL; elem = elem->next) { + PayloadType *pt = (PayloadType*)elem->data; + if (strcasecmp(pt->mime_type, payload_type_t140.mime_type) == 0) { + payload_type_set_number(pt, 99); + break; + } + } + } else if (mess_with_pauline_payload_number) { + MSList *elem; + for (elem = pauline->lc->codecs_conf.text_codecs; elem != NULL; elem = elem->next) { + PayloadType *pt = (PayloadType*)elem->data; + if (strcasecmp(pt->mime_type, payload_type_t140.mime_type) == 0) { + payload_type_set_number(pt, 99); + break; + } + } + } + if (srtp_enabled) { BC_ASSERT_TRUE(linphone_core_media_encryption_supported(marie->lc, LinphoneMediaEncryptionSRTP)); linphone_core_set_media_encryption(marie->lc, LinphoneMediaEncryptionSRTP); @@ -1353,7 +1373,7 @@ static void real_time_text(bool_t audio_stream_enabled, bool_t srtp_enabled) { } static void real_time_text_message(void) { - real_time_text(TRUE, FALSE); + real_time_text(TRUE, FALSE, FALSE, FALSE); } static void real_time_text_conversation(void) { @@ -1456,11 +1476,11 @@ static void real_time_text_conversation(void) { } static void real_time_text_without_audio(void) { - real_time_text(FALSE, FALSE); + real_time_text(FALSE, FALSE, FALSE, FALSE); } static void real_time_text_srtp(void) { - real_time_text(TRUE, TRUE); + real_time_text(TRUE, TRUE, FALSE, FALSE); } static void real_time_text_message_compat(bool_t end_with_crlf, bool_t end_with_lf) { @@ -1568,6 +1588,14 @@ static void real_time_text_message_accented_chars() { linphone_core_manager_destroy(pauline); } +static void real_time_text_message_different_text_codecs_payload_numbers_sender_side() { + real_time_text(FALSE, FALSE, TRUE, FALSE); +} + +static void real_time_text_message_different_text_codecs_payload_numbers_receiver_side() { + real_time_text(FALSE, FALSE, FALSE, TRUE); +} + void file_transfer_with_http_proxy(void) { if (transport_supported(LinphoneTransportTls)) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); @@ -1622,7 +1650,9 @@ test_t message_tests[] = { {"Real Time Text with srtp", real_time_text_srtp}, {"Real Time Text message compatibility crlf", real_time_text_message_compat_crlf}, {"Real Time Text message compatibility lf", real_time_text_message_compat_lf}, - {"Real Time text message with accented characters", real_time_text_message_accented_chars}, + {"Real Time Text message with accented characters", real_time_text_message_accented_chars}, + {"Real Time Text offer answer with different payload numbers (sender side)", real_time_text_message_different_text_codecs_payload_numbers_sender_side}, + {"Real Time Text offer answer with different payload numbers (receiver side)", real_time_text_message_different_text_codecs_payload_numbers_receiver_side}, }; test_suite_t message_test_suite = {