From c3a77d23bbcde369c9d70171fcb169b698a97b13 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Mon, 17 Apr 2006 18:25:43 +0000 Subject: [PATCH] improvements git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1176 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_apr.h | 2 +- src/include/switch_rtp.h | 22 ++++++++++++ src/include/switch_types.h | 10 ++++-- src/include/switch_utils.h | 3 ++ .../endpoints/mod_dingaling/mod_dingaling.c | 36 +++++++++++++++++-- src/switch_ivr.c | 19 ++++++++-- src/switch_rtp.c | 31 +++++++++++++++- src/switch_utils.c | 10 ++++++ 8 files changed, 124 insertions(+), 9 deletions(-) diff --git a/src/include/switch_apr.h b/src/include/switch_apr.h index 2ad916766f..121beddb61 100644 --- a/src/include/switch_apr.h +++ b/src/include/switch_apr.h @@ -651,7 +651,7 @@ DoxyDefine(apr_status_t switch_socket_recvfrom(switch_sockaddr_t *from, apr_int32_t flags, char *buf, apr_size_t *len);) -#define switch_socket_recvfrom apr_socket_recvfrom +//#define switch_socket_recvfrom apr_socket_recvfrom /** * Send a file from an open file descriptor to a socket, along with diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 8d60fca5a3..25beeb7acd 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -156,6 +156,28 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp **rtp_session); */ SWITCH_DECLARE(switch_status) switch_rtp_activate_ice(switch_rtp *rtp_session, char *login, char *rlogin); +/*! + \brief Set an RTP Flag + \param rtp_session the RTP session + \param flags the flags to set +*/ +SWITCH_DECLARE(void) switch_rtp_set_flag(switch_rtp *rtp_session, switch_rtp_flag_t flags); + +/*! + \brief Test an RTP Flag + \param rtp_session the RTP session + \param flags the flags to test + \return TRUE or FALSE +*/ +SWITCH_DECLARE(uint8_t) switch_rtp_test_flag(switch_rtp *rtp_session, switch_rtp_flag_t flags); + +/*! + \brief Clear an RTP Flag + \param rtp_session the RTP session + \param flags the flags to clear +*/ +SWITCH_DECLARE(void) switch_rtp_clear_flag(switch_rtp *rtp_session, switch_rtp_flag_t flags); + /*! \brief Retrieve the socket from an existing RTP session \param rtp_session the RTP session to retrieve the socket from diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 6e19507f4a..4302d857c9 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -102,13 +102,15 @@ SWITCH_DECLARE_DATA extern switch_directories SWITCH_GLOBAL_dirs; SWITCH_RTP_FLAG_IO - IO is ready SWITCH_RTP_FLAG_USE_TIMER - Timeout Reads and replace with a CNG Frame SWITCH_RTP_FLAG_SECURE - Secure RTP + SWITCH_RTP_FLAG_AUTOADJ - Auto-Adjust the dest based on the source */ typedef enum { SWITCH_RTP_FLAG_NOBLOCK = ( 1 << 0), SWITCH_RTP_FLAG_IO = (1 << 1), SWITCH_RTP_FLAG_USE_TIMER = (1 << 2), - SWITCH_RTP_FLAG_SECURE = (1 << 3) + SWITCH_RTP_FLAG_SECURE = (1 << 3), + SWITCH_RTP_FLAG_AUTOADJ = (1 << 4) } switch_rtp_flag_t; /*! @@ -148,12 +150,16 @@ typedef enum { SWITCH_MESSAGE_REDIRECT_AUDIO - Indication to redirect audio to another location if possible SWITCH_MESSAGE_TRANSMIT_TEXT - A text message SWITCH_MESSAGE_INDICATE_PROGRESS - indicate progress + SWITCH_MESSAGE_INDICATE_BRIDGE - indicate a bridge starting + SWITCH_MESSAGE_INDICATE_UNBRIDGE - indicate a bridge ending */ typedef enum { SWITCH_MESSAGE_REDIRECT_AUDIO, SWITCH_MESSAGE_TRANSMIT_TEXT, - SWITCH_MESSAGE_INDICATE_PROGRESS + SWITCH_MESSAGE_INDICATE_PROGRESS, + SWITCH_MESSAGE_INDICATE_BRIDGE, + SWITCH_MESSAGE_INDICATE_UNBRIDGE } switch_core_session_message_t; diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index fc2d54872c..bbcb85486b 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -65,6 +65,9 @@ extern "C" { !strcasecmp(expr, "true") ||\ atoi(expr))) ? SWITCH_TRUE : SWITCH_FALSE + +SWITCH_DECLARE(switch_status) switch_socket_recvfrom(switch_sockaddr_t *from, switch_socket_t *sock, int32_t flags, char *buf, switch_size_t *len); + /*! \brief Return a printable name of a switch_priority_t \param priority the priority to get the name of diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 279095972a..ed013e931a 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -271,7 +271,7 @@ static int activate_rtp(struct private_object *tech_pvt) tech_pvt->codec_num, tech_pvt->read_codec.implementation->encoded_bytes_per_frame, tech_pvt->read_codec.implementation->microseconds_per_frame, - SWITCH_RTP_FLAG_USE_TIMER, + SWITCH_RTP_FLAG_USE_TIMER | SWITCH_RTP_FLAG_AUTOADJ, NULL, &err, switch_core_session_get_pool(tech_pvt->session)))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "RTP ERROR %s\n", err); @@ -887,6 +887,37 @@ static switch_status channel_answer_channel(switch_core_session *session) return SWITCH_STATUS_SUCCESS; } + +static switch_status channel_receive_message(switch_core_session *session, switch_core_session_message *msg) +{ + switch_channel *channel; + struct private_object *tech_pvt; + + channel = switch_core_session_get_channel(session); + assert(channel != NULL); + + tech_pvt = switch_core_session_get_private(session); + assert(tech_pvt != NULL); + + switch (msg->message_id) { + case SWITCH_MESSAGE_INDICATE_BRIDGE: + if (tech_pvt->rtp_session) { + switch_rtp_clear_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_USE_TIMER); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "De-activate timed RTP!\n"); + } + break; + case SWITCH_MESSAGE_INDICATE_UNBRIDGE: + if (tech_pvt->rtp_session) { + switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_USE_TIMER); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Re-activate timed RTP!\n"); + } + break; + default: + break; + } + + return SWITCH_STATUS_SUCCESS; +} static const switch_state_handler_table channel_event_handlers = { /*.on_init */ channel_on_init, /*.on_ring */ channel_on_ring, @@ -904,7 +935,8 @@ static const switch_io_routines channel_io_routines = { /*.kill_channel */ channel_kill_channel, /*.waitfor_read */ channel_waitfor_read, /*.waitfor_write */ channel_waitfor_write, - /*.send_dtmf */ channel_send_dtmf + /*.send_dtmf */ channel_send_dtmf, + /*.receive_message*/ channel_receive_message }; static const switch_endpoint_interface channel_endpoint_interface = { diff --git a/src/switch_ivr.c b/src/switch_ivr.c index a9d461e8fe..24b1248b5d 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -927,15 +927,28 @@ SWITCH_DECLARE(switch_status) switch_ivr_multi_threaded_bridge(switch_core_sessi if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) { switch_event *event; - + switch_core_session_message msg = {0}; + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_BRIDGE) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(caller_channel, event); switch_event_fire(&event); } - - switch_core_session_launch_thread(session, audio_bridge_thread, (void *) &other_audio_thread); + + msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE; + msg.from = __FILE__; + msg.pointer_arg = session; + switch_core_session_receive_message(peer_session, &msg); + msg.pointer_arg = peer_session; + switch_core_session_receive_message(session, &msg); + + switch_core_session_launch_thread(peer_session, audio_bridge_thread, (void *) &other_audio_thread); audio_bridge_thread(NULL, (void *) &this_audio_thread); + msg.pointer_arg = NULL; + msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE; + switch_core_session_receive_message(peer_session, &msg); + switch_core_session_receive_message(session, &msg); + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNBRIDGE) == SWITCH_STATUS_SUCCESS) { switch_channel_event_set_data(caller_channel, event); switch_event_fire(&event); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index cc9fdc24ee..f9ee0679cb 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -86,6 +86,7 @@ struct switch_rtp { switch_time_t last_read; switch_time_t next_read; uint32_t ms_per_packet; + uint32_t remote_port; uint8_t stuncount; switch_buffer *packet_buffer; }; @@ -168,6 +169,7 @@ static void handle_ice(switch_rtp *rtp_session, void *data, switch_size_t len) switch_sockaddr_ip_get(&remote_ip, rtp_session->from_addr); switch_stun_packet_attribute_add_binded_address(rpacket, remote_ip, rtp_session->from_addr->port); bytes = switch_stun_packet_length(rpacket); + switch_socket_sendto(rtp_session->sock, rtp_session->from_addr, 0, (void*)rpacket, &bytes); } } @@ -239,6 +241,8 @@ SWITCH_DECLARE(switch_status) switch_rtp_set_remote_address(switch_rtp *rtp_sess return SWITCH_STATUS_FALSE; } + rtp_session->remote_port = port; + return SWITCH_STATUS_SUCCESS; } @@ -462,17 +466,41 @@ SWITCH_DECLARE(void) switch_rtp_set_invald_handler(switch_rtp *rtp_session, swit rtp_session->invalid_handler = on_invalid; } +SWITCH_DECLARE(void) switch_rtp_set_flag(switch_rtp *rtp_session, switch_rtp_flag_t flags) +{ + + switch_set_flag(rtp_session, flags); + +} + +SWITCH_DECLARE(uint8_t) switch_rtp_test_flag(switch_rtp *rtp_session, switch_rtp_flag_t flags) +{ + + return (uint8_t) switch_test_flag(rtp_session, flags); + +} + +SWITCH_DECLARE(void) switch_rtp_clear_flag(switch_rtp *rtp_session, switch_rtp_flag_t flags) +{ + + switch_clear_flag(rtp_session, flags); + +} static int rtp_common_read(switch_rtp *rtp_session, void *data, int *payload_type, switch_frame_flag *flags) { switch_size_t bytes; switch_status status; - for(;;) { bytes = sizeof(rtp_msg_t); status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock, 0, (void *)&rtp_session->recv_msg, &bytes); + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_AUTOADJ) && rtp_session->from_addr->port != rtp_session->remote_port) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Auto Changing port to %u\n", rtp_session->from_addr->port); + rtp_session->remote_addr->port = rtp_session->from_addr->port; + } + if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO)) { return -1; } @@ -497,6 +525,7 @@ static int rtp_common_read(switch_rtp *rtp_session, void *data, int *payload_typ if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) { if ((switch_time_now() - rtp_session->next_read) > 1000) { /* We're late! We're Late!*/ + printf("late\n"); memset(&rtp_session->recv_msg, 0, SWITCH_RTP_CNG_PAYLOAD); rtp_session->recv_msg.header.pt = SWITCH_RTP_CNG_PAYLOAD; *flags |= SFF_CNG; diff --git a/src/switch_utils.c b/src/switch_utils.c index 26272401c1..c1d94cf510 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -34,6 +34,16 @@ #include #include +SWITCH_DECLARE(switch_status) switch_socket_recvfrom(switch_sockaddr_t *from, switch_socket_t *sock, int32_t flags, char *buf, switch_size_t *len) +{ + switch_status status; + + if ((status = apr_socket_recvfrom(from, sock, flags, buf, len)) == SWITCH_STATUS_SUCCESS) { + from->port = ntohs(from->sa.sin.sin_port); + } + return status; +} + SWITCH_DECLARE(char *) switch_priority_name(switch_priority_t priority) { switch(priority) { /*lol*/