From fc6faf46fbefbd560921982b7d2fae1a9de69608 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 15 Apr 2010 22:33:14 -0500 Subject: [PATCH 01/62] Add missing directory specifiers --- libs/unimrcp/libs/apr-toolkit/aprtoolkit.2008.vcproj | 2 ++ libs/unimrcp/libs/mpf/mpf.2008.vcproj | 2 ++ libs/unimrcp/libs/mrcp-client/mrcpclient.2008.vcproj | 2 ++ libs/unimrcp/libs/mrcp-signaling/mrcpsignaling.2008.vcproj | 2 ++ libs/unimrcp/libs/mrcp/mrcp.2008.vcproj | 2 ++ libs/unimrcp/libs/mrcpv2-transport/mrcpv2transport.2008.vcproj | 2 ++ libs/unimrcp/libs/uni-rtsp/unirtsp.2008.vcproj | 2 ++ libs/unimrcp/modules/mrcp-sofiasip/mrcpsofiasip.2008.vcproj | 2 ++ libs/unimrcp/modules/mrcp-unirtsp/mrcpunirtsp.2008.vcproj | 2 ++ 9 files changed, 18 insertions(+) diff --git a/libs/unimrcp/libs/apr-toolkit/aprtoolkit.2008.vcproj b/libs/unimrcp/libs/apr-toolkit/aprtoolkit.2008.vcproj index 29dcd35d94..d77441afa5 100644 --- a/libs/unimrcp/libs/apr-toolkit/aprtoolkit.2008.vcproj +++ b/libs/unimrcp/libs/apr-toolkit/aprtoolkit.2008.vcproj @@ -133,6 +133,8 @@ Date: Thu, 15 Apr 2010 23:00:29 -0500 Subject: [PATCH 02/62] Add version check to support git and svn --- libs/win32/util.vbs | 55 +++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/libs/win32/util.vbs b/libs/win32/util.vbs index 934a3ec1a5..395632bf47 100644 --- a/libs/win32/util.vbs +++ b/libs/win32/util.vbs @@ -308,23 +308,44 @@ Sub CreateVersion(tmpFolder, VersionDir, includebase, includedest) Const ForReading = 1 if strVerRev = "" Then - VersionCmd="fs_svnversion " & quote & VersionDir & "." & quote & " -n" - Set MyFile = fso.CreateTextFile(tmpFolder & "tmpVersion.Bat", True) - MyFile.WriteLine("@" & "cd " & quote & tmpFolder & quote ) - MyFile.WriteLine("@" & VersionCmd) - MyFile.Close - Set oExec = WshShell.Exec("cmd /C " & quote & tmpFolder & "tmpVersion.Bat" & quote) - Do - strFromProc = OExec.StdOut.ReadLine() - VERSION=strFromProc - Loop While Not OExec.StdOut.atEndOfStream - sLastVersion = "" - Set sLastFile = FSO.OpenTextFile(tmpFolder & "lastversion", ForReading, true, OpenAsASCII) - If Not sLastFile.atEndOfStream Then - sLastVersion = sLastFile.ReadLine() - End If - sLastFile.Close - End If + if FSO.FolderExists(VersionDir & ".svn") Then + VersionCmd="fs_svnversion " & quote & VersionDir & "." & quote & " -n" + Set MyFile = fso.CreateTextFile(tmpFolder & "tmpVersion.Bat", True) + MyFile.WriteLine("@" & "cd " & quote & tmpFolder & quote ) + MyFile.WriteLine("@" & VersionCmd) + MyFile.Close + Set oExec = WshShell.Exec("cmd /C " & quote & tmpFolder & "tmpVersion.Bat" & quote) + Do + strFromProc = OExec.StdOut.ReadLine() + VERSION="svn-" & strFromProc + Loop While Not OExec.StdOut.atEndOfStream + sLastVersion = "" + Set sLastFile = FSO.OpenTextFile(tmpFolder & "lastversion", ForReading, true, OpenAsASCII) + If Not sLastFile.atEndOfStream Then + sLastVersion = sLastFile.ReadLine() + End If + sLastFile.Close + End If + + if FSO.FolderExists(VersionDir & ".git") Then + VersionCmd="git log --format=" & quote & "%%h %%ci" & quote & " -1 HEAD" + Set MyFile = FSO.CreateTextFile(tmpFolder & "tmpVersion.Bat", True) + MyFile.WriteLine("@" & "cd " & quote & VersionDir & quote) + MyFile.WriteLine("@" & VersionCmd) + MyFile.Close + Set oExec = WshShell.Exec("cmd /C " & quote & tmpFolder & "tmpVersion.Bat" & quote) + Do + strFromProc = Trim(OExec.StdOut.ReadLine()) + VERSION="git-" & strFromProc + Loop While Not OExec.StdOut.atEndOfStream + sLastVersion = "" + Set sLastFile = FSO.OpenTextFile(tmpFolder & "lastversion", ForReading, true, OpenAsASCII) + If Not sLastFile.atEndOfStream Then + sLastVersion = sLastFile.ReadLine() + End If + sLastFile.Close + End If + End If if strVerRev <> "" Then VERSION = strVerRev From 2cb527269234201ec9759fafcc37721c422714e8 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 15 Apr 2010 23:29:38 -0500 Subject: [PATCH 03/62] FSBUILD-262 --- src/mod/endpoints/mod_skypopen/mod_skypopen.2008.vcproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.2008.vcproj b/src/mod/endpoints/mod_skypopen/mod_skypopen.2008.vcproj index 585123b4a2..f2516ff7bf 100644 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.2008.vcproj +++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.2008.vcproj @@ -118,7 +118,7 @@ /> From 00b262235007cb6407c986b355d3a49881401419 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Fri, 16 Apr 2010 11:58:15 +0200 Subject: [PATCH 04/62] Skinny: initial transfer support and some re-indentation --- src/mod/endpoints/mod_skinny/mod_skinny.c | 2 +- src/mod/endpoints/mod_skinny/mod_skinny.h | 60 ++++++++-------- .../endpoints/mod_skinny/skinny_protocol.c | 72 ++++++++++++++++--- .../endpoints/mod_skinny/skinny_protocol.h | 24 +++---- 4 files changed, 106 insertions(+), 52 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index 2a6e65d695..63cc514429 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -542,9 +542,9 @@ void tech_init(private_t *tech_pvt, skinny_profile_t *profile, switch_core_sessi tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf); switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); + tech_pvt->profile = profile; tech_pvt->call_id = ++profile->next_call_id; tech_pvt->party_id = tech_pvt->call_id; - tech_pvt->profile = profile; switch_core_session_set_private(session, tech_pvt); tech_pvt->session = session; } diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h index 3443d2f7dd..341499967d 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.h +++ b/src/mod/endpoints/mod_skinny/mod_skinny.h @@ -147,36 +147,40 @@ typedef enum { } GFLAGS; struct private_object { - unsigned int flags; - switch_frame_t read_frame; - unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - switch_core_session_t *session; - switch_caller_profile_t *caller_profile; - switch_mutex_t *mutex; - switch_mutex_t *flag_mutex; - /* identification */ - uint32_t call_id; - uint32_t party_id; + unsigned int flags; + switch_frame_t read_frame; + unsigned char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; + switch_core_session_t *session; + switch_caller_profile_t *caller_profile; + switch_mutex_t *mutex; + switch_mutex_t *flag_mutex; - skinny_profile_t *profile; + /* identification */ + skinny_profile_t *profile; + uint32_t call_id; + uint32_t party_id; - /* codec */ - char *iananame; - switch_codec_t read_codec; - switch_codec_t write_codec; - switch_codec_implementation_t read_impl; - switch_codec_implementation_t write_impl; - unsigned long rm_rate; - uint32_t codec_ms; - char *rm_encoding; - char *rm_fmtp; - switch_payload_t agreed_pt; - /* RTP */ - switch_rtp_t *rtp_session; - char *local_sdp_audio_ip; - switch_port_t local_sdp_audio_port; - char *remote_sdp_audio_ip; - switch_port_t remote_sdp_audio_port; + /* related calls */ + uint32_t transfer_to_call_id; + uint32_t transfer_from_call_id; + + /* codec */ + char *iananame; + switch_codec_t read_codec; + switch_codec_t write_codec; + switch_codec_implementation_t read_impl; + switch_codec_implementation_t write_impl; + unsigned long rm_rate; + uint32_t codec_ms; + char *rm_encoding; + char *rm_fmtp; + switch_payload_t agreed_pt; + /* RTP */ + switch_rtp_t *rtp_session; + char *local_sdp_audio_ip; + switch_port_t local_sdp_audio_port; + char *remote_sdp_audio_ip; + switch_port_t remote_sdp_audio_port; }; typedef struct private_object private_t; diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.c b/src/mod/endpoints/mod_skinny/skinny_protocol.c index 7fd7998545..c6daed417f 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.c +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.c @@ -837,6 +837,47 @@ switch_status_t skinny_session_unhold_line(switch_core_session_t *session, liste return SWITCH_STATUS_SUCCESS; } +switch_status_t skinny_session_transfer(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + private_t *tech_pvt = NULL; + switch_channel_t *channel = NULL; + const char *uuid = NULL; + switch_core_session_t *session2 = NULL; + private_t *tech_pvt2 = NULL; + + switch_assert(session); + switch_assert(listener); + switch_assert(listener->profile); + + tech_pvt = switch_core_session_get_private(session); + channel = switch_core_session_get_channel(session); + uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE); + + if (tech_pvt->transfer_from_call_id) { + if((session2 = skinny_profile_find_session(listener->profile, listener, &line_instance, 0))) { + switch_channel_t *channel2 = switch_core_session_get_channel(session2); + const char *uuid2 = switch_channel_get_variable(channel2, SWITCH_BRIDGE_VARIABLE); + switch_ivr_uuid_bridge(uuid, uuid2); + switch_core_session_rwunlock(session2); + /* TODO: How to inform the user that the bridge is not possible? */ + } + } else { + if(uuid) { + /* TODO CallSelectStat */ + status = skinny_create_ingoing_session(listener, &line_instance, &session2); + tech_pvt2 = switch_core_session_get_private(session2); + tech_pvt2->transfer_from_call_id = tech_pvt->call_id; + tech_pvt->transfer_to_call_id = tech_pvt2->call_id; + skinny_session_process_dest(session2, listener, line_instance, NULL, '\0', 0); + switch_core_session_rwunlock(session2); + } else { + /* TODO: How to inform the user that the bridge is not possible? */ + } + } + return status; +} + switch_status_t skinny_session_stop_media(switch_core_session_t *session, listener_t *listener, uint32_t line_instance) { switch_channel_t *channel = NULL; @@ -1990,6 +2031,7 @@ switch_status_t skinny_handle_soft_key_set_request(listener_t *listener, skinny_ message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[0] = SOFTKEY_ENDCALL; message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[1] = SOFTKEY_HOLD; message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[2] = SOFTKEY_NEWCALL; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[3] = SOFTKEY_TRANSFER; message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[0] = SOFTKEY_ANSWER; message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[1] = SOFTKEY_ENDCALL; @@ -1998,6 +2040,9 @@ switch_status_t skinny_handle_soft_key_set_request(listener_t *listener, skinny_ message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[0] = SOFTKEY_NEWCALL; message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[1] = SOFTKEY_RESUME; message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[2] = SOFTKEY_ENDCALL; + + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES].soft_key_template_index[1] = SOFTKEY_REDIAL; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES].soft_key_template_index[2] = SOFTKEY_ENDCALL; skinny_send_reply(listener, message); @@ -2146,6 +2191,13 @@ switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinn status = skinny_session_hold_line(session, listener, line_instance); } break; + case SOFTKEY_TRANSFER: + session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); + + if(session) { + status = skinny_session_transfer(session, listener, line_instance); + } + break; case SOFTKEY_BACKSPACE: session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); @@ -2341,19 +2393,17 @@ switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *liste 0, /* uint32_t silence_suppression, */ 0, /* uint16_t max_frames_per_packet, */ 0 /* uint32_t g723_bitrate */ - ); - if (switch_channel_get_state(channel) == CS_NEW) { - switch_channel_set_state(channel, CS_INIT); - } - switch_channel_mark_answered(channel); + ); + if (switch_channel_get_state(channel) == CS_NEW) { + switch_channel_set_state(channel, CS_INIT); + } + switch_channel_mark_answered(channel); } end: - if(session) { switch_core_session_rwunlock(session); } - return status; } @@ -2509,14 +2559,14 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re return skinny_handle_unregister(listener, request); case SOFT_KEY_TEMPLATE_REQ_MESSAGE: return skinny_handle_soft_key_template_request(listener, request); - case SERVICE_URL_STAT_REQ_MESSAGE: - return skinny_handle_service_url_stat_request(listener, request); - case FEATURE_STAT_REQ_MESSAGE: - return skinny_handle_feature_stat_request(listener, request); case HEADSET_STATUS_MESSAGE: return skinny_headset_status_message(listener, request); case REGISTER_AVAILABLE_LINES_MESSAGE: return skinny_handle_register_available_lines_message(listener, request); + case SERVICE_URL_STAT_REQ_MESSAGE: + return skinny_handle_service_url_stat_request(listener, request); + case FEATURE_STAT_REQ_MESSAGE: + return skinny_handle_feature_stat_request(listener, request); default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unhandled request %s (type=%x,length=%d).\n", skinny_message_type2str(request->type), request->type, request->length); diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index c038be5cc9..994462684f 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -162,18 +162,6 @@ struct soft_key_event_message { /* SoftKeyTemplateReqMessage */ #define SOFT_KEY_TEMPLATE_REQ_MESSAGE 0x0028 -/* ServiceUrlStatReqMessage */ -#define SERVICE_URL_STAT_REQ_MESSAGE 0x0033 -struct service_url_stat_req_message { - uint32_t service_url_index; -}; - -/* FeatureStatReqMessage */ -#define FEATURE_STAT_REQ_MESSAGE 0x0034 -struct feature_stat_req_message { - uint32_t feature_index; -}; - /* HeadsetStatusMessage */ #define HEADSET_STATUS_MESSAGE 0x002B struct headset_status_message { @@ -186,6 +174,18 @@ struct register_available_lines_message { uint32_t count; }; +/* ServiceUrlStatReqMessage */ +#define SERVICE_URL_STAT_REQ_MESSAGE 0x0033 +struct service_url_stat_req_message { + uint32_t service_url_index; +}; + +/* FeatureStatReqMessage */ +#define FEATURE_STAT_REQ_MESSAGE 0x0034 +struct feature_stat_req_message { + uint32_t feature_index; +}; + /* RegisterAckMessage */ #define REGISTER_ACK_MESSAGE 0x0081 struct register_ack_message { From 4263dda2de1fe45a5795c19b7fd71e1ac6423b6c Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Fri, 16 Apr 2010 15:03:37 +0200 Subject: [PATCH 05/62] Skinny: Initial implementation of VersionReq And reordering --- .../endpoints/mod_skinny/skinny_protocol.c | 988 +++++++++--------- .../endpoints/mod_skinny/skinny_protocol.h | 14 + src/mod/endpoints/mod_skinny/skinny_tables.c | 2 + src/mod/endpoints/mod_skinny/skinny_tables.h | 2 +- 4 files changed, 522 insertions(+), 484 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.c b/src/mod/endpoints/mod_skinny/skinny_protocol.c index c6daed417f..975007279c 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.c +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.c @@ -1389,6 +1389,15 @@ switch_status_t send_capabilities_req(listener_t *listener) return skinny_send_reply(listener, message); } +switch_status_t send_version(listener_t *listener, + char *version) +{ + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.version)); + strncpy(message->data.version.version, version, 16); + return skinny_send_reply(listener, message); +} + switch_status_t send_register_reject(listener_t *listener, char *error) { @@ -1579,25 +1588,18 @@ switch_status_t send_reset(listener_t *listener, uint32_t reset_type) return skinny_send_reply(listener, message); } -/* Message handling */ -switch_status_t skinny_handle_alarm(listener_t *listener, skinny_message_t *request) +/*****************************************************************************/ +/* SKINNY MESSAGE HANDLERS */ +/*****************************************************************************/ +switch_status_t skinny_handle_keep_alive_message(listener_t *listener, skinny_message_t *request) { - switch_event_t *event = NULL; - - skinny_check_data_length(request, sizeof(request->data.alarm)); - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, - "Received alarm: Severity=%d, DisplayMessage=%s, Param1=%d, Param2=%d.\n", - request->data.alarm.alarm_severity, request->data.alarm.display_message, - request->data.alarm.alarm_param1, request->data.alarm.alarm_param2); - /* skinny::alarm event */ - skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_ALARM); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Severity", "%d", request->data.alarm.alarm_severity); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-DisplayMessage", "%s", request->data.alarm.display_message); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param1", "%d", request->data.alarm.alarm_param1); - switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param2", "%d", request->data.alarm.alarm_param2); - switch_event_fire(&event); + skinny_message_t *message; + message = switch_core_alloc(listener->pool, 12); + message->type = KEEP_ALIVE_ACK_MESSAGE; + message->length = 4; + keepalive_listener(listener, NULL); + skinny_send_reply(listener, message); return SWITCH_STATUS_SUCCESS; } @@ -1733,11 +1735,231 @@ end: return status; } -switch_status_t skinny_headset_status_message(listener_t *listener, skinny_message_t *request) +switch_status_t skinny_handle_port_message(listener_t *listener, skinny_message_t *request) { - skinny_check_data_length(request, sizeof(request->data.headset_status)); + char *sql; + skinny_profile_t *profile; + + switch_assert(listener->profile); + switch_assert(listener->device_name); + + profile = listener->profile; + + skinny_check_data_length(request, sizeof(request->data.as_uint16)); + + if ((sql = switch_mprintf( + "UPDATE skinny_devices SET port=%d WHERE name='%s' and instance=%d", + request->data.port.port, + listener->device_name, + listener->device_instance + ))) { + skinny_execute_sql(profile, sql, profile->sql_mutex); + switch_safe_free(sql); + } + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny_message_t *request) +{ + uint32_t line_instance = 0; + switch_core_session_t *session; + + skinny_check_data_length(request, sizeof(request->data.keypad_button)); + + if(request->data.keypad_button.line_instance) { + line_instance = request->data.keypad_button.line_instance; + } else { + line_instance = 1; + } + + session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.keypad_button.call_id); + + if(session) { + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; + char digit = '\0'; + + channel = switch_core_session_get_channel(session); + tech_pvt = switch_core_session_get_private(session); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "SEND DTMF ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button); + + if (request->data.keypad_button.button == 14) { + digit = '*'; + } else if (request->data.keypad_button.button == 15) { + digit = '#'; + } else if (request->data.keypad_button.button >= 0 && request->data.keypad_button.button <= 9) { + digit = '0' + request->data.keypad_button.button; + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "UNKNOW DTMF RECEIVED ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button); + } + + /* TODO check call_id and line */ + + if((skinny_line_get_state(listener, line_instance, tech_pvt->call_id) == SKINNY_OFF_HOOK)) { + + skinny_session_process_dest(session, listener, line_instance, NULL, digit, 0); + } else { + if(digit != '\0') { + switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0)}; + dtmf.digit = digit; + switch_channel_queue_dtmf(channel, &dtmf); + } + } + } + + if(session) { + switch_core_session_rwunlock(session); + } + + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_message_t *request) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + struct speed_dial_stat_res_message *button = NULL; + uint32_t line_instance = 0; + uint32_t call_id = 0; + switch_core_session_t *session = NULL; + + skinny_check_data_length(request, sizeof(request->data.stimulus)-sizeof(request->data.stimulus.call_id)); + + if(skinny_check_data_length_soft(request, sizeof(request->data.stimulus))) { + call_id = request->data.stimulus.call_id; + } + + switch(request->data.stimulus.instance_type) { + case SKINNY_BUTTON_LAST_NUMBER_REDIAL: + skinny_create_ingoing_session(listener, &line_instance, &session); + skinny_session_process_dest(session, listener, line_instance, "redial", '\0', 0); + break; + case SKINNY_BUTTON_SPEED_DIAL: + skinny_speed_dial_get(listener, request->data.stimulus.instance, &button); + if(strlen(button->line) > 0) { + skinny_create_ingoing_session(listener, &line_instance, &session); + skinny_session_process_dest(session, listener, line_instance, button->line, '\0', 0); + } + break; + case SKINNY_BUTTON_HOLD: + session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); + + if(session) { + status = skinny_session_hold_line(session, listener, line_instance); + } + break; + case SKINNY_BUTTON_VOICEMAIL: + skinny_create_ingoing_session(listener, &line_instance, &session); + skinny_session_process_dest(session, listener, line_instance, "vmain", '\0', 0); + break; + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown Stimulus Type Received [%d]\n", request->data.stimulus.instance_type); + } + + if(session) { + switch_core_session_rwunlock(session); + } + + return status; +} + +switch_status_t skinny_handle_off_hook_message(listener_t *listener, skinny_message_t *request) +{ + uint32_t line_instance; + switch_core_session_t *session = NULL; + private_t *tech_pvt = NULL; + + skinny_check_data_length(request, sizeof(request->data.off_hook)); + + if(request->data.off_hook.line_instance > 0) { + line_instance = request->data.off_hook.line_instance; + } else { + line_instance = 1; + } + + session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.off_hook.call_id); + + if(session) { /*answering a call */ + skinny_session_answer(session, listener, line_instance); + } else { /* start a new call */ + skinny_create_ingoing_session(listener, &line_instance, &session); + tech_pvt = switch_core_session_get_private(session); + assert(tech_pvt != NULL); + + skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0); + } + + if(session) { + switch_core_session_rwunlock(session); + } + + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t skinny_handle_on_hook_message(listener_t *listener, skinny_message_t *request) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_core_session_t *session = NULL; + uint32_t line_instance = 0; + + skinny_check_data_length(request, sizeof(request->data.on_hook)); + + line_instance = request->data.on_hook.line_instance; + + session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.on_hook.call_id); + + if(session) { + switch_channel_t *channel = NULL; + + channel = switch_core_session_get_channel(session); + + switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); + } + + if(session) { + switch_core_session_rwunlock(session); + } + + return status; +} + +switch_status_t skinny_handle_speed_dial_stat_request(listener_t *listener, skinny_message_t *request) +{ + skinny_message_t *message; + struct speed_dial_stat_res_message *button = NULL; + + skinny_check_data_length(request, sizeof(request->data.speed_dial_req)); + + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.speed_dial_res)); + message->type = SPEED_DIAL_STAT_RES_MESSAGE; + message->length = 4 + sizeof(message->data.speed_dial_res); + + skinny_speed_dial_get(listener, request->data.speed_dial_req.number, &button); + + memcpy(&message->data.speed_dial_res, button, sizeof(struct speed_dial_stat_res_message)); + + skinny_send_reply(listener, message); + + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t skinny_handle_line_stat_request(listener_t *listener, skinny_message_t *request) +{ + skinny_message_t *message; + struct line_stat_res_message *button = NULL; + + skinny_check_data_length(request, sizeof(request->data.line_req)); + + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.line_res)); + message->type = LINE_STAT_RES_MESSAGE; + message->length = 4 + sizeof(message->data.line_res); + + skinny_line_get(listener, request->data.line_req.number, &button); + + memcpy(&message->data.line_res, button, sizeof(struct line_stat_res_message)); + + skinny_send_reply(listener, message); - /* Nothing to do */ return SWITCH_STATUS_SUCCESS; } @@ -1798,88 +2020,9 @@ switch_status_t skinny_handle_config_stat_request(listener_t *listener, skinny_m return SWITCH_STATUS_SUCCESS; } -switch_status_t skinny_handle_capabilities_response(listener_t *listener, skinny_message_t *request) +switch_status_t skinny_handle_time_date_request(listener_t *listener, skinny_message_t *request) { - char *sql; - skinny_profile_t *profile; - - uint32_t i = 0; - uint32_t n = 0; - char *codec_order[SWITCH_MAX_CODECS]; - char *codec_string; - - size_t string_len, string_pos, pos; - - switch_assert(listener->profile); - switch_assert(listener->device_name); - - profile = listener->profile; - - skinny_check_data_length(request, sizeof(request->data.cap_res.count)); - - n = request->data.cap_res.count; - if (n > SWITCH_MAX_CODECS) { - n = SWITCH_MAX_CODECS; - } - string_len = -1; - - skinny_check_data_length(request, sizeof(request->data.cap_res.count) + n * sizeof(request->data.cap_res.caps[0])); - - for (i = 0; i < n; i++) { - char *codec = skinny_codec2string(request->data.cap_res.caps[i].codec); - codec_order[i] = codec; - string_len += strlen(codec)+1; - } - i = 0; - pos = 0; - codec_string = switch_core_alloc(listener->pool, string_len+1); - for (string_pos = 0; string_pos < string_len; string_pos++) { - char *codec = codec_order[i]; - switch_assert(i < n); - if(pos == strlen(codec)) { - codec_string[string_pos] = ','; - i++; - pos = 0; - } else { - codec_string[string_pos] = codec[pos++]; - } - } - codec_string[string_len] = '\0'; - if ((sql = switch_mprintf( - "UPDATE skinny_devices SET codec_string='%s' WHERE name='%s'", - codec_string, - listener->device_name - ))) { - skinny_execute_sql(profile, sql, profile->sql_mutex); - switch_safe_free(sql); - } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, - "Codecs %s supported.\n", codec_string); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t skinny_handle_port_message(listener_t *listener, skinny_message_t *request) -{ - char *sql; - skinny_profile_t *profile; - - switch_assert(listener->profile); - switch_assert(listener->device_name); - - profile = listener->profile; - - skinny_check_data_length(request, sizeof(request->data.as_uint16)); - - if ((sql = switch_mprintf( - "UPDATE skinny_devices SET port=%d WHERE name='%s' and instance=%d", - request->data.port.port, - listener->device_name, - listener->device_instance - ))) { - skinny_execute_sql(profile, sql, profile->sql_mutex); - switch_safe_free(sql); - } - return SWITCH_STATUS_SUCCESS; + return send_define_current_time_date(listener); } struct button_template_helper { @@ -1968,357 +2111,99 @@ switch_status_t skinny_handle_button_template_request(listener_t *listener, skin } } - skinny_send_reply(listener, message); + - return SWITCH_STATUS_SUCCESS; + return skinny_send_reply(listener, message);; } -switch_status_t skinny_handle_soft_key_template_request(listener_t *listener, skinny_message_t *request) +switch_status_t skinny_handle_version_request(listener_t *listener, skinny_message_t *request) { - skinny_message_t *message; + /* TODO */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "VersionReqMessage not implemented yet.\n"); + return SWITCH_STATUS_SUCCESS; + /* return send_version(listener, ""); */ +} + +switch_status_t skinny_handle_capabilities_response(listener_t *listener, skinny_message_t *request) +{ + char *sql; skinny_profile_t *profile; + uint32_t i = 0; + uint32_t n = 0; + char *codec_order[SWITCH_MAX_CODECS]; + char *codec_string; + + size_t string_len, string_pos, pos; + switch_assert(listener->profile); switch_assert(listener->device_name); profile = listener->profile; - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.soft_key_template)); - message->type = SOFT_KEY_TEMPLATE_RES_MESSAGE; - message->length = 4 + sizeof(message->data.soft_key_template); + skinny_check_data_length(request, sizeof(request->data.cap_res.count)); - message->data.soft_key_template.soft_key_offset = 0; - message->data.soft_key_template.soft_key_count = 21; - message->data.soft_key_template.total_soft_key_count = 21; - - memcpy(message->data.soft_key_template.soft_key, - soft_key_template_default, - sizeof(soft_key_template_default)); - - skinny_send_reply(listener, message); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t skinny_handle_soft_key_set_request(listener_t *listener, skinny_message_t *request) -{ - skinny_message_t *message; - skinny_profile_t *profile; - - switch_assert(listener->profile); - switch_assert(listener->device_name); - - profile = listener->profile; - - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.soft_key_set)); - message->type = SOFT_KEY_SET_RES_MESSAGE; - message->length = 4 + sizeof(message->data.soft_key_set); - - message->data.soft_key_set.soft_key_set_offset = 0; - message->data.soft_key_set.soft_key_set_count = 11; - message->data.soft_key_set.total_soft_key_set_count = 11; - - /* TODO fill the set */ - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOOK].soft_key_template_index[0] = SOFTKEY_NEWCALL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOOK].soft_key_template_index[1] = SOFTKEY_REDIAL; - - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK].soft_key_template_index[1] = SOFTKEY_REDIAL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK].soft_key_template_index[2] = SOFTKEY_ENDCALL; - - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT].soft_key_template_index[0] = SOFTKEY_BACKSPACE; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT].soft_key_template_index[2] = SOFTKEY_ENDCALL; - - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[0] = SOFTKEY_ENDCALL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[1] = SOFTKEY_HOLD; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[2] = SOFTKEY_NEWCALL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[3] = SOFTKEY_TRANSFER; - - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[0] = SOFTKEY_ANSWER; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[1] = SOFTKEY_ENDCALL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[2] = SOFTKEY_NEWCALL; - - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[0] = SOFTKEY_NEWCALL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[1] = SOFTKEY_RESUME; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[2] = SOFTKEY_ENDCALL; - - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES].soft_key_template_index[1] = SOFTKEY_REDIAL; - message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES].soft_key_template_index[2] = SOFTKEY_ENDCALL; - - skinny_send_reply(listener, message); - - /* Init the states */ - send_select_soft_keys(listener, 0, 0, SKINNY_KEY_SET_ON_HOOK, 0xffff); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t skinny_handle_line_stat_request(listener_t *listener, skinny_message_t *request) -{ - skinny_message_t *message; - struct line_stat_res_message *button = NULL; - - skinny_check_data_length(request, sizeof(request->data.line_req)); - - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.line_res)); - message->type = LINE_STAT_RES_MESSAGE; - message->length = 4 + sizeof(message->data.line_res); - - skinny_line_get(listener, request->data.line_req.number, &button); - - memcpy(&message->data.line_res, button, sizeof(struct line_stat_res_message)); - - skinny_send_reply(listener, message); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t skinny_handle_speed_dial_stat_request(listener_t *listener, skinny_message_t *request) -{ - skinny_message_t *message; - struct speed_dial_stat_res_message *button = NULL; - - skinny_check_data_length(request, sizeof(request->data.speed_dial_req)); - - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.speed_dial_res)); - message->type = SPEED_DIAL_STAT_RES_MESSAGE; - message->length = 4 + sizeof(message->data.speed_dial_res); - - skinny_speed_dial_get(listener, request->data.speed_dial_req.number, &button); - - memcpy(&message->data.speed_dial_res, button, sizeof(struct speed_dial_stat_res_message)); - - skinny_send_reply(listener, message); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t skinny_handle_service_url_stat_request(listener_t *listener, skinny_message_t *request) -{ - skinny_message_t *message; - struct service_url_stat_res_message *button = NULL; - - skinny_check_data_length(request, sizeof(request->data.service_url_req)); - - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.service_url_res)); - message->type = SERVICE_URL_STAT_RES_MESSAGE; - message->length = 4 + sizeof(message->data.service_url_res); - - skinny_service_url_get(listener, request->data.service_url_req.service_url_index, &button); - - memcpy(&message->data.service_url_res, button, sizeof(struct service_url_stat_res_message)); - - skinny_send_reply(listener, message); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t skinny_handle_feature_stat_request(listener_t *listener, skinny_message_t *request) -{ - skinny_message_t *message; - struct feature_stat_res_message *button = NULL; - - skinny_check_data_length(request, sizeof(request->data.feature_req)); - - message = switch_core_alloc(listener->pool, 12+sizeof(message->data.feature_res)); - message->type = FEATURE_STAT_RES_MESSAGE; - message->length = 4 + sizeof(message->data.feature_res); - - skinny_feature_get(listener, request->data.feature_req.feature_index, &button); - - memcpy(&message->data.feature_res, button, sizeof(struct feature_stat_res_message)); - - skinny_send_reply(listener, message); - - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t skinny_handle_register_available_lines_message(listener_t *listener, skinny_message_t *request) -{ - skinny_check_data_length(request, sizeof(request->data.reg_lines)); - - /* Do nothing */ - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t skinny_handle_time_date_request(listener_t *listener, skinny_message_t *request) -{ - return send_define_current_time_date(listener); -} - -switch_status_t skinny_handle_keep_alive_message(listener_t *listener, skinny_message_t *request) -{ - skinny_message_t *message; - - message = switch_core_alloc(listener->pool, 12); - message->type = KEEP_ALIVE_ACK_MESSAGE; - message->length = 4; - keepalive_listener(listener, NULL); - skinny_send_reply(listener, message); - return SWITCH_STATUS_SUCCESS; -} - -switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinny_message_t *request) -{ - switch_status_t status = SWITCH_STATUS_SUCCESS; - uint32_t line_instance = 0; - switch_core_session_t *session = NULL; - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - - switch_assert(listener); - switch_assert(listener->profile); - - skinny_check_data_length(request, sizeof(request->data.soft_key_event)); - - line_instance = request->data.soft_key_event.line_instance; - - switch(request->data.soft_key_event.event) { - case SOFTKEY_REDIAL: - status = skinny_create_ingoing_session(listener, &line_instance, &session); - - skinny_session_process_dest(session, listener, line_instance, "redial", '\0', 0); - break; - case SOFTKEY_NEWCALL: - status = skinny_create_ingoing_session(listener, &line_instance, &session); - tech_pvt = switch_core_session_get_private(session); - - skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0); - break; - case SOFTKEY_HOLD: - session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); - - if(session) { - status = skinny_session_hold_line(session, listener, line_instance); - } - break; - case SOFTKEY_TRANSFER: - session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); - - if(session) { - status = skinny_session_transfer(session, listener, line_instance); - } - break; - case SOFTKEY_BACKSPACE: - session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); - - if(session) { - skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 1); - } - break; - case SOFTKEY_ENDCALL: - session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); - - if(session) { - channel = switch_core_session_get_channel(session); - - switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); - } - break; - case SOFTKEY_RESUME: - session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); - - if(session) { - status = skinny_session_unhold_line(session, listener, line_instance); - } - break; - case SOFTKEY_ANSWER: - session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); - - if(session) { - status = skinny_session_answer(session, listener, line_instance); - } - break; - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, - "Unknown SoftKeyEvent type: %d.\n", request->data.soft_key_event.event); + n = request->data.cap_res.count; + if (n > SWITCH_MAX_CODECS) { + n = SWITCH_MAX_CODECS; } + string_len = -1; - if(session) { - switch_core_session_rwunlock(session); + skinny_check_data_length(request, sizeof(request->data.cap_res.count) + n * sizeof(request->data.cap_res.caps[0])); + + for (i = 0; i < n; i++) { + char *codec = skinny_codec2string(request->data.cap_res.caps[i].codec); + codec_order[i] = codec; + string_len += strlen(codec)+1; } - - return status; -} - -switch_status_t skinny_handle_off_hook_message(listener_t *listener, skinny_message_t *request) -{ - uint32_t line_instance; - switch_core_session_t *session = NULL; - private_t *tech_pvt = NULL; - - skinny_check_data_length(request, sizeof(request->data.off_hook)); - - if(request->data.off_hook.line_instance > 0) { - line_instance = request->data.off_hook.line_instance; - } else { - line_instance = 1; + i = 0; + pos = 0; + codec_string = switch_core_alloc(listener->pool, string_len+1); + for (string_pos = 0; string_pos < string_len; string_pos++) { + char *codec = codec_order[i]; + switch_assert(i < n); + if(pos == strlen(codec)) { + codec_string[string_pos] = ','; + i++; + pos = 0; + } else { + codec_string[string_pos] = codec[pos++]; + } } - - session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.off_hook.call_id); - - if(session) { /*answering a call */ - skinny_session_answer(session, listener, line_instance); - } else { /* start a new call */ - skinny_create_ingoing_session(listener, &line_instance, &session); - tech_pvt = switch_core_session_get_private(session); - assert(tech_pvt != NULL); - - skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0); + codec_string[string_len] = '\0'; + if ((sql = switch_mprintf( + "UPDATE skinny_devices SET codec_string='%s' WHERE name='%s'", + codec_string, + listener->device_name + ))) { + skinny_execute_sql(profile, sql, profile->sql_mutex); + switch_safe_free(sql); } - - if(session) { - switch_core_session_rwunlock(session); - } - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, + "Codecs %s supported.\n", codec_string); return SWITCH_STATUS_SUCCESS; } -switch_status_t skinny_handle_stimulus_message(listener_t *listener, skinny_message_t *request) +switch_status_t skinny_handle_alarm(listener_t *listener, skinny_message_t *request) { - switch_status_t status = SWITCH_STATUS_SUCCESS; - struct speed_dial_stat_res_message *button = NULL; - uint32_t line_instance = 0; - uint32_t call_id = 0; - switch_core_session_t *session = NULL; + switch_event_t *event = NULL; - skinny_check_data_length(request, sizeof(request->data.stimulus)-sizeof(request->data.stimulus.call_id)); + skinny_check_data_length(request, sizeof(request->data.alarm)); - if(skinny_check_data_length_soft(request, sizeof(request->data.stimulus))) { - call_id = request->data.stimulus.call_id; - } + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, + "Received alarm: Severity=%d, DisplayMessage=%s, Param1=%d, Param2=%d.\n", + request->data.alarm.alarm_severity, request->data.alarm.display_message, + request->data.alarm.alarm_param1, request->data.alarm.alarm_param2); + /* skinny::alarm event */ + skinny_device_event(listener, &event, SWITCH_EVENT_CUSTOM, SKINNY_EVENT_ALARM); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Severity", "%d", request->data.alarm.alarm_severity); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-DisplayMessage", "%s", request->data.alarm.display_message); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param1", "%d", request->data.alarm.alarm_param1); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Skinny-Alarm-Param2", "%d", request->data.alarm.alarm_param2); + switch_event_fire(&event); - switch(request->data.stimulus.instance_type) { - case SKINNY_BUTTON_LAST_NUMBER_REDIAL: - skinny_create_ingoing_session(listener, &line_instance, &session); - skinny_session_process_dest(session, listener, line_instance, "redial", '\0', 0); - break; - case SKINNY_BUTTON_SPEED_DIAL: - skinny_speed_dial_get(listener, request->data.stimulus.instance, &button); - if(strlen(button->line) > 0) { - skinny_create_ingoing_session(listener, &line_instance, &session); - skinny_session_process_dest(session, listener, line_instance, button->line, '\0', 0); - } - break; - case SKINNY_BUTTON_HOLD: - session = skinny_profile_find_session(listener->profile, listener, &line_instance, call_id); - - if(session) { - status = skinny_session_hold_line(session, listener, line_instance); - } - break; - case SKINNY_BUTTON_VOICEMAIL: - skinny_create_ingoing_session(listener, &line_instance, &session); - skinny_session_process_dest(session, listener, line_instance, "vmain", '\0', 0); - break; - default: - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown Stimulus Type Received [%d]\n", request->data.stimulus.instance_type); - } - - if(session) { - switch_core_session_rwunlock(session); - } - - return status; + return SWITCH_STATUS_SUCCESS; } switch_status_t skinny_handle_open_receive_channel_ack_message(listener_t *listener, skinny_message_t *request) @@ -2407,80 +2292,132 @@ end: return status; } -switch_status_t skinny_handle_keypad_button_message(listener_t *listener, skinny_message_t *request) +switch_status_t skinny_handle_soft_key_set_request(listener_t *listener, skinny_message_t *request) { - uint32_t line_instance = 0; - switch_core_session_t *session; + skinny_message_t *message; + skinny_profile_t *profile; - skinny_check_data_length(request, sizeof(request->data.keypad_button)); + switch_assert(listener->profile); + switch_assert(listener->device_name); + + profile = listener->profile; + + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.soft_key_set)); + message->type = SOFT_KEY_SET_RES_MESSAGE; + message->length = 4 + sizeof(message->data.soft_key_set); + + message->data.soft_key_set.soft_key_set_offset = 0; + message->data.soft_key_set.soft_key_set_count = 11; + message->data.soft_key_set.total_soft_key_set_count = 11; + + /* TODO fill the set */ + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOOK].soft_key_template_index[0] = SOFTKEY_NEWCALL; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOOK].soft_key_template_index[1] = SOFTKEY_REDIAL; - if(request->data.keypad_button.line_instance) { - line_instance = request->data.keypad_button.line_instance; - } else { - line_instance = 1; - } + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK].soft_key_template_index[1] = SOFTKEY_REDIAL; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK].soft_key_template_index[2] = SOFTKEY_ENDCALL; - session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.keypad_button.call_id); + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT].soft_key_template_index[0] = SOFTKEY_BACKSPACE; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_DIGITS_AFTER_DIALING_FIRST_DIGIT].soft_key_template_index[2] = SOFTKEY_ENDCALL; - if(session) { - switch_channel_t *channel = NULL; - private_t *tech_pvt = NULL; - char digit = '\0'; - - channel = switch_core_session_get_channel(session); - tech_pvt = switch_core_session_get_private(session); - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "SEND DTMF ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button); - - if (request->data.keypad_button.button == 14) { - digit = '*'; - } else if (request->data.keypad_button.button == 15) { - digit = '#'; - } else if (request->data.keypad_button.button >= 0 && request->data.keypad_button.button <= 9) { - digit = '0' + request->data.keypad_button.button; - } else { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "UNKNOW DTMF RECEIVED ON CALL %d [%d]\n", tech_pvt->call_id, request->data.keypad_button.button); - } - - /* TODO check call_id and line */ - - if((skinny_line_get_state(listener, line_instance, tech_pvt->call_id) == SKINNY_OFF_HOOK)) { + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[0] = SOFTKEY_ENDCALL; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[1] = SOFTKEY_HOLD; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[2] = SOFTKEY_NEWCALL; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_CONNECTED].soft_key_template_index[3] = SOFTKEY_TRANSFER; - skinny_session_process_dest(session, listener, line_instance, NULL, digit, 0); - } else { - if(digit != '\0') { - switch_dtmf_t dtmf = { 0, switch_core_default_dtmf_duration(0)}; - dtmf.digit = digit; - switch_channel_queue_dtmf(channel, &dtmf); - } - } - } + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[0] = SOFTKEY_ANSWER; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[1] = SOFTKEY_ENDCALL; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_RING_IN].soft_key_template_index[2] = SOFTKEY_NEWCALL; - if(session) { - switch_core_session_rwunlock(session); - } + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[0] = SOFTKEY_NEWCALL; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[1] = SOFTKEY_RESUME; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_ON_HOLD].soft_key_template_index[2] = SOFTKEY_ENDCALL; + + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES].soft_key_template_index[1] = SOFTKEY_REDIAL; + message->data.soft_key_set.soft_key_set[SKINNY_KEY_SET_OFF_HOOK_WITH_FEATURES].soft_key_template_index[2] = SOFTKEY_ENDCALL; + + skinny_send_reply(listener, message); + + /* Init the states */ + send_select_soft_keys(listener, 0, 0, SKINNY_KEY_SET_ON_HOOK, 0xffff); return SWITCH_STATUS_SUCCESS; } -switch_status_t skinny_handle_on_hook_message(listener_t *listener, skinny_message_t *request) +switch_status_t skinny_handle_soft_key_event_message(listener_t *listener, skinny_message_t *request) { switch_status_t status = SWITCH_STATUS_SUCCESS; - switch_core_session_t *session = NULL; uint32_t line_instance = 0; + switch_core_session_t *session = NULL; + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; - skinny_check_data_length(request, sizeof(request->data.on_hook)); - - line_instance = request->data.on_hook.line_instance; + switch_assert(listener); + switch_assert(listener->profile); - session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.on_hook.call_id); + skinny_check_data_length(request, sizeof(request->data.soft_key_event)); - if(session) { - switch_channel_t *channel = NULL; + line_instance = request->data.soft_key_event.line_instance; - channel = switch_core_session_get_channel(session); + switch(request->data.soft_key_event.event) { + case SOFTKEY_REDIAL: + status = skinny_create_ingoing_session(listener, &line_instance, &session); - switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); + skinny_session_process_dest(session, listener, line_instance, "redial", '\0', 0); + break; + case SOFTKEY_NEWCALL: + status = skinny_create_ingoing_session(listener, &line_instance, &session); + tech_pvt = switch_core_session_get_private(session); + + skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 0); + break; + case SOFTKEY_HOLD: + session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); + + if(session) { + status = skinny_session_hold_line(session, listener, line_instance); + } + break; + case SOFTKEY_TRANSFER: + session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); + + if(session) { + status = skinny_session_transfer(session, listener, line_instance); + } + break; + case SOFTKEY_BACKSPACE: + session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); + + if(session) { + skinny_session_process_dest(session, listener, line_instance, NULL, '\0', 1); + } + break; + case SOFTKEY_ENDCALL: + session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); + + if(session) { + channel = switch_core_session_get_channel(session); + + switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); + } + break; + case SOFTKEY_RESUME: + session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); + + if(session) { + status = skinny_session_unhold_line(session, listener, line_instance); + } + break; + case SOFTKEY_ANSWER: + session = skinny_profile_find_session(listener->profile, listener, &line_instance, request->data.soft_key_event.call_id); + + if(session) { + status = skinny_session_answer(session, listener, line_instance); + } + break; + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Unknown SoftKeyEvent type: %d.\n", request->data.soft_key_event.event); } if(session) { @@ -2511,6 +2448,89 @@ switch_status_t skinny_handle_unregister(listener_t *listener, skinny_message_t return SWITCH_STATUS_SUCCESS; } +switch_status_t skinny_handle_soft_key_template_request(listener_t *listener, skinny_message_t *request) +{ + skinny_message_t *message; + skinny_profile_t *profile; + + switch_assert(listener->profile); + switch_assert(listener->device_name); + + profile = listener->profile; + + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.soft_key_template)); + message->type = SOFT_KEY_TEMPLATE_RES_MESSAGE; + message->length = 4 + sizeof(message->data.soft_key_template); + + message->data.soft_key_template.soft_key_offset = 0; + message->data.soft_key_template.soft_key_count = 21; + message->data.soft_key_template.total_soft_key_count = 21; + + memcpy(message->data.soft_key_template.soft_key, + soft_key_template_default, + sizeof(soft_key_template_default)); + + skinny_send_reply(listener, message); + + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t skinny_headset_status_message(listener_t *listener, skinny_message_t *request) +{ + skinny_check_data_length(request, sizeof(request->data.headset_status)); + + /* Nothing to do */ + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t skinny_handle_register_available_lines_message(listener_t *listener, skinny_message_t *request) +{ + skinny_check_data_length(request, sizeof(request->data.reg_lines)); + + /* Do nothing */ + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t skinny_handle_service_url_stat_request(listener_t *listener, skinny_message_t *request) +{ + skinny_message_t *message; + struct service_url_stat_res_message *button = NULL; + + skinny_check_data_length(request, sizeof(request->data.service_url_req)); + + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.service_url_res)); + message->type = SERVICE_URL_STAT_RES_MESSAGE; + message->length = 4 + sizeof(message->data.service_url_res); + + skinny_service_url_get(listener, request->data.service_url_req.service_url_index, &button); + + memcpy(&message->data.service_url_res, button, sizeof(struct service_url_stat_res_message)); + + skinny_send_reply(listener, message); + + return SWITCH_STATUS_SUCCESS; +} + +switch_status_t skinny_handle_feature_stat_request(listener_t *listener, skinny_message_t *request) +{ + skinny_message_t *message; + struct feature_stat_res_message *button = NULL; + + skinny_check_data_length(request, sizeof(request->data.feature_req)); + + message = switch_core_alloc(listener->pool, 12+sizeof(message->data.feature_res)); + message->type = FEATURE_STAT_RES_MESSAGE; + message->length = 4 + sizeof(message->data.feature_res); + + skinny_feature_get(listener, request->data.feature_req.feature_index, &button); + + memcpy(&message->data.feature_res, button, sizeof(struct feature_stat_res_message)); + + skinny_send_reply(listener, message); + + return SWITCH_STATUS_SUCCESS; +} + switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *request) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, @@ -2545,6 +2565,8 @@ switch_status_t skinny_handle_request(listener_t *listener, skinny_message_t *re return skinny_handle_time_date_request(listener, request); case BUTTON_TEMPLATE_REQ_MESSAGE: return skinny_handle_button_template_request(listener, request); + case VERSION_REQ_MESSAGE: + return skinny_handle_version_request(listener, request); case CAPABILITIES_RES_MESSAGE: return skinny_handle_capabilities_response(listener, request); case ALARM_MESSAGE: diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.h b/src/mod/endpoints/mod_skinny/skinny_protocol.h index 994462684f..aeaa42f09e 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.h +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.h @@ -114,6 +114,9 @@ struct line_stat_req_message { /* ButtonTemplateReqMessage */ #define BUTTON_TEMPLATE_REQ_MESSAGE 0x000E +/* VersionReqMessage */ +#define VERSION_REQ_MESSAGE 0x000F + /* CapabilitiesResMessage */ #define CAPABILITIES_RES_MESSAGE 0x0010 struct station_capabilities { @@ -343,6 +346,12 @@ struct button_template_message { struct button_definition btn[SKINNY_MAX_BUTTON_COUNT]; }; +/* VersionMessage */ +#define VERSION_MESSAGE 0x0098 +struct version_message { + char version[16]; +}; + /* CapabilitiesReqMessage */ #define CAPABILITIES_REQ_MESSAGE 0x009B @@ -535,6 +544,7 @@ union skinny_data { struct config_stat_res_message config_res; struct define_time_date_message define_time_date; struct button_template_message button_template; + struct version_message version; struct register_reject_message reg_rej; struct reset_message reset; struct open_receive_channel_message open_receive_channel; @@ -724,6 +734,10 @@ switch_status_t send_define_time_date(listener_t *listener, uint32_t milliseconds, uint32_t timestamp); switch_status_t send_define_current_time_date(listener_t *listener); +switch_status_t send_version(listener_t *listener, + char *version); +switch_status_t send_register_reject(listener_t *listener, + char *error); switch_status_t send_open_receive_channel(listener_t *listener, uint32_t conference_id, uint32_t pass_thru_party_id, diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c index a9bf84431f..42e8bb96b3 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.c +++ b/src/mod/endpoints/mod_skinny/skinny_tables.c @@ -47,6 +47,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {"ConfigStatReqMessage", CONFIG_STAT_REQ_MESSAGE}, {"TimeDateReqMessage", TIME_DATE_REQ_MESSAGE}, {"ButtonTemplateReqMessage", BUTTON_TEMPLATE_REQ_MESSAGE}, + {"VersionReqMessage", VERSION_REQ_MESSAGE}, {"CapabilitiesReqMessage", CAPABILITIES_RES_MESSAGE}, {"AlarmMessage", ALARM_MESSAGE}, {"OpenReceiveChannelAckMessage", OPEN_RECEIVE_CHANNEL_ACK_MESSAGE}, @@ -72,6 +73,7 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { {"ConfigStatResMessage", CONFIG_STAT_RES_MESSAGE}, {"DefineTimeDateMessage", DEFINE_TIME_DATE_MESSAGE}, {"ButtonTemplateResMessage", BUTTON_TEMPLATE_RES_MESSAGE}, + {"VersionMessage", VERSION_MESSAGE}, {"CapabilitiesReqMessage", CAPABILITIES_REQ_MESSAGE}, {"RegisterRejectMessage", REGISTER_REJECT_MESSAGE}, {"ResetMessage", RESET_MESSAGE}, diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h index f3755b5c2f..90bc45ef91 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.h +++ b/src/mod/endpoints/mod_skinny/skinny_tables.h @@ -84,7 +84,7 @@ uint32_t func(const char *str)\ } -struct skinny_table SKINNY_MESSAGE_TYPES[57]; +struct skinny_table SKINNY_MESSAGE_TYPES[59]; const char *skinny_message_type2str(uint32_t id); uint32_t skinny_str2message_type(const char *str); #define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES) From deb2277936caedc9d4df11b1aae7bde666bf911a Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Fri, 16 Apr 2010 15:16:27 +0200 Subject: [PATCH 06/62] Skinny: allow firmware version per device --- src/mod/endpoints/mod_skinny/mod_skinny.h | 2 ++ .../endpoints/mod_skinny/skinny_protocol.c | 27 +++++++++++++------ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h index 341499967d..61ded754a3 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.h +++ b/src/mod/endpoints/mod_skinny/mod_skinny.h @@ -107,6 +107,8 @@ struct listener { skinny_profile_t *profile; char device_name[16]; uint32_t device_instance; + + char firmware_version[16]; switch_socket_t *sock; switch_memory_pool_t *pool; diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.c b/src/mod/endpoints/mod_skinny/skinny_protocol.c index 975007279c..f1bb313fa3 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.c +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.c @@ -1609,7 +1609,7 @@ switch_status_t skinny_handle_register(listener_t *listener, skinny_message_t *r skinny_profile_t *profile; switch_event_t *event = NULL; switch_event_t *params = NULL; - switch_xml_t xroot, xdomain, xgroup, xuser, xskinny, xbuttons, xbutton; + switch_xml_t xroot, xdomain, xgroup, xuser, xskinny, xparams, xparam, xbuttons, xbutton; char *sql; assert(listener->profile); profile = listener->profile; @@ -1658,8 +1658,16 @@ switch_status_t skinny_handle_register(listener_t *listener, skinny_message_t *r xskinny = switch_xml_child(xuser, "skinny"); if (xskinny) { - xbuttons = switch_xml_child(xskinny, "buttons"); - if (xbuttons) { + if ((xparams = switch_xml_child(xskinny, "params"))) { + for (xparam = switch_xml_child(xparams, "param"); xparam; xparam = xparam->next) { + const char *name = switch_xml_attr_soft(xparam, "name"); + const char *value = switch_xml_attr_soft(xparam, "value"); + if (!strcasecmp(name, "skinny-firmware-version")) { + strncpy(listener->firmware_version, value, 16); + } + } + } + if ((xbuttons = switch_xml_child(xskinny, "buttons"))) { uint32_t line_instance = 1; for (xbutton = switch_xml_child(xbuttons, "button"); xbutton; xbutton = xbutton->next) { uint32_t position = atoi(switch_xml_attr_soft(xbutton, "position")); @@ -2118,11 +2126,14 @@ switch_status_t skinny_handle_button_template_request(listener_t *listener, skin switch_status_t skinny_handle_version_request(listener_t *listener, skinny_message_t *request) { - /* TODO */ - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, - "VersionReqMessage not implemented yet.\n"); - return SWITCH_STATUS_SUCCESS; - /* return send_version(listener, ""); */ + if (!zstr(listener->firmware_version)) { + return send_version(listener, listener->firmware_version); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Device %s:%d is requesting for firmware version, but none is set.\n", + listener->device_name, listener->device_instance); + return SWITCH_STATUS_SUCCESS; + } } switch_status_t skinny_handle_capabilities_response(listener_t *listener, skinny_message_t *request) From 31c9f50fa196ee164e12aba72ec3e5a338305632 Mon Sep 17 00:00:00 2001 From: Christopher Rienzo Date: Fri, 16 Apr 2010 14:34:22 +0100 Subject: [PATCH 07/62] my first git commit - added comment to mod_unimrcp.c --- src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c index dfce2cecaf..1ecc1404ce 100644 --- a/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c +++ b/src/mod/asr_tts/mod_unimrcp/mod_unimrcp.c @@ -2059,6 +2059,7 @@ static switch_status_t recog_channel_start(speech_channel_t *schannel, const cha r->start_of_input = 0; /* input timers are started by default unless the start-input-timers=false param is set */ + /* TODO this is true for Nuance, but might not be true on other MRCP servers */ start_input_timers = (char *) switch_core_hash_find(schannel->params, "start-input-timers"); r->timers_started = zstr(start_input_timers) || strcasecmp(start_input_timers, "false"); From c9aabe2c116bd1d47b18d753ac33b00342d97fd2 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Fri, 16 Apr 2010 08:59:08 -0500 Subject: [PATCH 08/62] FSBUILD-262 --- src/mod/endpoints/mod_skypopen/mod_skypopen.2008.vcproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_skypopen/mod_skypopen.2008.vcproj b/src/mod/endpoints/mod_skypopen/mod_skypopen.2008.vcproj index f2516ff7bf..1e3acada07 100644 --- a/src/mod/endpoints/mod_skypopen/mod_skypopen.2008.vcproj +++ b/src/mod/endpoints/mod_skypopen/mod_skypopen.2008.vcproj @@ -118,7 +118,7 @@ /> From 33c05ead16eda037e70a38de71435fbe6c4e3422 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 16 Apr 2010 09:35:41 -0500 Subject: [PATCH 09/62] add uuid_autoanswer command --- src/include/switch_types.h | 1 + .../applications/mod_commands/mod_commands.c | 33 +++++++++++++++++++ src/mod/endpoints/mod_sofia/mod_sofia.c | 5 +++ src/switch_core_session.c | 1 + 4 files changed, 40 insertions(+) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 0d47984a5f..df14f2bfd5 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -690,6 +690,7 @@ typedef enum { SWITCH_MESSAGE_INDICATE_PROXY_MEDIA, SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC, SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC_COMPLETE, + SWITCH_MESSAGE_INDICATE_AUTOANSWER, SWITCH_MESSAGE_INVALID } switch_core_session_message_types_t; diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 23fbaf23a4..3be030deed 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2347,6 +2347,37 @@ SWITCH_STANDARD_API(uuid_simplify_function) } +#define AUTOANSWER_SYNTAX "" +SWITCH_STANDARD_API(uuid_autoanswer_function) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (zstr(cmd)) { + stream->write_function(stream, "-USAGE: %s\n", AUTOANSWER_SYNTAX); + } else { + switch_core_session_message_t msg = { 0 }; + switch_core_session_t *lsession = NULL; + + msg.message_id = SWITCH_MESSAGE_INDICATE_AUTOANSWER; + msg.string_arg = cmd; + msg.from = __FILE__; + + if ((lsession = switch_core_session_locate(cmd))) { + status = switch_core_session_receive_message(lsession, &msg); + switch_core_session_rwunlock(lsession); + } + } + + if (status == SWITCH_STATUS_SUCCESS) { + stream->write_function(stream, "+OK Success\n"); + } else { + stream->write_function(stream, "-ERR Operation Failed\n"); + } + + return SWITCH_STATUS_SUCCESS; +} + + #define DEBUG_AUDIO_SYNTAX " " SWITCH_STANDARD_API(uuid_debug_audio_function) { @@ -4202,6 +4233,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "user_data", "find user data", user_data_function, "@ [var|param|attr] "); SWITCH_ADD_API(commands_api_interface, "user_exists", "find a user", user_exists_function, " "); SWITCH_ADD_API(commands_api_interface, "uuid_audio", "uuid_audio", session_audio_function, AUDIO_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "uuid_autoanswer", "Force a ringing channel offhook", uuid_autoanswer_function, AUTOANSWER_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_break", "Break", break_function, BREAK_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_bridge", "uuid_bridge", uuid_bridge_function, ""); SWITCH_ADD_API(commands_api_interface, "uuid_broadcast", "broadcast", uuid_broadcast_function, BROADCAST_SYNTAX); @@ -4300,6 +4332,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add uuid_audio ::console::list_uuid start write mute"); switch_console_set_complete("add uuid_audio ::console::list_uuid start write level"); switch_console_set_complete("add uuid_audio ::console::list_uuid stop"); + switch_console_set_complete("add uuid_autoanswer ::console::list_uuid"); switch_console_set_complete("add uuid_break ::console::list_uuid all"); switch_console_set_complete("add uuid_break ::console::list_uuid both"); switch_console_set_complete("add uuid_bridge ::console::list_uuid ::console::list_uuid"); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 0f0abfa09a..91432ab672 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1496,6 +1496,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } break; + case SWITCH_MESSAGE_INDICATE_AUTOANSWER: + { + nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR("talk"), TAG_END()); + } + break; case SWITCH_MESSAGE_INDICATE_SIMPLIFY: { char *ref_to, *ref_by; diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 863b928092..46adc7d442 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -555,6 +555,7 @@ static const char *message_names[] = { "PROXY_MEDIA", "APPLICATION_EXEC", "APPLICATION_EXEC_COMPLETE", + "AUTOANSWER", "INVALID" }; From d265cbfce485fc9b23ac30fc4c53ffa11cd70d6c Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 16 Apr 2010 10:01:00 -0500 Subject: [PATCH 10/62] expand last patch to do hold as well and rename the command to uuid_phone_event --- src/include/switch_types.h | 2 +- .../applications/mod_commands/mod_commands.c | 31 ++++++++++++------- src/mod/endpoints/mod_sofia/mod_sofia.c | 12 +++++-- src/mod/endpoints/mod_sofia/sofia.c | 1 + src/switch_core_session.c | 2 +- 5 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/include/switch_types.h b/src/include/switch_types.h index df14f2bfd5..3c624e922e 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -690,7 +690,7 @@ typedef enum { SWITCH_MESSAGE_INDICATE_PROXY_MEDIA, SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC, SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC_COMPLETE, - SWITCH_MESSAGE_INDICATE_AUTOANSWER, + SWITCH_MESSAGE_INDICATE_PHONE_EVENT, SWITCH_MESSAGE_INVALID } switch_core_session_message_types_t; diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 3be030deed..6dc2d8c913 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2319,7 +2319,7 @@ SWITCH_STANDARD_API(uuid_display_function) #define SIMPLIFY_SYNTAX "" SWITCH_STANDARD_API(uuid_simplify_function) { - switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_status_t status = SWITCH_STATUS_FALSE; if (zstr(cmd)) { stream->write_function(stream, "-USAGE: %s\n", SIMPLIFY_SYNTAX); @@ -2347,22 +2347,28 @@ SWITCH_STANDARD_API(uuid_simplify_function) } -#define AUTOANSWER_SYNTAX "" -SWITCH_STANDARD_API(uuid_autoanswer_function) +#define PHONE_EVENT_SYNTAX "" +SWITCH_STANDARD_API(uuid_phone_event_function) { - switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_status_t status = SWITCH_STATUS_FALSE; + char *mycmd = NULL, *argv[2] = { 0 }; + int argc = 0; - if (zstr(cmd)) { - stream->write_function(stream, "-USAGE: %s\n", AUTOANSWER_SYNTAX); + if (!zstr(cmd) && (mycmd = strdup(cmd))) { + argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0]))); + } + + if (argc < 1) { + stream->write_function(stream, "-USAGE: %s\n", PHONE_EVENT_SYNTAX); } else { switch_core_session_message_t msg = { 0 }; switch_core_session_t *lsession = NULL; - msg.message_id = SWITCH_MESSAGE_INDICATE_AUTOANSWER; - msg.string_arg = cmd; + msg.message_id = SWITCH_MESSAGE_INDICATE_PHONE_EVENT; + msg.string_arg = argv[1]; msg.from = __FILE__; - if ((lsession = switch_core_session_locate(cmd))) { + if ((lsession = switch_core_session_locate(argv[0]))) { status = switch_core_session_receive_message(lsession, &msg); switch_core_session_rwunlock(lsession); } @@ -2374,6 +2380,8 @@ SWITCH_STANDARD_API(uuid_autoanswer_function) stream->write_function(stream, "-ERR Operation Failed\n"); } + switch_safe_free(mycmd); + return SWITCH_STATUS_SUCCESS; } @@ -4233,7 +4241,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "user_data", "find user data", user_data_function, "@ [var|param|attr] "); SWITCH_ADD_API(commands_api_interface, "user_exists", "find a user", user_exists_function, " "); SWITCH_ADD_API(commands_api_interface, "uuid_audio", "uuid_audio", session_audio_function, AUDIO_SYNTAX); - SWITCH_ADD_API(commands_api_interface, "uuid_autoanswer", "Force a ringing channel offhook", uuid_autoanswer_function, AUTOANSWER_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_break", "Break", break_function, BREAK_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_bridge", "uuid_bridge", uuid_bridge_function, ""); SWITCH_ADD_API(commands_api_interface, "uuid_broadcast", "broadcast", uuid_broadcast_function, BROADCAST_SYNTAX); @@ -4251,6 +4258,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "uuid_loglevel", "set loglevel on session", uuid_loglevel, UUID_LOGLEVEL_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_media", "media", uuid_media_function, MEDIA_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_park", "Park Channel", park_function, PARK_SYNTAX); + SWITCH_ADD_API(commands_api_interface, "uuid_phone_event", "Send and event to the phone", uuid_phone_event_function, PHONE_EVENT_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_preprocess", "Pre-process Channel", preprocess_function, PREPROCESS_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_record", "session record", session_record_function, SESS_REC_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_recv_dtmf", "receive dtmf digits", uuid_recv_dtmf_function, UUID_RECV_DTMF_SYNTAX); @@ -4332,7 +4340,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add uuid_audio ::console::list_uuid start write mute"); switch_console_set_complete("add uuid_audio ::console::list_uuid start write level"); switch_console_set_complete("add uuid_audio ::console::list_uuid stop"); - switch_console_set_complete("add uuid_autoanswer ::console::list_uuid"); switch_console_set_complete("add uuid_break ::console::list_uuid all"); switch_console_set_complete("add uuid_break ::console::list_uuid both"); switch_console_set_complete("add uuid_bridge ::console::list_uuid ::console::list_uuid"); @@ -4358,6 +4365,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add uuid_loglevel ::console::list_uuid debug"); switch_console_set_complete("add uuid_media ::console::list_uuid"); switch_console_set_complete("add uuid_park ::console::list_uuid"); + switch_console_set_complete("add uuid_phone_event ::console::list_uuid talk"); + switch_console_set_complete("add uuid_phone_event ::console::list_uuid hold"); switch_console_set_complete("add uuid_preprocess ::console::list_uuid"); switch_console_set_complete("add uuid_record ::console::list_uuid"); switch_console_set_complete("add uuid_recv_dtmf ::console::list_uuid"); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 91432ab672..32512b4544 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1496,9 +1496,17 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi } break; - case SWITCH_MESSAGE_INDICATE_AUTOANSWER: + case SWITCH_MESSAGE_INDICATE_PHONE_EVENT: { - nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR("talk"), TAG_END()); + const char *event = "talk"; + if (!zstr(msg->string_arg) && strcasecmp(msg->string_arg, event)) { + if (!strcasecmp(msg->string_arg, "hold")) { + event = "hold"; + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Invalid event.\n"); + } + } + nua_notify(tech_pvt->nh, NUTAG_NEWSUB(1), NUTAG_SUBSTATE(nua_substate_active), SIPTAG_EVENT_STR(event), TAG_END()); } break; case SWITCH_MESSAGE_INDICATE_SIMPLIFY: diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index df3da21156..6d21074516 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -1371,6 +1371,7 @@ void *SWITCH_THREAD_FUNC sofia_profile_thread_run(switch_thread_t *thread, void NUTAG_ALLOW("INFO"), NUTAG_ALLOW("NOTIFY"), NUTAG_ALLOW_EVENTS("talk"), + NUTAG_ALLOW_EVENTS("hold"), NUTAG_SESSION_TIMER(profile->session_timeout), NTATAG_MAX_PROCEEDING(profile->max_proceeding), TAG_IF(profile->pres_type, NUTAG_ALLOW("PUBLISH")), diff --git a/src/switch_core_session.c b/src/switch_core_session.c index 46adc7d442..69f2492a93 100644 --- a/src/switch_core_session.c +++ b/src/switch_core_session.c @@ -555,7 +555,7 @@ static const char *message_names[] = { "PROXY_MEDIA", "APPLICATION_EXEC", "APPLICATION_EXEC_COMPLETE", - "AUTOANSWER", + "PHONE_EVENT", "INVALID" }; From 03f91afd34da3ace3f0a2c213fa1b2de4b108ed9 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Fri, 16 Apr 2010 17:30:49 +0200 Subject: [PATCH 11/62] Skinny: VersionMessage per device type --- src/mod/endpoints/mod_skinny/mod_skinny.c | 32 +++++++++++++++++-- src/mod/endpoints/mod_skinny/mod_skinny.h | 8 ++++- .../endpoints/mod_skinny/skinny_protocol.c | 15 +++++++++ src/mod/endpoints/mod_skinny/skinny_tables.c | 18 +++++++++++ src/mod/endpoints/mod_skinny/skinny_tables.h | 5 +++ src/mod/endpoints/mod_skinny/test-skinny.pl | 5 +++ 6 files changed, 80 insertions(+), 3 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index 63cc514429..a90df113d8 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -1460,13 +1460,14 @@ static switch_status_t load_skinny_config(void) if ((xprofiles = switch_xml_child(xcfg, "profiles"))) { for (xprofile = switch_xml_child(xprofiles, "profile"); xprofile; xprofile = xprofile->next) { char *profile_name = (char *) switch_xml_attr_soft(xprofile, "name"); - switch_xml_t xsettings = switch_xml_child(xprofile, "settings"); + switch_xml_t xsettings; + switch_xml_t xdevice_types; if (zstr(profile_name)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " is missing name attribute\n"); continue; } - if (xsettings) { + if ((xsettings = switch_xml_child(xprofile, "settings"))) { switch_memory_pool_t *profile_pool = NULL; char dbname[256]; switch_core_db_t *db; @@ -1521,6 +1522,7 @@ static switch_status_t load_skinny_config(void) profile->port = 2000; } + /* Database */ switch_snprintf(dbname, sizeof(dbname), "skinny_%s", profile->name); profile->dbname = switch_core_strdup(profile->pool, dbname); @@ -1558,6 +1560,32 @@ static switch_status_t load_skinny_config(void) skinny_execute_sql_callback(profile, profile->sql_mutex, "DELETE FROM skinny_buttons", NULL, NULL); skinny_execute_sql_callback(profile, profile->sql_mutex, "DELETE FROM skinny_active_lines", NULL, NULL); + /* Device types */ + switch_core_hash_init(&profile->device_type_params_hash, profile->pool); + if ((xdevice_types = switch_xml_child(xprofile, "device-types"))) { + switch_xml_t xdevice_type; + for (xdevice_type = switch_xml_child(xdevice_types, "device-type"); xdevice_type; xdevice_type = xdevice_type->next) { + uint32_t id = skinny_str2device_type(switch_xml_attr_soft(xdevice_type, "id")); + if (id != 0) { + char *id_str = switch_mprintf("%d", id); + skinny_device_type_params_t *params = switch_core_alloc(profile->pool, sizeof(skinny_device_type_params_t)); + for (param = switch_xml_child(xdevice_type, "param"); param; param = param->next) { + char *var = (char *) switch_xml_attr_soft(param, "name"); + char *val = (char *) switch_xml_attr_soft(param, "value"); + + if (!strcasecmp(var, "firmware-version")) { + strncpy(params->firmware_version, val, 16); + } + } /* param */ + switch_core_hash_insert(profile->device_type_params_hash, id_str, params); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "Unknow device type %s in profile %s.\n", switch_xml_attr_soft(xdevice_type, "id"), profile->name); + } + } + } + + /* Register profile */ switch_mutex_lock(globals.mutex); switch_core_hash_insert(globals.profile_hash, profile->name, profile); switch_mutex_unlock(globals.mutex); diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h index 61ded754a3..d8728510a6 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.h +++ b/src/mod/endpoints/mod_skinny/mod_skinny.h @@ -67,6 +67,7 @@ struct skinny_profile { uint32_t keep_alive; char date_format[6]; int debug; + switch_hash_t *device_type_params_hash; /* db */ char *dbname; char *odbc_dsn; @@ -93,6 +94,10 @@ struct skinny_profile { }; typedef struct skinny_profile skinny_profile_t; +struct skinny_device_type_params { + char firmware_version[16]; +}; +typedef struct skinny_device_type_params skinny_device_type_params_t; /*****************************************************************************/ /* LISTENERS TYPES */ @@ -107,8 +112,9 @@ struct listener { skinny_profile_t *profile; char device_name[16]; uint32_t device_instance; + uint32_t device_type; - char firmware_version[16]; + char firmware_version[16]; switch_socket_t *sock; switch_memory_pool_t *pool; diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.c b/src/mod/endpoints/mod_skinny/skinny_protocol.c index f1bb313fa3..0c0396e7f6 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.c +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.c @@ -1394,6 +1394,8 @@ switch_status_t send_version(listener_t *listener, { skinny_message_t *message; message = switch_core_alloc(listener->pool, 12+sizeof(message->data.version)); + message->type = VERSION_MESSAGE; + message->length = 4+ sizeof(message->data.version); strncpy(message->data.version.version, version, 16); return skinny_send_reply(listener, message); } @@ -1655,6 +1657,7 @@ switch_status_t skinny_handle_register(listener_t *listener, skinny_message_t *r strncpy(listener->device_name, request->data.reg.device_name, 16); listener->device_instance = request->data.reg.instance; + listener->device_type = request->data.reg.device_type; xskinny = switch_xml_child(xuser, "skinny"); if (xskinny) { @@ -2126,6 +2129,18 @@ switch_status_t skinny_handle_button_template_request(listener_t *listener, skin switch_status_t skinny_handle_version_request(listener_t *listener, skinny_message_t *request) { + if (zstr(listener->firmware_version)) { + char *id_str; + skinny_device_type_params_t *params; + id_str = switch_mprintf("%d", listener->device_type); + params = (skinny_device_type_params_t *) switch_core_hash_find(listener->profile->device_type_params_hash, id_str); + if (params) { + if (!zstr(params->firmware_version)) { + strncpy(listener->firmware_version, params->firmware_version, 16); + } + } + } + if (!zstr(listener->firmware_version)) { return send_version(listener, listener->firmware_version); } else { diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.c b/src/mod/endpoints/mod_skinny/skinny_tables.c index 42e8bb96b3..ac16b6509f 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.c +++ b/src/mod/endpoints/mod_skinny/skinny_tables.c @@ -98,6 +98,24 @@ struct skinny_table SKINNY_MESSAGE_TYPES[] = { SKINNY_DECLARE_ID2STR(skinny_message_type2str, SKINNY_MESSAGE_TYPES, "UnknownMessage") SKINNY_DECLARE_STR2ID(skinny_str2message_type, SKINNY_MESSAGE_TYPES, -1) +struct skinny_table SKINNY_DEVICE_TYPES[] = { + {"Cisco 30 SP+", 0x0001}, + {"Cisco 12 SP+", 0x0002}, + {"Cisco 12 SP", 0x0003}, + {"Cisco 12", 0x0004}, + {"Cisco 30 VIP", 0x0005}, + {"Cisco IP Phone 7910", 0x0006}, + {"Cisco IP Phone 7960", 0x0007}, + {"Cisco IP Phone 7940", 0x0008}, + {"Cisco IP Phone 7935", 0x0009}, + {"Cisco ATA 186", 0x000c}, + {"Cisco IP Phone 7961", 0x4275}, + {"Cisco IP Phone 7936", 0x4276}, + {NULL, 0} +}; +SKINNY_DECLARE_ID2STR(skinny_device_type2str, SKINNY_DEVICE_TYPES, "UnknownDeviceType") +SKINNY_DECLARE_STR2ID(skinny_str2device_type, SKINNY_DEVICE_TYPES, -1) + struct skinny_table SKINNY_RING_TYPES[] = { {"RingOff", SKINNY_RING_OFF}, {"RingInside", SKINNY_RING_INSIDE}, diff --git a/src/mod/endpoints/mod_skinny/skinny_tables.h b/src/mod/endpoints/mod_skinny/skinny_tables.h index 90bc45ef91..5efd774648 100644 --- a/src/mod/endpoints/mod_skinny/skinny_tables.h +++ b/src/mod/endpoints/mod_skinny/skinny_tables.h @@ -89,6 +89,11 @@ const char *skinny_message_type2str(uint32_t id); uint32_t skinny_str2message_type(const char *str); #define SKINNY_PUSH_MESSAGE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_MESSAGE_TYPES) +struct skinny_table SKINNY_DEVICE_TYPES[13]; +const char *skinny_device_type2str(uint32_t id); +uint32_t skinny_str2device_type(const char *str); +#define SKINNY_PUSH_DEVICE_TYPES SKINNY_DECLARE_PUSH_MATCH(SKINNY_DEVICE_TYPES) + enum skinny_tone { SKINNY_TONE_SILENCE = 0x00, SKINNY_TONE_DIALTONE = 0x21, diff --git a/src/mod/endpoints/mod_skinny/test-skinny.pl b/src/mod/endpoints/mod_skinny/test-skinny.pl index a8c7bb5d68..a44afa33dc 100644 --- a/src/mod/endpoints/mod_skinny/test-skinny.pl +++ b/src/mod/endpoints/mod_skinny/test-skinny.pl @@ -64,6 +64,11 @@ $socket->send_message( ) ); +if(0) { + $socket->send_message(VERSION_REQ_MESSAGE); + $socket->receive_message(); # VersionMessage +} + $socket->send_message(BUTTON_TEMPLATE_REQ_MESSAGE); $socket->receive_message(); # ButtonTemplateMessage From 4ca3f5746f7db9af79cae7dc730fa61d381ff979 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Fri, 16 Apr 2010 17:32:00 +0200 Subject: [PATCH 12/62] SKinny: example firmware version --- conf/skinny_profiles/internal.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/conf/skinny_profiles/internal.xml b/conf/skinny_profiles/internal.xml index 00ce803493..e9b08133d3 100644 --- a/conf/skinny_profiles/internal.xml +++ b/conf/skinny_profiles/internal.xml @@ -10,5 +10,10 @@ + + + + + From 9a689a45fc19ca0c2107d333f2f3ac5e0495776f Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Fri, 16 Apr 2010 17:59:48 +0200 Subject: [PATCH 13/62] Skinny: correct transfer --- src/mod/endpoints/mod_skinny/skinny_protocol.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.c b/src/mod/endpoints/mod_skinny/skinny_protocol.c index 0c0396e7f6..261ef98789 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.c +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.c @@ -842,7 +842,7 @@ switch_status_t skinny_session_transfer(switch_core_session_t *session, listener switch_status_t status = SWITCH_STATUS_SUCCESS; private_t *tech_pvt = NULL; switch_channel_t *channel = NULL; - const char *uuid = NULL; + const char *remote_uuid = NULL; switch_core_session_t *session2 = NULL; private_t *tech_pvt2 = NULL; @@ -852,18 +852,22 @@ switch_status_t skinny_session_transfer(switch_core_session_t *session, listener tech_pvt = switch_core_session_get_private(session); channel = switch_core_session_get_channel(session); - uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE); + remote_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE); if (tech_pvt->transfer_from_call_id) { - if((session2 = skinny_profile_find_session(listener->profile, listener, &line_instance, 0))) { + if((session2 = skinny_profile_find_session(listener->profile, listener, &line_instance, tech_pvt->transfer_from_call_id))) { switch_channel_t *channel2 = switch_core_session_get_channel(session2); - const char *uuid2 = switch_channel_get_variable(channel2, SWITCH_BRIDGE_VARIABLE); - switch_ivr_uuid_bridge(uuid, uuid2); + const char *remote_uuid2 = switch_channel_get_variable(channel2, SWITCH_SIGNAL_BOND_VARIABLE); + if (switch_ivr_uuid_bridge(remote_uuid, remote_uuid2) == SWITCH_STATUS_SUCCESS) { + switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); + switch_channel_hangup(channel2, SWITCH_CAUSE_NORMAL_CLEARING); + } else { + /* TODO: How to inform the user that the bridge is not possible? */ + } switch_core_session_rwunlock(session2); - /* TODO: How to inform the user that the bridge is not possible? */ } } else { - if(uuid) { + if(remote_uuid) { /* TODO CallSelectStat */ status = skinny_create_ingoing_session(listener, &line_instance, &session2); tech_pvt2 = switch_core_session_get_private(session2); From 02d51915490d7fc8e60b9502ddd34c9d1f82e5d0 Mon Sep 17 00:00:00 2001 From: Nenad Corbic Date: Thu, 15 Apr 2010 19:50:24 -0400 Subject: [PATCH 14/62] Bug fixes in freetdm and openzap --- .../ftmod_sangoma_boost/ftmod_sangoma_boost.c | 114 ++++++++++++------ .../ozmod_sangoma_boost/ozmod_sangoma_boost.c | 56 ++++++--- 2 files changed, 113 insertions(+), 57 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index c950798b09..e916c403ab 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@ -73,15 +73,14 @@ static ftdm_status_t ftdm_sangoma_boost_list_sigmods(ftdm_stream_handle_t *strea #define BOOST_EVENT_CHAN(sigmod, event) ((sigmod)? event->chan:event->chan+1) /** - * \brief Strange flag + * \brief SANGOMA boost notification flag */ typedef enum { - SFLAG_FREE_REQ_ID = (1 << 0), - SFLAG_SENT_FINAL_MSG = (1 << 1), - SFLAG_SENT_ACK = (1 << 2), - SFLAG_RECVD_ACK = (1 << 3), - SFLAG_HANGUP = (1 << 4), - SFLAG_TERMINATING = (1 << 5) + SFLAG_SENT_FINAL_MSG = (1 << 0), + SFLAG_SENT_ACK = (1 << 1), + SFLAG_RECVD_ACK = (1 << 2), + SFLAG_HANGUP = (1 << 3), + SFLAG_TERMINATING = (1 << 4) } sflag_t; typedef uint16_t sangoma_boost_request_id_t; @@ -214,17 +213,20 @@ static sangoma_boost_request_id_t __next_request_id(const char *func, int line) static void print_request_ids(void) { sangoma_boost_request_id_t i = 0; - + int cnt=0; + ftdm_mutex_lock(request_mutex); for (i=1; i<= MAX_REQ_ID; i++){ if (req_map[i]) { ftdm_log(FTDM_LOG_CRIT, "Used Request ID=%i\n",i); + cnt++; } } ftdm_mutex_unlock(request_mutex); - + ftdm_log(FTDM_LOG_CRIT, "Total Request IDs=%i\n",cnt); + return; } @@ -630,6 +632,12 @@ static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_ if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { ftdm_log(FTDM_LOG_ERROR, "Failed to open FTDM channel [%s]\n", ftdmchan->last_error); } else { + + /* Only bind the setup id to GRID when we are sure that channel is ready + otherwise we could overwite the original call */ + OUTBOUND_REQUESTS[event->call_setup_id].event = *event; + SETUP_GRID[event->span][event->chan] = event->call_setup_id; + ftdm_set_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND); ftdm_set_flag_locked(ftdmchan, FTDM_CHANNEL_INUSE); ftdmchan->sflags = SFLAG_RECVD_ACK; @@ -668,6 +676,7 @@ static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_ OUTBOUND_REQUESTS[event->call_setup_id].status = BST_READY; return; } + } else { ftdm_assert(!mcon->sigmod, "CALL STOP ACK: Invalid Sigmod Path"); @@ -682,16 +691,16 @@ static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_ if (ftdmchan->state == FTDM_CHANNEL_STATE_UP || ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA || ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS) { - ftdm_log(FTDM_LOG_CRIT, "FTDM_CHAN STATE UP/PROG/PROG_MEDIA -> Changed to HANGUP %d:%d\n", event->span+1,event->chan+1); - ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP, 0, r); - - } else if (ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) { - /* Do nothing because outgoing STOP will generaate a stop ack */ - + ftdm_log(FTDM_LOG_CRIT, "ZCHAN CALL ACK STATE UP -> Changed to TERMINATING %d:%d\n", event->span+1,event->chan+1); + ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r); + } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP || ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) { + ftdm_log(FTDM_LOG_CRIT, "ZCHAN CALL ACK STATE HANGUP -> Changed to HANGUP COMPLETE %d:%d\n", event->span+1,event->chan+1); + ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, 0, r); } else { - ftdm_log(FTDM_LOG_CRIT, "FTDM_CHAN STATE INVALID %s on IN CALL ACK %d:%d\n", ftdm_channel_state2str(ftdmchan->state),event->span+1,event->chan+1); - + ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE INVALID State %s on IN CALL ACK %d:%d\n", + ftdm_channel_state2str(ftdmchan->state),event->span+1,event->chan+1); } + ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG); ftdmchan=NULL; } } @@ -747,7 +756,6 @@ static void handle_call_done(ftdm_span_t *span, sangomabc_connection_t *mcon, sa ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, 0, r); if (r) { - ftdm_set_sflag(ftdmchan, SFLAG_FREE_REQ_ID); ftdm_mutex_unlock(ftdmchan->mutex); return; } @@ -920,10 +928,6 @@ static void handle_call_stop(ftdm_span_t *span, sangomabc_connection_t *mcon, sa ftdmchan->caller_data.hangup_cause = event->release_cause; } - if (r) { - ftdm_set_sflag(ftdmchan, SFLAG_FREE_REQ_ID); - } - ftdm_mutex_unlock(ftdmchan->mutex); if (r) { @@ -994,15 +998,19 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s /* NC: If we get CALL START and channel is in active state then we are completely out of sync with the other end. Treat CALL START as CALL STOP and hangup the current call. + The incoming call will also be NACKed. */ - if (ftdmchan->state == FTDM_CHANNEL_STATE_UP) { - ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE UP -> Changed to TERMINATING %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); + if (ftdmchan->state == FTDM_CHANNEL_STATE_UP || + ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA || + ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS) { + ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE UP -> Changed to TERMINATING %d:%d\n", event->span+1,event->chan+1); ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r); - } else if (ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) { - ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE HANGUP -> Changed to HANGUP COMPLETE %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, 0, r); + } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP || ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) { + ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE HANGUP -> Changed to HANGUP COMPLETE %d:%d\n", event->span+1,event->chan+1); + ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, 0, r); } else { - ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE INVALID %s on IN CALL %d:%d\n", ftdm_channel_state2str(ftdmchan->state),BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); + ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE INVALID %s on IN CALL %d:%d\n", ftdm_channel_state2str(ftdmchan->state),event->span+1,event->chan+1); } ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG); ftdmchan = NULL; @@ -1358,9 +1366,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) int call_stopped_ack_sent = 0; ftdm_sangoma_boost_data_t *sangoma_boost_data = ftdmchan->span->signal_data; - if (ftdm_test_sflag(ftdmchan, SFLAG_FREE_REQ_ID)) { - release_request_id_span_chan(ftdmchan->physical_span_id-1, ftdmchan->physical_chan_id-1); - } + release_request_id_span_chan(ftdmchan->physical_span_id-1, ftdmchan->physical_chan_id-1); if (!ftdm_test_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG)) { ftdm_set_sflag_locked(ftdmchan, SFLAG_SENT_FINAL_MSG); @@ -1912,6 +1918,21 @@ static int sigmod_ss7box_isup_exec_cmd(ftdm_stream_handle_t *stream, char *cmd) } #endif +static void ftdm_cli_span_state_cmd(ftdm_span_t *span, char *state) +{ + int j; + int cnt=0; + for(j = 1; j <= span->chan_count; j++) { + if (span->channels[j]->state != FTDM_CHANNEL_STATE_DOWN) { + ftdm_channel_t *ftdmchan = span->channels[j]; + ftdm_log(FTDM_LOG_CRIT, "Channel %i s%dc%d State=%s\n", + j,ftdmchan->physical_span_id-1,ftdmchan->physical_chan_id-1,ftdm_channel_state2str(ftdmchan->state)); + cnt++; + } + } + ftdm_log(FTDM_LOG_CRIT, "Total Channel Cnt %i\n",cnt); +} + #define FTDM_BOOST_SYNTAX "list sigmods | " /** * \brief API function to kill or debug a sangoma_boost span @@ -1966,27 +1987,42 @@ static FIO_API_FUNCTION(ftdm_sangoma_boost_api) goto done; #endif #endif - } else if (!strcasecmp(argv[0], "restart")) { + + } else if (!strcasecmp(argv[0], "span")) { sangomabc_connection_t *pcon; ftdm_sangoma_boost_data_t *sangoma_boost_data; ftdm_span_t *span; + + if (argc <= 2) { + stream->write_function(stream, "-ERR invalid span usage: span \n"); + goto done; + } + int err = ftdm_span_find_by_name(argv[1], &span); if (FTDM_SUCCESS != err) { stream->write_function(stream, "-ERR failed to find span by name %s\n",argv[1]); goto done; } - - sangoma_boost_data = span->signal_data; - pcon = &sangoma_boost_data->pcon; - /* No need to set any span flags because + if (!strcasecmp(argv[2], "restart")) { + sangoma_boost_data = span->signal_data; + pcon = &sangoma_boost_data->pcon; + + /* No need to set any span flags because our RESTART will generate a RESTART from the sig daemon */ - sangomabc_exec_commandp(pcon, + sangomabc_exec_commandp(pcon, 0, 0, -1, SIGBOOST_EVENT_SYSTEM_RESTART, - 0); + 0); + } else if (!strcasecmp(argv[2], "state")) { + if (argc <= 3) { + stream->write_function(stream, "-ERR invalid span state: span state \n"); + goto done; + } + ftdm_cli_span_state_cmd(span,argv[3]); + } goto done; @@ -1996,7 +2032,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_boost_api) if (sigmod_iface) { char *p = strchr(data, ' '); if (++p) { - char* mydup = ftdm_strdup(p); + char* mydup = strdup(p); if(sigmod_iface->exec_api == NULL) { stream->write_function(stream, "%s does not support api functions\n", sigmod_iface->name); goto done; @@ -2005,7 +2041,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_boost_api) if (sigmod_iface->exec_api(stream, mydup) != FTDM_SUCCESS) { stream->write_function(stream, "-ERR:failed to execute command:%s\n", mydup); } - ftdm_safe_free(mydup); + free(mydup); } goto done; diff --git a/libs/openzap/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c b/libs/openzap/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c index 995d943552..96321e2bda 100644 --- a/libs/openzap/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c +++ b/libs/openzap/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c @@ -344,6 +344,7 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request) if (sangomabc_connection_write(&sangoma_boost_data->mcon, &event) <= 0) { zap_log(ZAP_LOG_CRIT, "Failed to tx on ISUP socket [%s]\n", strerror(errno)); status = ZAP_FAIL; + OUTBOUND_REQUESTS[r].status = ZAP_FAIL; *zchan = NULL; goto done; } @@ -351,7 +352,7 @@ static ZIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request) while(zap_running() && OUTBOUND_REQUESTS[r].status == BST_WAITING) { zap_sleep(1); if (--sanity <= 0) { - status = ZAP_FAIL; + status = ZAP_FAIL; *zchan = NULL; goto done; } @@ -456,13 +457,18 @@ static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_ return; } - OUTBOUND_REQUESTS[event->call_setup_id].event = *event; - SETUP_GRID[event->span][event->chan] = event->call_setup_id; + if ((zchan = find_zchan(OUTBOUND_REQUESTS[event->call_setup_id].span, event, 0))) { if (zap_channel_open_chan(zchan) != ZAP_SUCCESS) { zap_log(ZAP_LOG_ERROR, "OPEN ERROR [%s]\n", zchan->last_error); } else { + + /* Only bind the setup id to GRID when we are sure that channel is ready + otherwise we could overwite the original call */ + OUTBOUND_REQUESTS[event->call_setup_id].event = *event; + SETUP_GRID[event->span][event->chan] = event->call_setup_id; + zap_set_flag(zchan, ZAP_CHANNEL_OUTBOUND); zap_set_flag_locked(zchan, ZAP_CHANNEL_INUSE); zchan->extra_id = event->call_setup_id; @@ -499,16 +505,20 @@ static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_ if (zchan->state == ZAP_CHANNEL_STATE_UP || zchan->state == ZAP_CHANNEL_STATE_PROGRESS_MEDIA || zchan->state == ZAP_CHANNEL_STATE_PROGRESS) { - zap_log(ZAP_LOG_CRIT, "ZCHAN STATE UP/PROG/PROG_MEDIA -> Changed to HANGUP %d:%d\n", event->span+1,event->chan+1); - zap_set_state_r(zchan, ZAP_CHANNEL_STATE_HANGUP, 0, r); + zap_log(ZAP_LOG_CRIT, "ZCHAN CALL ACK STATE %s -> Changed to HANGUP %d:%d\n", + zap_channel_state2str(zchan->state),event->span+1,event->chan+1); + zap_set_state_r(zchan, ZAP_CHANNEL_STATE_TERMINATING, 0, r); - } else if (zap_test_sflag(zchan, SFLAG_HANGUP)) { + } else if (zchan->state == ZAP_CHANNEL_STATE_HANGUP || zap_test_sflag(zchan, SFLAG_HANGUP)) { + zap_log(ZAP_LOG_CRIT, "ZCHAN CALL ACK STATE HANGUP -> Changed to HANGUP %d:%d\n", event->span+1,event->chan+1); + zap_set_state_r(zchan, ZAP_CHANNEL_STATE_HANGUP_COMPLETE, 0, r); /* Do nothing because outgoing STOP will generaate a stop ack */ } else { - zap_log(ZAP_LOG_CRIT, "ZCHAN STATE INVALID %s on IN CALL ACK %d:%d\n", zap_channel_state2str(zchan->state),event->span+1,event->chan+1); - + zap_log(ZAP_LOG_CRIT, "ZCHAN CALL ACK STATE INVALID %s s%dc%d\n", + zap_channel_state2str(zchan->state),event->span+1,event->chan+1); } + zap_set_sflag(zchan, SFLAG_SENT_FINAL_MSG); zchan=NULL; } } @@ -518,7 +528,10 @@ static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_ //printf("WTF BAD ACK2 %d:%d (%d:%d) CSid=%d xtra_id=%d out=%d state=%s\n", zchan->span_id, zchan->chan_id, event->span+1,event->chan+1, event->call_setup_id, zchan->extra_id, zap_test_flag(zchan, ZAP_CHANNEL_OUTBOUND), zap_channel_state2str(zchan->state)); } - zap_set_sflag(zchan, SFLAG_SENT_FINAL_MSG); + if (zchan) { + zap_set_sflag(zchan, SFLAG_SENT_FINAL_MSG); + } + zap_log(ZAP_LOG_CRIT, "START ACK CANT FIND A CHAN %d:%d\n", event->span+1,event->chan+1); sangomabc_exec_command(mcon, event->span, @@ -777,17 +790,24 @@ static void handle_call_start(zap_span_t *span, sangomabc_connection_t *mcon, sa then we are completely out of sync with the other end. Treat CALL START as CALL STOP and hangup the current call. */ - - if (zchan->state == ZAP_CHANNEL_STATE_UP) { - zap_log(ZAP_LOG_CRIT, "ZCHAN STATE UP -> Changed to TERMINATING %d:%d\n", event->span+1,event->chan+1); - zap_set_state_r(zchan, ZAP_CHANNEL_STATE_TERMINATING, 0, r); - } else if (zap_test_sflag(zchan, SFLAG_HANGUP)) { - zap_log(ZAP_LOG_CRIT, "ZCHAN STATE HANGUP -> Changed to HANGUP COMPLETE %d:%d\n", event->span+1,event->chan+1); - zap_set_state_r(zchan, ZAP_CHANNEL_STATE_HANGUP_COMPLETE, 0, r); - } else { - zap_log(ZAP_LOG_CRIT, "ZCHAN STATE INVALID %s on IN CALL %d:%d\n", zap_channel_state2str(zchan->state),event->span+1,event->chan+1); + if (zchan->state == ZAP_CHANNEL_STATE_UP || + zchan->state == ZAP_CHANNEL_STATE_PROGRESS_MEDIA || + zchan->state == ZAP_CHANNEL_STATE_PROGRESS) { + zap_log(ZAP_LOG_CRIT, "ZCHAN CALL STATE %s -> Changed to TERMINATING %d:%d\n", + zap_channel_state2str(zchan->state),event->span+1,event->chan+1); + zap_set_state_r(zchan, ZAP_CHANNEL_STATE_TERMINATING, 0, r); + + } else if (zchan->state == ZAP_CHANNEL_STATE_HANGUP || zap_test_sflag(zchan, SFLAG_HANGUP)) { + zap_log(ZAP_LOG_CRIT, "ZCHAN CALL STATE HANGUP -> Changed to HANGUP %d:%d\n", event->span+1,event->chan+1); + zap_set_state_r(zchan, ZAP_CHANNEL_STATE_HANGUP_COMPLETE, 0, r); + /* Do nothing because outgoing STOP will generaate a stop ack */ + + } else { + zap_log(ZAP_LOG_CRIT, "ZCHAN CALL ACK STATE INVALID %s s%dc%d\n", + zap_channel_state2str(zchan->state),event->span+1,event->chan+1); } + zap_set_sflag(zchan, SFLAG_SENT_FINAL_MSG); zchan=NULL; } From f772b05da8f60a60b71a89a4f19cd1294bf66d23 Mon Sep 17 00:00:00 2001 From: Nenad Corbic Date: Fri, 16 Apr 2010 18:28:15 -0400 Subject: [PATCH 15/62] openzap bug fix- try to remove id on down every time --- .../src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libs/openzap/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c b/libs/openzap/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c index 96321e2bda..c32878debd 100644 --- a/libs/openzap/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c +++ b/libs/openzap/src/ozmod/ozmod_sangoma_boost/ozmod_sangoma_boost.c @@ -1152,9 +1152,8 @@ static __inline__ void state_advance(zap_channel_t *zchan) switch (zchan->state) { case ZAP_CHANNEL_STATE_DOWN: { - if (zap_test_sflag(zchan, SFLAG_FREE_REQ_ID)) { - release_request_id_span_chan(zchan->physical_span_id-1, zchan->physical_chan_id-1); - } + /* Always try to clear the GRID */ + release_request_id_span_chan(zchan->physical_span_id-1, zchan->physical_chan_id-1); if (!zap_test_sflag(zchan, SFLAG_SENT_FINAL_MSG)) { zap_set_sflag_locked(zchan, SFLAG_SENT_FINAL_MSG); From 16d672a273d35940ab3416dd60327fdf68d58733 Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Sat, 17 Apr 2010 11:13:25 +0000 Subject: [PATCH 16/62] [1/3] gcc-4.5: Fix enum type mismatches in switch_core_sqldb.c. --- src/switch_core_sqldb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 0d6ac3d15e..530d700873 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -311,7 +311,7 @@ SWITCH_DECLARE(switch_status_t) _switch_cache_db_get_db_handle(switch_cache_db_h if ((odbc_dbh = switch_odbc_handle_new(connection_options->odbc_options.dsn, connection_options->odbc_options.user, connection_options->odbc_options.pass))) { - if (switch_odbc_handle_connect(odbc_dbh) != SWITCH_STATUS_SUCCESS) { + if (switch_odbc_handle_connect(odbc_dbh) != SWITCH_ODBC_SUCCESS) { switch_odbc_handle_destroy(&odbc_dbh); } } @@ -386,7 +386,7 @@ static switch_status_t switch_cache_db_execute_sql_real(switch_cache_db_handle_t case SCDB_TYPE_ODBC: { switch_odbc_statement_handle_t stmt = NULL; - if ((status = switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, sql, &stmt, NULL)) != SWITCH_ODBC_SUCCESS) { + if ((status = switch_odbc_handle_exec(dbh->native_handle.odbc_dbh, sql, &stmt, NULL)) != SWITCH_STATUS_SUCCESS) { errmsg = switch_odbc_handle_get_error(dbh->native_handle.odbc_dbh, stmt); } switch_odbc_statement_handle_free(&stmt); From 8f2b8388fc80fc62aa762a57e0d35614cca4ad8a Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Sat, 17 Apr 2010 11:17:28 +0000 Subject: [PATCH 17/62] [2/3][sofia-sip] gcc-4.5: Fix enum type mismatch. --- libs/sofia-sip/libsofia-sip-ua/sdp/sdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp.c b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp.c index 9ea45131a5..867ca7a79d 100644 --- a/libs/sofia-sip/libsofia-sip-ua/sdp/sdp.c +++ b/libs/sofia-sip/libsofia-sip-ua/sdp/sdp.c @@ -1469,7 +1469,7 @@ int sdp_media_cmp(sdp_media_t const *a, sdp_media_t const *b) if (a->m_proto != b->m_proto) return a->m_proto < b->m_proto ? -1 : 1; - if (a->m_proto == sdp_media_x) + if (a->m_proto == sdp_proto_x) if ((rv = su_strcmp(a->m_proto_name, b->m_proto_name))) return rv; From dc356af926cb4528289d4196540797918cc10cd2 Mon Sep 17 00:00:00 2001 From: Stefan Knoblich Date: Sat, 17 Apr 2010 11:17:48 +0000 Subject: [PATCH 18/62] [3/3][OpenZAP] gcc-4.5: Use zt_event_t instead of zap_oob_event_t to fix enum type mismatches. --- libs/openzap/src/ozmod/ozmod_zt/ozmod_zt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/openzap/src/ozmod/ozmod_zt/ozmod_zt.c b/libs/openzap/src/ozmod/ozmod_zt/ozmod_zt.c index 15803017b5..e1552a9b77 100644 --- a/libs/openzap/src/ozmod/ozmod_zt/ozmod_zt.c +++ b/libs/openzap/src/ozmod/ozmod_zt/ozmod_zt.c @@ -978,7 +978,7 @@ ZIO_SPAN_POLL_EVENT_FUNCTION(zt_poll_event) ZIO_SPAN_NEXT_EVENT_FUNCTION(zt_next_event) { uint32_t i, event_id = 0; - zap_oob_event_t zt_event_id = 0; + zt_event_t zt_event_id = 0; for(i = 1; i <= span->chan_count; i++) { if (zap_test_flag(span->channels[i], ZAP_CHANNEL_EVENT)) { From b5049a35d77e216b325750132ae1b5ff02121096 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Sat, 17 Apr 2010 15:05:48 +0200 Subject: [PATCH 19/62] debian: install mod_skinny Build tested on i386, amd64 and ppc. --- debian/freeswitch.conffiles | 1 + debian/freeswitch.install | 2 ++ debian/rules | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/debian/freeswitch.conffiles b/debian/freeswitch.conffiles index 7f06d05c00..40c6bf90ed 100644 --- a/debian/freeswitch.conffiles +++ b/debian/freeswitch.conffiles @@ -87,6 +87,7 @@ /opt/freeswitch/conf/sip_profiles/internal/example.xml /opt/freeswitch/conf/sip_profiles/internal-ipv6.xml /opt/freeswitch/conf/sip_profiles/internal.xml +/opt/freeswitch/conf/skinny_profiles/internal.xml /opt/freeswitch/conf/tetris.ttml /opt/freeswitch/conf/tones.conf /opt/freeswitch/conf/vars.xml diff --git a/debian/freeswitch.install b/debian/freeswitch.install index 421e2a2286..bb09e6843d 100644 --- a/debian/freeswitch.install +++ b/debian/freeswitch.install @@ -95,6 +95,7 @@ opt/freeswitch/conf/sip_profiles/external.xml opt/freeswitch/conf/sip_profiles/internal/example.xml opt/freeswitch/conf/sip_profiles/internal-ipv6.xml opt/freeswitch/conf/sip_profiles/internal.xml +opt/freeswitch/conf/skinny_profiles/internal.xml opt/freeswitch/conf/tetris.ttml opt/freeswitch/conf/tones.conf opt/freeswitch/conf/vars.xml @@ -139,6 +140,7 @@ opt/freeswitch/mod/mod_portaudio.so* opt/freeswitch/mod/mod_rss.so* opt/freeswitch/mod/mod_shout.so* opt/freeswitch/mod/mod_siren.so* +opt/freeswitch/mod/mod_skinny.so* opt/freeswitch/mod/mod_skypopen.so* opt/freeswitch/mod/mod_sndfile.so* opt/freeswitch/mod/mod_snom.so* diff --git a/debian/rules b/debian/rules index 409f6473ec..f2c57ea95a 100755 --- a/debian/rules +++ b/debian/rules @@ -20,7 +20,8 @@ export DIALPLANS_MODULES=dialplans/mod_dialplan_asterisk dialplans/mod_dialplan_ export DIRECTORIES_MODULES= export DOTNET_MODULES= export ENDPOINTS_MODULES=endpoints/mod_dingaling endpoints/mod_portaudio endpoints/mod_sofia \ - endpoints/mod_loopback ../../libs/openzap/mod_openzap endpoints/mod_skypopen + endpoints/mod_loopback ../../libs/openzap/mod_openzap endpoints/mod_skypopen \ + endpoints/mod_skinny export EVENT_HANDLERS_MODULES=event_handlers/mod_event_multicast event_handlers/mod_event_socket event_handlers/mod_cdr_csv export FORMATS_MODULES=formats/mod_local_stream formats/mod_native_file formats/mod_sndfile formats/mod_tone_stream formats/mod_shout export LANGUAGES_MODULES=languages/mod_spidermonkey languages/mod_perl languages/mod_lua From 3a53af901299eb71e0c296971d5ec1bf49c4e436 Mon Sep 17 00:00:00 2001 From: Rupa Schomaker Date: Sat, 17 Apr 2010 00:34:01 -0500 Subject: [PATCH 20/62] evesdrop - aquire/release db connection for channel query only --- src/mod/applications/mod_dptools/mod_dptools.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) mode change 100644 => 100755 src/mod/applications/mod_dptools/mod_dptools.c diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c old mode 100644 new mode 100755 index 9990871df3..fadb23eabc --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -358,16 +358,18 @@ SWITCH_STANDARD_APP(eavesdrop_function) char terminator; switch_status_t status; - if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Database Error!\n"); - } - while (switch_channel_ready(channel)) { for (x = 0; x < MAX_SPY; x++) { switch_safe_free(e_data.uuid_list[x]); } e_data.total = 0; + + if (switch_core_db_handle(&db) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Database Error!\n"); + break; + } switch_cache_db_execute_sql_callback(db, sql, e_callback, &e_data, &errmsg); + switch_cache_db_release_db_handle(&db); if (errmsg) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error: %s\n", errmsg); switch_core_db_free(errmsg); @@ -408,7 +410,6 @@ SWITCH_STANDARD_APP(eavesdrop_function) } free(sql); - switch_cache_db_release_db_handle(&db); } else { switch_ivr_eavesdrop_session(session, data, require_group, ED_DTMF); From 3e600fb968fbb697dcef204e148548bf2aa3d060 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Mon, 19 Apr 2010 11:51:13 -0400 Subject: [PATCH 21/62] freetdm: Windows compilation quirks --- .../ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index e916c403ab..65a929248a 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@ -1826,7 +1826,7 @@ static void *ftdm_sangoma_boost_run(ftdm_thread_t *me, void *obj) } if (ftdm_boost_connection_open(span) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_ERROR, "ftdm_boost_connection_open failed\n"); + ftdm_log(FTDM_LOG_CRIT, "ftdm_boost_connection_open failed\n"); goto end; } @@ -1870,10 +1870,6 @@ static void *ftdm_sangoma_boost_run(ftdm_thread_t *me, void *obj) check_state(span); } - goto end; - - ftdm_log(FTDM_LOG_CRIT, "Boost event processing Error!\n"); - end: if (!sangoma_boost_data->sigmod) { sangomabc_connection_close(&sangoma_boost_data->mcon); @@ -1920,7 +1916,7 @@ static int sigmod_ss7box_isup_exec_cmd(ftdm_stream_handle_t *stream, char *cmd) static void ftdm_cli_span_state_cmd(ftdm_span_t *span, char *state) { - int j; + unsigned j; int cnt=0; for(j = 1; j <= span->chan_count; j++) { if (span->channels[j]->state != FTDM_CHANNEL_STATE_DOWN) { @@ -1989,6 +1985,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_boost_api) #endif } else if (!strcasecmp(argv[0], "span")) { + int err; sangomabc_connection_t *pcon; ftdm_sangoma_boost_data_t *sangoma_boost_data; ftdm_span_t *span; @@ -1998,7 +1995,7 @@ static FIO_API_FUNCTION(ftdm_sangoma_boost_api) goto done; } - int err = ftdm_span_find_by_name(argv[1], &span); + err = ftdm_span_find_by_name(argv[1], &span); if (FTDM_SUCCESS != err) { stream->write_function(stream, "-ERR failed to find span by name %s\n",argv[1]); goto done; @@ -2446,7 +2443,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_boost_configure_span) ftdm_dso_lib_t lib = NULL; char path[255] = ""; char *err = NULL; - int j = 0; + unsigned int j = 0; unsigned paramindex = 0; ftdm_status_t rc = FTDM_SUCCESS; From ca9dfc3c5e3687357b467aecc72b903a7cdbeb8e Mon Sep 17 00:00:00 2001 From: Rupa Schomaker Date: Mon, 19 Apr 2010 13:17:33 -0500 Subject: [PATCH 22/62] nibblebill - free allocated memory at shutdown --- src/mod/applications/mod_nibblebill/mod_nibblebill.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) mode change 100644 => 100755 src/mod/applications/mod_nibblebill/mod_nibblebill.c diff --git a/src/mod/applications/mod_nibblebill/mod_nibblebill.c b/src/mod/applications/mod_nibblebill/mod_nibblebill.c old mode 100644 new mode 100755 index 78b7addf37..fe9a9ecf3e --- a/src/mod/applications/mod_nibblebill/mod_nibblebill.c +++ b/src/mod/applications/mod_nibblebill/mod_nibblebill.c @@ -964,6 +964,18 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_nibblebill_shutdown) switch_core_remove_state_handler(&nibble_state_handler); switch_odbc_handle_disconnect(globals.master_odbc); + switch_safe_free(globals.db_username); + switch_safe_free(globals.db_password); + switch_safe_free(globals.db_dsn); + switch_safe_free(globals.db_table); + switch_safe_free(globals.db_column_cash); + switch_safe_free(globals.db_column_account); + switch_safe_free(globals.custom_sql_save); + switch_safe_free(globals.custom_sql_lookup); + switch_safe_free(globals.percall_action); + switch_safe_free(globals.lowbal_action); + switch_safe_free(globals.nobal_action); + return SWITCH_STATUS_UNLOAD; } From 9a74958b22f2ae5566415cf131a76f450a3f6139 Mon Sep 17 00:00:00 2001 From: Rupa Schomaker Date: Mon, 19 Apr 2010 14:42:11 -0500 Subject: [PATCH 23/62] nibblebill - free properly if using custom_sql --- src/mod/applications/mod_nibblebill/mod_nibblebill.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mod/applications/mod_nibblebill/mod_nibblebill.c b/src/mod/applications/mod_nibblebill/mod_nibblebill.c index fe9a9ecf3e..093fbd4ef2 100755 --- a/src/mod/applications/mod_nibblebill/mod_nibblebill.c +++ b/src/mod/applications/mod_nibblebill/mod_nibblebill.c @@ -337,9 +337,10 @@ static switch_status_t bill_event(float billamount, const char *billaccount, swi switch_odbc_statement_handle_free(&stmt); end: - if (sql != globals.custom_sql_save) { + if (sql != globals.custom_sql_lookup && sql != sql_stream.data) { switch_safe_free(sql); } + switch_safe_free(sql_stream.data); return SWITCH_STATUS_SUCCESS; } @@ -385,9 +386,10 @@ static float get_balance(const char *billaccount, switch_channel_t *channel) } end: - if (sql != globals.custom_sql_lookup) { + if (sql != globals.custom_sql_lookup && sql != sql_stream.data) { switch_safe_free(sql); } + switch_safe_free(sql_stream.data); return balance; } From 70d73cafb757281b85661e7295adbd4802a3abe8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 19 Apr 2010 19:07:23 -0500 Subject: [PATCH 24/62] FSRTP-14 --- src/include/switch.h | 1 + src/include/switch_rtcp_frame.h | 74 ++++ src/include/switch_rtp.h | 17 + src/include/switch_types.h | 35 +- src/mod/endpoints/mod_sofia/mod_sofia.c | 45 +++ src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 4 + src/mod/endpoints/mod_sofia/sofia_glue.c | 9 + src/switch_event.c | 1 + src/switch_rtp.c | 454 +++++++++++++++++++++-- 10 files changed, 600 insertions(+), 41 deletions(-) create mode 100644 src/include/switch_rtcp_frame.h diff --git a/src/include/switch.h b/src/include/switch.h index 7e93646e29..2b007d2425 100644 --- a/src/include/switch.h +++ b/src/include/switch.h @@ -116,6 +116,7 @@ #include "switch_utils.h" #include "switch_caller.h" #include "switch_frame.h" +#include "switch_rtcp_frame.h" #include "switch_module_interfaces.h" #include "switch_channel.h" #include "switch_buffer.h" diff --git a/src/include/switch_rtcp_frame.h b/src/include/switch_rtcp_frame.h new file mode 100644 index 0000000000..1c718a089f --- /dev/null +++ b/src/include/switch_rtcp_frame.h @@ -0,0 +1,74 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2009, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Sherwin Sim + * + * + * switch_rtcp_frame.h -- RTCP Frame Structure + * + */ +/*! \file switch_rtcp_frame.h + \brief RTCP Frame Structure +*/ + +#ifndef SWITCH_RTCP_FRAME_H +#define SWITCH_RTCP_FRAME_H + +#include + +SWITCH_BEGIN_EXTERN_C +/*! \brief An abstraction of a rtcp frame */ + struct switch_rtcp_frame { + + uint16_t report_count; + + uint16_t packet_type; + + uint32_t ssrc; + + uint32_t ntp_msw; + + uint32_t ntp_lsw; + + uint32_t timestamp; + + uint32_t packet_count; + + uint32_t octect_count; + +}; + +SWITCH_END_EXTERN_C +#endif +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index e3098d0035..4ad264ae8e 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -41,6 +41,7 @@ SWITCH_BEGIN_EXTERN_C #define SWITCH_RTP_MAX_BUF_LEN 16384 +#define SWITCH_RTCP_MAX_BUF_LEN 16384 #define SWITCH_RTP_MAX_CRYPTO_LEN 64 #define SWITCH_RTP_KEY_LEN 30 #define SWITCH_RTP_CRYPTO_KEY_32 "AES_CM_128_HMAC_SHA1_32" @@ -213,6 +214,13 @@ SWITCH_DECLARE(void) switch_rtp_destroy(switch_rtp_t **rtp_session); */ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_session, char *login, char *rlogin); +/*! + \brief Activate sending RTCP Sender Reports (SR's) + \param send_rate interval in milliseconds to send at + \return SWITCH_STATUS_SUCCESS +*/ +SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate); + /*! \brief Acvite a jitter buffer on an RTP session \param rtp_session the rtp session @@ -347,6 +355,15 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read(switch_rtp_t *rtp_sessi */ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_frame_t *frame, switch_io_flag_t io_flags); + +/*! + \brief Read RTCP data from a given RTP session without copying + \param rtp_session the RTP session to read from + \param frame an RTCP frame to populate with information + \return the number of bytes read +*/ +SWITCH_DECLARE(switch_status_t) switch_rtcp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_rtcp_frame_t *frame); + SWITCH_DECLARE(void) rtp_flush_read_buffer(switch_rtp_t *rtp_session, switch_rtp_flush_t flush); /*! diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 3c624e922e..52f8ac1c24 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -534,7 +534,8 @@ typedef enum { SWITCH_ZRTP_FLAG_SECURE_MITM_RECV = (1 << 26), SWITCH_RTP_FLAG_DEBUG_RTP_READ = (1 << 27), SWITCH_RTP_FLAG_DEBUG_RTP_WRITE = (1 << 28), - SWITCH_RTP_FLAG_VIDEO = (1 << 29) + SWITCH_RTP_FLAG_VIDEO = (1 << 29), + SWITCH_RTP_FLAG_ENABLE_RTCP = (1 << 30) } switch_rtp_flag_enum_t; typedef uint32_t switch_rtp_flag_t; @@ -607,6 +608,35 @@ typedef struct { #pragma pack(pop, r1) #endif +#ifdef _MSC_VER +#pragma pack(push, r1, 1) +#endif + +#if SWITCH_BYTE_ORDER == __BIG_ENDIAN +typedef struct { + unsigned version:2; /* protocol version */ + unsigned p:1; /* padding flag */ + unsigned count:5; /* number of reception report blocks */ + unsigned type:8; /* packet type */ + unsigned length:16; /* length in 32-bit words - 1 */ +} switch_rtcp_hdr_t; + +#else /* BIG_ENDIAN */ + +typedef struct { + unsigned count:5; /* number of reception report blocks */ + unsigned p:1; /* padding flag */ + unsigned version:2; /* protocol version */ + unsigned type:8; /* packet type */ + unsigned length:16; /* length in 32-bit words - 1 */ +} switch_rtcp_hdr_t; + +#endif + +#ifdef _MSC_VER +#pragma pack(pop, r1) +#endif + /*! \enum switch_priority_t \brief Priority Indication @@ -1352,6 +1382,7 @@ typedef enum { SWITCH_EVENT_SERVER_DISCONNECTED, SWITCH_EVENT_SEND_INFO, SWITCH_EVENT_RECV_INFO, + SWITCH_EVENT_RECV_RTCP_MESSAGE, SWITCH_EVENT_CALL_SECURE, SWITCH_EVENT_NAT, SWITCH_EVENT_RECORD_START, @@ -1472,6 +1503,7 @@ typedef uint16_t switch_port_t; typedef uint8_t switch_payload_t; typedef struct switch_app_log switch_app_log_t; typedef struct switch_rtp switch_rtp_t; +typedef struct switch_rtcp switch_rtcp_t; typedef struct switch_core_session_message switch_core_session_message_t; typedef struct switch_event_header switch_event_header_t; typedef struct switch_event switch_event_t; @@ -1479,6 +1511,7 @@ typedef struct switch_event_subclass switch_event_subclass_t; typedef struct switch_event_node switch_event_node_t; typedef struct switch_loadable_module switch_loadable_module_t; typedef struct switch_frame switch_frame_t; +typedef struct switch_rtcp_frame switch_rtcp_frame_t; typedef struct switch_channel switch_channel_t; typedef struct switch_file_handle switch_file_handle_t; typedef struct switch_core_session switch_core_session_t; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 32512b4544..77510d4570 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -802,6 +802,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f switch_channel_t *channel = switch_core_session_get_channel(session); int payload = 0; uint32_t sanity = 1000; + switch_rtcp_frame_t rtcp_frame; switch_assert(tech_pvt != NULL); @@ -859,6 +860,50 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f } return status; } + + /* Try to read an RTCP frame, if successful raise an event */ + if (switch_rtcp_zerocopy_read_frame(tech_pvt->rtp_session, &rtcp_frame) == SWITCH_STATUS_SUCCESS) { + switch_event_t *event; + + if (switch_event_create(&event, SWITCH_EVENT_RECV_RTCP_MESSAGE) == SWITCH_STATUS_SUCCESS) { + char buf[30]; + + char* uuid = switch_core_session_get_uuid(session); + if (uuid) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Unique-ID", switch_core_session_get_uuid(session)); + } + + snprintf(buf, sizeof(buf), "%.8x", rtcp_frame.ssrc); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "SSRC", buf); + + snprintf(buf, sizeof(buf), "%u", rtcp_frame.ntp_msw); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "NTP-Most-Significant-Word", buf); + + snprintf(buf, sizeof(buf), "%u", rtcp_frame.ntp_lsw); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "NTP-Least-Significant-Word", buf); + + snprintf(buf, sizeof(buf), "%u", rtcp_frame.timestamp); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "RTP-Timestamp", buf); + + snprintf(buf, sizeof(buf), "%u", rtcp_frame.packet_count); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Sender-Packet-Count", buf); + + snprintf(buf, sizeof(buf), "%u", rtcp_frame.octect_count); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Octect-Packet-Count", buf); + + snprintf(buf, sizeof(buf), "%lu", tech_pvt->read_frame.timestamp); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Last-RTP-Timestamp", buf); + + snprintf(buf, sizeof(buf), "%u", tech_pvt->read_frame.rate); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "RTP-Rate", buf); + + snprintf(buf, sizeof(buf), "%lu", switch_time_now()); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Capture-Time", buf); + + switch_event_fire(&event); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG10, "Dispatched RTCP event\n"); + } + } /* Fast PASS! */ if (switch_test_flag((&tech_pvt->read_frame), SFF_PROXY_PACKET)) { diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index c03da5f648..ebf669028f 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -466,6 +466,7 @@ struct sofia_profile { char *record_path; char *presence_hosts; char *challenge_realm; + char *rtcp_interval_msec; sofia_cid_type_t cid_type; sofia_dtmf_t dtmf_type; int auto_restart; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 6d21074516..71faa4e782 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2459,6 +2459,8 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) profile->hold_music = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "outbound-proxy")) { profile->outbound_proxy = switch_core_strdup(profile->pool, val); + } else if (!strcasecmp(var, "rtcp-interval-msec")) { + profile->rtcp_interval_msec = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "session-timeout")) { int v_session_timeout = atoi(val); if (v_session_timeout >= 0) { @@ -2996,6 +2998,8 @@ switch_status_t config_sofia(int reload, char *profile_name) profile->hold_music = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "outbound-proxy")) { profile->outbound_proxy = switch_core_strdup(profile->pool, val); + } else if (!strcasecmp(var, "rtcp-interval-msec")) { + profile->rtcp_interval_msec = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "session-timeout")) { int v_session_timeout = atoi(val); if (v_session_timeout >= 0) { diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 782e62dd90..1143fda5f0 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2725,6 +2725,15 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f switch_rtp_activate_stun_ping(tech_pvt->rtp_session, tech_pvt->stun_ip, tech_pvt->stun_port, stun_ping, (tech_pvt->stun_flags & STUN_FLAG_FUNNY) ? 1 : 0); } + + if ((val = switch_channel_get_variable(tech_pvt->channel, "rtcp_interval_msec")) || (val = tech_pvt->profile->rtcp_interval_msec)) { + int interval = atoi(val); + if (interval < 100 || interval > 5000) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval); + } else { + switch_rtp_activate_rtcp(tech_pvt->rtp_session, interval); + } + } if ((val = switch_channel_get_variable(tech_pvt->channel, "jitterbuffer_msec"))) { int len = atoi(val); diff --git a/src/switch_event.c b/src/switch_event.c index b65c7b1371..00a08fba1b 100644 --- a/src/switch_event.c +++ b/src/switch_event.c @@ -180,6 +180,7 @@ static char *EVENT_NAMES[] = { "SERVER_DISCONNECTED", "SEND_INFO", "RECV_INFO", + "RECV_RTCP_MESSAGE", "CALL_SECURE", "NAT", "RECORD_START", diff --git a/src/switch_rtp.c b/src/switch_rtp.c index fc929e8f74..101c721484 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -89,6 +89,11 @@ typedef struct { char body[SWITCH_RTP_MAX_BUF_LEN]; } rtp_msg_t; +typedef struct { + switch_rtcp_hdr_t header; + char body[SWITCH_RTCP_MAX_BUF_LEN]; +} rtcp_msg_t; + struct switch_rtp_vad_data { switch_core_session_t *session; switch_codec_t vad_codec; @@ -137,16 +142,17 @@ struct switch_rtp { * families are equal, sock_input == sock_output and only one socket is * used. */ - switch_socket_t *sock_input, *sock_output; - switch_pollfd_t *read_pollfd; + switch_socket_t *sock_input, *sock_output, *rtcp_sock_input, *rtcp_sock_output; + switch_pollfd_t *read_pollfd, *rtcp_read_pollfd; switch_pollfd_t *jb_pollfd; - switch_sockaddr_t *local_addr; + switch_sockaddr_t *local_addr, *rtcp_local_addr; rtp_msg_t send_msg; + rtcp_msg_t rtcp_send_msg; - switch_sockaddr_t *remote_addr; + switch_sockaddr_t *remote_addr, *rtcp_remote_addr; rtp_msg_t recv_msg; - + rtcp_msg_t rtcp_recv_msg; switch_sockaddr_t *remote_stun_addr; @@ -173,12 +179,13 @@ struct switch_rtp { switch_time_t last_write_timestamp; uint32_t flags; switch_memory_pool_t *pool; - switch_sockaddr_t *from_addr; + switch_sockaddr_t *from_addr, *rtcp_from_addr; char *rx_host; switch_port_t rx_port; char *ice_user; char *user_ice; char *timer_name; + char *local_host_str; char *remote_host_str; switch_time_t last_stun; uint32_t samples_per_interval; @@ -186,6 +193,7 @@ struct switch_rtp { uint32_t conf_samples_per_interval; uint32_t rsamples_per_interval; uint32_t ms_per_packet; + switch_port_t local_port; switch_port_t remote_port; uint32_t stuncount; uint32_t funny_stun; @@ -216,6 +224,8 @@ struct switch_rtp { switch_rtp_stats_t stats; uint32_t hot_hits; uint32_t sync_packets; + int rtcp_interval; + switch_bool_t rtcp_fresh_frame; #ifdef ENABLE_ZRTP zrtp_session_t *zrtp_session; @@ -225,10 +235,16 @@ struct switch_rtp { int zinit; #endif -#ifdef RTP_DEBUG_WRITE_DELTA switch_time_t send_time; -#endif +}; +struct switch_rtcp_senderinfo { + unsigned ssrc:32; + unsigned ntp_msw:32; + unsigned ntp_lsw:32; + unsigned ts:32; + unsigned pc:32; + unsigned oc:32; }; static int global_init = 0; @@ -284,7 +300,7 @@ static switch_status_t do_stun_ping(switch_rtp_t *rtp_session) switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_stun_addr, 0, (void *) packet, &bytes); rtp_session->stuncount = rtp_session->default_stuncount; - end: + end: WRITE_DEC(rtp_session); return status; @@ -324,7 +340,7 @@ static switch_status_t ice_out(switch_rtp_t *rtp_session) switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_addr, 0, (void *) packet, &bytes); rtp_session->stuncount = rtp_session->default_stuncount; - end: + end: WRITE_DEC(rtp_session); return status; @@ -410,7 +426,7 @@ static void handle_ice(switch_rtp_t *rtp_session, void *data, switch_size_t len) switch_socket_sendto(rtp_session->sock_output, rtp_session->from_addr, 0, (void *) rpacket, &bytes); } - end: + end: READ_DEC(rtp_session); WRITE_DEC(rtp_session); @@ -750,6 +766,104 @@ SWITCH_DECLARE(void) switch_rtp_intentional_bugs(switch_rtp_t *rtp_session, swit rtp_session->rtp_bugs = bugs; } + +static switch_status_t enable_remote_rtcp_socket(switch_rtp_t *rtp_session, const char **err) { + + switch_status_t status = SWITCH_STATUS_SUCCESS; + + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { + + rtp_session->rtcp_remote_addr = rtp_session->remote_addr; + + if (switch_sockaddr_info_get(&rtp_session->rtcp_remote_addr, rtp_session->remote_host_str, SWITCH_UNSPEC, + rtp_session->remote_port + 1, 0, rtp_session->pool) != SWITCH_STATUS_SUCCESS || !rtp_session->rtcp_remote_addr) { + *err = "RTCP Remote Address Error!"; + return SWITCH_STATUS_FALSE; + } + + if (rtp_session->rtcp_sock_input && switch_sockaddr_get_family(rtp_session->rtcp_remote_addr) == + switch_sockaddr_get_family(rtp_session->rtcp_local_addr)) { + rtp_session->rtcp_sock_output = rtp_session->rtcp_sock_input; + } else { + if (rtp_session->rtcp_sock_output && rtp_session->rtcp_sock_output != rtp_session->rtcp_sock_input) { + switch_socket_close(rtp_session->rtcp_sock_output); + } + if ((status = switch_socket_create(&rtp_session->rtcp_sock_output, + switch_sockaddr_get_family(rtp_session->rtcp_remote_addr), + SOCK_DGRAM, 0, rtp_session->pool)) != SWITCH_STATUS_SUCCESS) { + *err = "RTCP Socket Error!"; + } + } + } else { + *err = "RTCP NOT ACTIVE!"; + } + + return status; + +} + +static switch_status_t enable_local_rtcp_socket(switch_rtp_t *rtp_session, const char **err) { + + const char *host = rtp_session->local_host_str; + switch_port_t port = rtp_session->local_port; + switch_socket_t *rtcp_new_sock = NULL, *rtcp_old_sock = NULL; + switch_status_t status = SWITCH_STATUS_SUCCESS; + char bufa[30]; + + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { + if (switch_sockaddr_info_get(&rtp_session->rtcp_local_addr, host, SWITCH_UNSPEC, port+1, 0, rtp_session->pool) != SWITCH_STATUS_SUCCESS) { + *err = "RTCP Local Address Error!"; + goto done; + } + + if (switch_socket_create(&rtcp_new_sock, switch_sockaddr_get_family(rtp_session->rtcp_local_addr), SOCK_DGRAM, 0, rtp_session->pool) != SWITCH_STATUS_SUCCESS) { + *err = "RTCP Socket Error!"; + goto done; + } + + if (switch_socket_opt_set(rtcp_new_sock, SWITCH_SO_REUSEADDR, 1) != SWITCH_STATUS_SUCCESS) { + *err = "RTCP Socket Error!"; + goto done; + } + + if (switch_socket_bind(rtcp_new_sock, rtp_session->rtcp_local_addr) != SWITCH_STATUS_SUCCESS) { + *err = "RTCP Bind Error!"; + goto done; + } + + if (switch_sockaddr_info_get(&rtp_session->rtcp_from_addr, switch_get_addr(bufa, sizeof(bufa), rtp_session->from_addr), + SWITCH_UNSPEC, switch_sockaddr_get_port(rtp_session->from_addr) + 1, 0, rtp_session->pool) != SWITCH_STATUS_SUCCESS) { + *err = "RTCP From Address Error!"; + goto done; + } + + rtcp_old_sock = rtp_session->rtcp_sock_input; + rtp_session->rtcp_sock_input = rtcp_new_sock; + rtcp_new_sock = NULL; + + switch_socket_create_pollset(&rtp_session->rtcp_read_pollfd, rtp_session->rtcp_sock_input, SWITCH_POLLIN | SWITCH_POLLERR, rtp_session->pool); + + done: + + if (*err) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error allocating rtcp [%s]\n", *err); + status = SWITCH_STATUS_FALSE; + } + + if (rtcp_new_sock) { + switch_socket_close(rtcp_new_sock); + } + + if (rtcp_old_sock) { + switch_socket_close(rtcp_old_sock); + } + } else { + status = SWITCH_STATUS_FALSE; + } + + return status; +} + SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, const char **err) { switch_socket_t *new_sock = NULL, *old_sock = NULL; @@ -781,11 +895,17 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s goto done; } + + rtp_session->local_host_str = switch_core_strdup(rtp_session->pool, host); + rtp_session->local_port = port; + + if (switch_sockaddr_info_get(&rtp_session->local_addr, host, SWITCH_UNSPEC, port, 0, rtp_session->pool) != SWITCH_STATUS_SUCCESS) { *err = "Local Address Error!"; goto done; } + if (rtp_session->sock_input) { switch_rtp_kill_socket(rtp_session); } @@ -799,11 +919,12 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s *err = "Socket Error!"; goto done; } - + if (switch_socket_bind(new_sock, rtp_session->local_addr) != SWITCH_STATUS_SUCCESS) { *err = "Bind Error!"; goto done; } + #ifndef WIN32 len = sizeof(i); switch_socket_opt_set(new_sock, SWITCH_SO_NONBLOCK, TRUE); @@ -827,12 +948,15 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s } switch_socket_opt_set(new_sock, SWITCH_SO_NONBLOCK, FALSE); -#endif old_sock = rtp_session->sock_input; rtp_session->sock_input = new_sock; new_sock = NULL; + +#endif + + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER) || switch_test_flag(rtp_session, SWITCH_RTP_FLAG_NOBLOCK)) { switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, TRUE); switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_NOBLOCK); @@ -840,11 +964,18 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s switch_socket_create_pollset(&rtp_session->read_pollfd, rtp_session->sock_input, SWITCH_POLLIN | SWITCH_POLLERR, rtp_session->pool); - status = SWITCH_STATUS_SUCCESS; - *err = "Success"; + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { + if ((status = enable_local_rtcp_socket(rtp_session, err)) == SWITCH_STATUS_SUCCESS) { + *err = "Success"; + } + } else { + status = SWITCH_STATUS_SUCCESS; + *err = "Success"; + } + switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_IO); - done: + done: if (new_sock) { switch_socket_close(new_sock); @@ -854,6 +985,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_local_address(switch_rtp_t *rtp_s switch_socket_close(old_sock); } + if (rtp_session->ready != 1) { WRITE_DEC(rtp_session); READ_DEC(rtp_session); @@ -901,6 +1033,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_ return SWITCH_STATUS_FALSE; } + switch_mutex_lock(rtp_session->write_mutex); rtp_session->remote_addr = remote_addr; @@ -923,6 +1056,10 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_ } } + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { + status = enable_remote_rtcp_socket(rtp_session, err); + } + switch_mutex_unlock(rtp_session->write_mutex); return status; @@ -985,8 +1122,11 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess policy->next = NULL; policy->key = (uint8_t *) crypto_key->key; - crypto_policy_set_rtcp_default(&policy->rtcp); - policy->rtcp.sec_serv = sec_serv_none; + + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { + crypto_policy_set_rtcp_default(&policy->rtcp); + policy->rtcp.sec_serv = sec_serv_none; + } policy->rtp.sec_serv = sec_serv_conf_and_auth; switch (direction) { @@ -1136,8 +1276,9 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session /* for from address on recvfrom calls */ switch_sockaddr_info_get(&rtp_session->from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool); - - + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { + switch_sockaddr_info_get(&rtp_session->rtcp_from_addr, NULL, SWITCH_UNSPEC, 0, 0, pool); + } rtp_session->seq = (uint16_t) rand(); rtp_session->ssrc = (uint32_t) ((intptr_t) rtp_session + (uint32_t) switch_epoch_time_now(NULL)); @@ -1162,6 +1303,14 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session rtp_session->payload = payload; + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { + rtp_session->rtcp_send_msg.header.version = 2; + rtp_session->rtcp_send_msg.header.p = 0; + rtp_session->rtcp_send_msg.header.type = 200; + rtp_session->rtcp_send_msg.header.count = 0; + rtp_session->rtcp_send_msg.header.length = htons(6); + } + switch_rtp_set_interval(rtp_session, ms_per_packet, samples_per_interval); rtp_session->conf_samples_per_interval = samples_per_interval; @@ -1257,7 +1406,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session } } - end: + end: #endif @@ -1316,7 +1465,7 @@ SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(const char *rx_host, goto end; } - end: + end: if (rtp_session) { switch_mutex_unlock(rtp_session->flag_mutex); @@ -1382,6 +1531,19 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t * return SWITCH_STATUS_SUCCESS; } +SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate) +{ + const char *err = NULL; + + switch_set_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "RTCP send rate is: %d and packet rate is: %d\n", send_rate, rtp_session->ms_per_packet); + rtp_session->rtcp_interval = send_rate/(rtp_session->ms_per_packet/1000); + + return enable_local_rtcp_socket(rtp_session, &err) || enable_remote_rtcp_socket(rtp_session, &err); + +} + SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_session, char *login, char *rlogin) { char ice_user[80]; @@ -1407,6 +1569,10 @@ static void ping_socket(switch_rtp_t *rtp_session) uint32_t o = UINT_MAX; switch_size_t len = sizeof(o); switch_socket_sendto(rtp_session->sock_input, rtp_session->local_addr, 0, (void *) &o, &len); + + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && rtp_session->rtcp_sock_input) { + switch_socket_sendto(rtp_session->rtcp_sock_input, rtp_session->rtcp_local_addr, 0, (void *) &o, &len); + } } SWITCH_DECLARE(void) switch_rtp_break(switch_rtp_t *rtp_session) @@ -1443,6 +1609,16 @@ SWITCH_DECLARE(void) switch_rtp_kill_socket(switch_rtp_t *rtp_session) if (rtp_session->sock_output && rtp_session->sock_output != rtp_session->sock_input) { switch_socket_shutdown(rtp_session->sock_output, SWITCH_SHUTDOWN_READWRITE); } + + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { + if (rtp_session->rtcp_sock_input) { + ping_socket(rtp_session); + switch_socket_shutdown(rtp_session->rtcp_sock_input, SWITCH_SHUTDOWN_READWRITE); + } + if (rtp_session->rtcp_sock_output && rtp_session->rtcp_sock_output != rtp_session->rtcp_sock_input) { + switch_socket_shutdown(rtp_session->rtcp_sock_output, SWITCH_SHUTDOWN_READWRITE); + } + } } switch_mutex_unlock(rtp_session->flag_mutex); } @@ -1746,7 +1922,7 @@ static void do_flush(switch_rtp_t *rtp_session) } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CONSOLE, "%s FLUSH\n", switch_channel_get_name(switch_core_session_get_channel(session)) - ); + ); } } @@ -1841,18 +2017,126 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t return status; } +static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes, switch_frame_flag_t *flags) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + + if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { + return SWITCH_STATUS_FALSE; + } + + switch_assert(bytes); + + *bytes = sizeof(rtcp_msg_t); + if ((status = switch_socket_recvfrom(rtp_session->rtcp_from_addr, rtp_session->rtcp_sock_input, 0, (void *) &rtp_session->rtcp_recv_msg, bytes)) + != SWITCH_STATUS_SUCCESS) { + *bytes = 0; + } + + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_RECV)) { + int sbytes = (int) *bytes; + err_status_t stat = 0; + + stat = srtp_unprotect_rtcp(rtp_session->recv_ctx, &rtp_session->rtcp_recv_msg.header, &sbytes); + + if (stat) { + if (++rtp_session->srtp_errs >= MAX_SRTP_ERRS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Error: SRTP RTCP unprotect failed with code %d%s\n", stat, + stat == err_status_replay_fail ? " (replay check failed)" : stat == + err_status_auth_fail ? " (auth check failed)" : ""); + return SWITCH_STATUS_FALSE; + } else { + sbytes = 0; + } + } else { + rtp_session->srtp_errs = 0; + } + + *bytes = sbytes; + + } + + +#ifdef ENABLE_ZRTP + /* ZRTP Recv */ + if (bytes) { + unsigned int sbytes = (int) bytes; + zrtp_status_t stat = 0; + + stat = zrtp_process_srtcp(rtp_session->zrtp_stream, (void *) &rtp_session->rtcp_recv_msg, &sbytes); + + switch (stat) { + case zrtp_status_ok: + bytes = sbytes; + break; + case zrtp_status_drop: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection drop with code %d\n", stat); + bytes = 0; + goto do_continue; + case zrtp_status_fail: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection fail with code %d\n", stat); + ret = -1; + goto end; + default: + break; + } + } +#endif + + + if (*bytes) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,"Received an RTCP packet of length %lu bytes\n", *bytes); + if (rtp_session->rtcp_recv_msg.header.version == 2) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,"RTCP packet type is %d\n", rtp_session->rtcp_recv_msg.header.type); + if (rtp_session->rtcp_recv_msg.header.type == 200) { + struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session->rtcp_recv_msg.body; + + rtp_session->rtcp_fresh_frame = 1; + + /* sender report */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,"Received a SR with %d report blocks, " \ + "length in words = %d, " \ + "SSRC = 0x%X, " \ + "NTP MSW = %u, " \ + "NTP LSW = %u, " \ + "RTP timestamp = %u, " \ + "Sender Packet Count = %u, " \ + "Sender Octet Count = %u\n", + rtp_session->rtcp_recv_msg.header.count, + ntohs(rtp_session->rtcp_recv_msg.header.length), + ntohl(sr->ssrc), + ntohl(sr->ntp_msw), + ntohl(sr->ntp_lsw), + ntohl(sr->ts), + ntohl(sr->pc), + ntohl(sr->oc)); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Received an unsupported RTCP packet version %d\nn", rtp_session->rtcp_recv_msg.header.version); + } + + status = SWITCH_STATUS_SUCCESS; + } + + return status; +} + static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_type, switch_frame_flag_t *flags, switch_io_flag_t io_flags) { switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session"); switch_channel_t *channel = NULL; switch_size_t bytes = 0; + switch_size_t rtcp_bytes = 0; switch_status_t status = SWITCH_STATUS_SUCCESS, poll_status = SWITCH_STATUS_SUCCESS; + switch_status_t rtcp_status = SWITCH_STATUS_SUCCESS, rtcp_poll_status = SWITCH_STATUS_SUCCESS; int check = 0; int ret = -1; int sleep_mss = 1000; int poll_sec = 5; int poll_loop = 0; int fdr = 0; + int rtcp_fdr = 0; int hot_socket = 0; if (session) { @@ -1904,7 +2188,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } } - recvfrom: + recvfrom: bytes = 0; if (!switch_rtp_ready(rtp_session)) { @@ -1946,6 +2230,14 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ return_cng_frame(); } } + + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && rtp_session->rtcp_read_pollfd) { + rtcp_poll_status = switch_poll(rtp_session->rtcp_read_pollfd, 1, &rtcp_fdr, 0); + + if (rtcp_poll_status == SWITCH_STATUS_SUCCESS) { + rtcp_status = read_rtcp_packet(rtp_session, &rtcp_bytes, flags); + } + } if (bytes < 0) { ret = (int) bytes; @@ -2210,7 +2502,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ We know the real rules here, but if we enforce them, it's an interop nightmare so, we put up with as much as we can so we don't have to deal with being punished for doing it right. Nice guys finish last! - */ + */ if (bytes && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833) && rtp_session->recv_msg.header.pt == rtp_session->recv_te) { switch_size_t len = bytes - rtp_header_len; @@ -2324,7 +2616,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ return_cng_frame(); } - timer_check: + timer_check: if (do_cng) { uint8_t *data = (uint8_t *) rtp_session->recv_msg.body; @@ -2371,7 +2663,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ break; - do_continue: + do_continue: if (!bytes && !rtp_session->timer.interval) { switch_yield(sleep_mss); @@ -2391,7 +2683,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ ret = -1; } - end: + end: READ_DEC(rtp_session); @@ -2513,6 +2805,33 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_read(switch_rtp_t *rtp_session, void return SWITCH_STATUS_SUCCESS; } +SWITCH_DECLARE(switch_status_t) switch_rtcp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_rtcp_frame_t *frame) +{ + + if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { + return SWITCH_STATUS_FALSE; + } + + /* A fresh frame has been found! */ + if (rtp_session->rtcp_fresh_frame) { + struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session->rtcp_recv_msg.body; + /* turn the flag off! */ + rtp_session->rtcp_fresh_frame = 0; + + frame->ssrc = ntohl(sr->ssrc); + frame->packet_type = rtp_session->rtcp_recv_msg.header.type; + frame->ntp_msw = ntohl(sr->ntp_msw); + frame->ntp_lsw = ntohl(sr->ntp_lsw); + frame->timestamp = ntohl(sr->ts); + frame->packet_count = ntohl(sr->pc); + frame->octect_count = ntohl(sr->oc); + + return SWITCH_STATUS_SUCCESS; + } + + return SWITCH_STATUS_TIMEOUT; +} + SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp_session, switch_frame_t *frame, switch_io_flag_t io_flags) { int bytes = 0; @@ -2625,10 +2944,11 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read(switch_rtp_t *rtp_sessi static int rtp_common_write(switch_rtp_t *rtp_session, rtp_msg_t *send_msg, void *data, uint32_t datalen, switch_payload_t payload, uint32_t timestamp, switch_frame_flag_t *flags) { - switch_size_t bytes; + switch_size_t bytes, rtcp_bytes; uint8_t send = 1; uint32_t this_ts = 0; int ret; + switch_time_t now; if (!switch_rtp_ready(rtp_session)) { return SWITCH_STATUS_FALSE; @@ -2860,15 +3180,14 @@ static int rtp_common_write(switch_rtp_t *rtp_session, } #endif + now = switch_time_now(); #ifdef RTP_DEBUG_WRITE_DELTA { - switch_time_t now = switch_time_now(); int delta = (int) (now - rtp_session->send_time) / 1000; printf("WRITE %d delta %d\n", (int) bytes, delta); - rtp_session->send_time = now; } #endif - + rtp_session->send_time = now; if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_DEBUG_RTP_WRITE)) { switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session"); @@ -2924,6 +3243,61 @@ static int rtp_common_write(switch_rtp_t *rtp_session, } rtp_session->last_write_ts = this_ts; + + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && + rtp_session->rtcp_interval && (rtp_session->stats.outbound.packet_count % rtp_session->rtcp_interval) == 0) { + struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session->rtcp_send_msg.body; + + sr->ssrc = send_msg->header.ssrc; + sr->ntp_msw = htonl(rtp_session->send_time / 1000000 + 2208988800UL); + sr->ntp_lsw = htonl(rtp_session->send_time % 1000000 * ((UINT_MAX * 1.0)/ 1000000.0)); + sr->ts = send_msg->header.ts; + sr->pc = htonl(rtp_session->stats.outbound.packet_count); + sr->oc = htonl((rtp_session->stats.outbound.raw_bytes - rtp_session->stats.outbound.packet_count * sizeof(srtp_hdr_t))); + + rtcp_bytes = sizeof(switch_rtcp_hdr_t) + sizeof(struct switch_rtcp_senderinfo); + + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_SECURE_SEND)) { + int sbytes = (int) rtcp_bytes; + int stat = srtp_protect_rtcp(rtp_session->send_ctx, &rtp_session->rtcp_send_msg.header, &sbytes); + if (stat) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: SRTP RTCP protection failed with code %d\n", stat); + } + rtcp_bytes = sbytes; + } + +#ifdef ENABLE_ZRTP + /* ZRTP Send */ + if (1) { + unsigned int sbytes = (int) bytes; + zrtp_status_t stat = zrtp_status_fail; + + stat = zrtp_process_rtcp(rtp_session->zrtp_stream, (void *) &rtp_session->rtcp_send_msg, &sbytes); + + switch (stat) { + case zrtp_status_ok: + break; + case zrtp_status_drop: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection drop with code %d\n", stat); + ret = (int) bytes; + goto end; + break; + case zrtp_status_fail: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection fail with code %d\n", stat); + break; + default: + break; + } + + bytes = sbytes; + } +#endif + + if (switch_socket_sendto(rtp_session->rtcp_sock_output, rtp_session->rtcp_remote_addr, 0, + (const char*)&rtp_session->rtcp_send_msg, &rtcp_bytes ) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"RTCP packet not written\n"); + } + } } if (rtp_session->remote_stun_addr) { @@ -2939,7 +3313,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session, ret = (int) bytes; - end: + end: WRITE_DEC(rtp_session); @@ -3031,9 +3405,9 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra send_msg = frame->packet; /* - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { - send_msg->header.pt = rtp_session->payload; - } + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { + send_msg->header.pt = rtp_session->payload; + } */ if (switch_socket_sendto(rtp_session->sock_output, rtp_session->remote_addr, 0, frame->packet, &bytes) != SWITCH_STATUS_SUCCESS) { @@ -3131,9 +3505,9 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra } /* - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { - send_msg->header.pt = rtp_session->payload; - } + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VIDEO)) { + send_msg->header.pt = rtp_session->payload; + } */ return rtp_common_write(rtp_session, send_msg, data, len, payload, ts, &frame->flags); @@ -3234,7 +3608,7 @@ SWITCH_DECLARE(int) switch_rtp_write_manual(switch_rtp_t *rtp_session, ret = (int) bytes; - end: + end: WRITE_DEC(rtp_session); From 9e152e0f74bf811c51b34016ea120602e2ae9da0 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 19 Apr 2010 19:08:22 -0500 Subject: [PATCH 25/62] MODENDP-302 --- .../endpoints/mod_portaudio/mod_portaudio.c | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/mod/endpoints/mod_portaudio/mod_portaudio.c b/src/mod/endpoints/mod_portaudio/mod_portaudio.c index 0fe7f0bdcc..b2778d4f80 100644 --- a/src/mod/endpoints/mod_portaudio/mod_portaudio.c +++ b/src/mod/endpoints/mod_portaudio/mod_portaudio.c @@ -181,6 +181,17 @@ SWITCH_STANDARD_API(pa_cmd); static switch_status_t channel_on_init(switch_core_session_t *session) { switch_channel_t *channel = switch_core_session_get_channel(session); + + /* Move channel's state machine to ROUTING */ + switch_channel_set_state(channel, CS_ROUTING); + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t channel_on_routing(switch_core_session_t *session) +{ + + switch_channel_t *channel = switch_core_session_get_channel(session); private_t *tech_pvt = switch_core_session_get_private(session); switch_time_t last; int waitsec = globals.ring_interval * 1000000; @@ -201,12 +212,8 @@ static switch_status_t channel_on_init(switch_core_session_t *session) if (hold_file) { tech_pvt->hold_file = switch_core_session_strdup(session, hold_file); } - + if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { - - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL INIT %d %d\n", - switch_channel_get_name(channel), switch_channel_get_state(channel), switch_test_flag(tech_pvt, TFLAG_ANSWER)); - if (engage_device(0) != SWITCH_STATUS_SUCCESS) { switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); return SWITCH_STATUS_FALSE; @@ -309,14 +316,7 @@ static switch_status_t channel_on_init(switch_core_session_t *session) switch_set_flag_locked(tech_pvt, TFLAG_IO); - /* Move channel's state machine to ROUTING */ - switch_channel_set_state(channel, CS_ROUTING); - return SWITCH_STATUS_SUCCESS; -} - -static switch_status_t channel_on_routing(switch_core_session_t *session) -{ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s CHANNEL ROUTING\n", switch_channel_get_name(switch_core_session_get_channel(session))); return SWITCH_STATUS_SUCCESS; From 9d198c5012521342a5c8d504a77a5781020fcbf0 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 20 Apr 2010 11:08:25 -0500 Subject: [PATCH 26/62] config option for rtcp on profile --- conf/sip_profiles/internal.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/conf/sip_profiles/internal.xml b/conf/sip_profiles/internal.xml index eda248626e..dcce589013 100644 --- a/conf/sip_profiles/internal.xml +++ b/conf/sip_profiles/internal.xml @@ -207,6 +207,10 @@ + + + + From f1e07625db5985b77410934f334a909ba4259b0d Mon Sep 17 00:00:00 2001 From: Rupa Schomaker Date: Tue, 20 Apr 2010 12:11:07 -0500 Subject: [PATCH 27/62] %lu -> SWITCH_SIZE_T_FMT --- src/switch_rtp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 101c721484..0cacc3bded 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -2086,7 +2086,7 @@ static switch_status_t read_rtcp_packet(switch_rtp_t *rtp_session, switch_size_t if (*bytes) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,"Received an RTCP packet of length %lu bytes\n", *bytes); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,"Received an RTCP packet of length %" SWITCH_SIZE_T_FMT " bytes\n", *bytes); if (rtp_session->rtcp_recv_msg.header.version == 2) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10,"RTCP packet type is %d\n", rtp_session->rtcp_recv_msg.header.type); if (rtp_session->rtcp_recv_msg.header.type == 200) { From 995c4277dad7f35c9955c4a978c5a38a7e034f6a Mon Sep 17 00:00:00 2001 From: Rupa Schomaker Date: Tue, 20 Apr 2010 12:21:46 -0500 Subject: [PATCH 28/62] more %lu->SWITCH_SIZE_T_FMT --- src/mod/endpoints/mod_sofia/mod_sofia.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 77510d4570..1f289499dd 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -891,13 +891,13 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f snprintf(buf, sizeof(buf), "%u", rtcp_frame.octect_count); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Octect-Packet-Count", buf); - snprintf(buf, sizeof(buf), "%lu", tech_pvt->read_frame.timestamp); + snprintf(buf, sizeof(buf), "%" SWITCH_SIZE_T_FMT, tech_pvt->read_frame.timestamp); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Last-RTP-Timestamp", buf); snprintf(buf, sizeof(buf), "%u", tech_pvt->read_frame.rate); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "RTP-Rate", buf); - snprintf(buf, sizeof(buf), "%lu", switch_time_now()); + snprintf(buf, sizeof(buf), "%" SWITCH_SIZE_T_FMT, switch_time_now()); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Capture-Time", buf); switch_event_fire(&event); From 03703293f453d16263a7819a4199c36016c62a5d Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 20 Apr 2010 12:20:41 -0500 Subject: [PATCH 29/62] fix ignore --- .gitignore | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.gitignore b/.gitignore index 41b0907f48..6d5559cd0b 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,18 @@ configure.lineno /scripts/gentls_cert /a.out.dSYM /freeswitch-sounds-* +src/mod/applications/mod_easyroute/Makefile +src/mod/applications/mod_lcr/Makefile +src/mod/applications/mod_nibblebill/Makefile +src/mod/applications/mod_rss/Makefile +src/mod/applications/mod_snipe_hunt/Makefile +src/mod/codecs/mod_dahdi_codec/Makefile +src/mod/dialplans/mod_dialplan_directory/Makefile +src/mod/formats/mod_shell_stream/Makefile +src/mod/say/mod_say_de/Makefile +src/mod/say/mod_say_es/Makefile +src/mod/say/mod_say_fr/Makefile +src/mod/say/mod_say_it/Makefile +src/mod/say/mod_say_nl/Makefile +src/mod/say/mod_say_th/Makefile +src/mod/say/mod_say_zh/Makefile From 517a822b500a2076d0fc78e80854ce96112f2510 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 20 Apr 2010 12:27:38 -0500 Subject: [PATCH 30/62] ignore more --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 6d5559cd0b..d5dd7326a4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.lo *.a *.la +*.loT .libs .deps .\#* From 150e1f48056014ae2fa98e375fe92a2f1e1749c4 Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 20 Apr 2010 12:28:04 -0500 Subject: [PATCH 31/62] ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d5dd7326a4..3b82069a68 100644 --- a/.gitignore +++ b/.gitignore @@ -86,3 +86,4 @@ src/mod/say/mod_say_it/Makefile src/mod/say/mod_say_nl/Makefile src/mod/say/mod_say_th/Makefile src/mod/say/mod_say_zh/Makefile +libs/curl/lib/ca-bundle.h From b9ddf2c3adfe8028adf4f65cec3cb37be4364aeb Mon Sep 17 00:00:00 2001 From: Rupa Schomaker Date: Tue, 20 Apr 2010 12:33:10 -0500 Subject: [PATCH 32/62] oops, SWITCH_TIME_T_FMT instead --- src/mod/endpoints/mod_sofia/mod_sofia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 1f289499dd..7790c776ca 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -897,7 +897,7 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f snprintf(buf, sizeof(buf), "%u", tech_pvt->read_frame.rate); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "RTP-Rate", buf); - snprintf(buf, sizeof(buf), "%" SWITCH_SIZE_T_FMT, switch_time_now()); + snprintf(buf, sizeof(buf), "%" SWITCH_TIME_T_FMT, switch_time_now()); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Capture-Time", buf); switch_event_fire(&event); From a3629654a265fbac62fd2ed040865a80c50fcd5e Mon Sep 17 00:00:00 2001 From: Brian West Date: Tue, 20 Apr 2010 13:34:51 -0500 Subject: [PATCH 33/62] use correct header prefix var --- src/mod/endpoints/mod_sofia/mod_sofia.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 7790c776ca..1930454ebc 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -657,7 +657,7 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session) } if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) { - char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_PROGRESS_HEADER_PREFIX); + char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_RESPONSE_HEADER_PREFIX); if (sofia_use_soa(tech_pvt)) { nua_respond(tech_pvt->nh, SIP_200_OK, NUTAG_AUTOANSWER(0), From 9fd1b828135a70fe888f58c7c9c66a196c680618 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Tue, 20 Apr 2010 22:39:20 +0200 Subject: [PATCH 34/62] Skinny: prepare config for skinny-patterns dialplan --- conf/dialplan/skinny-patterns.xml | 30 +++++++++++++++++++ conf/dialplan/skinny-patterns/20-Demo.xml | 8 +++++ .../skinny-patterns/20-Local_extension.xml | 8 +++++ conf/dialplan/skinny-patterns/90-External.xml | 8 +++++ .../skinny-patterns/99-Default_Drop.xml | 9 ++++++ conf/skinny_profiles/internal.xml | 2 ++ 6 files changed, 65 insertions(+) create mode 100644 conf/dialplan/skinny-patterns.xml create mode 100644 conf/dialplan/skinny-patterns/20-Demo.xml create mode 100644 conf/dialplan/skinny-patterns/20-Local_extension.xml create mode 100644 conf/dialplan/skinny-patterns/90-External.xml create mode 100644 conf/dialplan/skinny-patterns/99-Default_Drop.xml diff --git a/conf/dialplan/skinny-patterns.xml b/conf/dialplan/skinny-patterns.xml new file mode 100644 index 0000000000..a78b83bdc7 --- /dev/null +++ b/conf/dialplan/skinny-patterns.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + diff --git a/conf/dialplan/skinny-patterns/20-Demo.xml b/conf/dialplan/skinny-patterns/20-Demo.xml new file mode 100644 index 0000000000..0246fe29a4 --- /dev/null +++ b/conf/dialplan/skinny-patterns/20-Demo.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/conf/dialplan/skinny-patterns/20-Local_extension.xml b/conf/dialplan/skinny-patterns/20-Local_extension.xml new file mode 100644 index 0000000000..488d740790 --- /dev/null +++ b/conf/dialplan/skinny-patterns/20-Local_extension.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/conf/dialplan/skinny-patterns/90-External.xml b/conf/dialplan/skinny-patterns/90-External.xml new file mode 100644 index 0000000000..706bf74027 --- /dev/null +++ b/conf/dialplan/skinny-patterns/90-External.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/conf/dialplan/skinny-patterns/99-Default_Drop.xml b/conf/dialplan/skinny-patterns/99-Default_Drop.xml new file mode 100644 index 0000000000..897fd8fb94 --- /dev/null +++ b/conf/dialplan/skinny-patterns/99-Default_Drop.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/conf/skinny_profiles/internal.xml b/conf/skinny_profiles/internal.xml index e9b08133d3..eaa493c047 100644 --- a/conf/skinny_profiles/internal.xml +++ b/conf/skinny_profiles/internal.xml @@ -3,6 +3,8 @@ + + From dcb9c0ca5285c24973f1022a07f8bf695841eee4 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Tue, 20 Apr 2010 22:40:21 +0200 Subject: [PATCH 35/62] Skinny: Initial patterns dialplan implementation. More info on mod_skinny wiki page --- src/mod/endpoints/mod_skinny/mod_skinny.c | 50 +++++--- src/mod/endpoints/mod_skinny/mod_skinny.h | 8 ++ .../endpoints/mod_skinny/skinny_protocol.c | 114 +++++++++++++++--- 3 files changed, 142 insertions(+), 30 deletions(-) diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.c b/src/mod/endpoints/mod_skinny/mod_skinny.c index a90df113d8..5b780d3700 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.c +++ b/src/mod/endpoints/mod_skinny/mod_skinny.c @@ -107,21 +107,23 @@ switch_status_t skinny_profile_dump(const skinny_profile_t *profile, switch_stre switch_assert(profile); stream->write_function(stream, "%s\n", line); /* prefs */ - stream->write_function(stream, "Name \t%s\n", profile->name); - stream->write_function(stream, "Domain Name \t%s\n", profile->domain); - stream->write_function(stream, "IP \t%s\n", profile->ip); - stream->write_function(stream, "Port \t%d\n", profile->port); - stream->write_function(stream, "Dialplan \t%s\n", profile->dialplan); - stream->write_function(stream, "Context \t%s\n", profile->context); - stream->write_function(stream, "Keep-Alive \t%d\n", profile->keep_alive); - stream->write_function(stream, "Date-Format \t%s\n", profile->date_format); - stream->write_function(stream, "DBName \t%s\n", profile->dbname ? profile->dbname : switch_str_nil(profile->odbc_dsn)); - stream->write_function(stream, "Debug \t%d\n", profile->debug); + stream->write_function(stream, "Name \t%s\n", profile->name); + stream->write_function(stream, "Domain Name \t%s\n", profile->domain); + stream->write_function(stream, "IP \t%s\n", profile->ip); + stream->write_function(stream, "Port \t%d\n", profile->port); + stream->write_function(stream, "Dialplan \t%s\n", profile->dialplan); + stream->write_function(stream, "Context \t%s\n", profile->context); + stream->write_function(stream, "Patterns-Dialplan \t%s\n", profile->patterns_dialplan); + stream->write_function(stream, "Patterns-Context \t%s\n", profile->patterns_context); + stream->write_function(stream, "Keep-Alive \t%d\n", profile->keep_alive); + stream->write_function(stream, "Date-Format \t%s\n", profile->date_format); + stream->write_function(stream, "DBName \t%s\n", profile->dbname ? profile->dbname : switch_str_nil(profile->odbc_dsn)); + stream->write_function(stream, "Debug \t%d\n", profile->debug); /* stats */ - stream->write_function(stream, "CALLS-IN \t%d\n", profile->ib_calls); - stream->write_function(stream, "FAILED-CALLS-IN \t%d\n", profile->ib_failed_calls); - stream->write_function(stream, "CALLS-OUT \t%d\n", profile->ob_calls); - stream->write_function(stream, "FAILED-CALLS-OUT \t%d\n", profile->ob_failed_calls); + stream->write_function(stream, "CALLS-IN \t%d\n", profile->ib_calls); + stream->write_function(stream, "FAILED-CALLS-IN \t%d\n", profile->ib_failed_calls); + stream->write_function(stream, "CALLS-OUT \t%d\n", profile->ob_calls); + stream->write_function(stream, "FAILED-CALLS-OUT \t%d\n", profile->ob_failed_calls); /* listener */ stream->write_function(stream, "Listener-Threads \t%d\n", profile->listener_threads); stream->write_function(stream, "%s\n", line); @@ -1429,6 +1431,10 @@ static void skinny_profile_set(skinny_profile_t *profile, char *var, char *val) profile->dialplan = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "context")) { profile->context = switch_core_strdup(profile->pool, val); + } else if (!strcasecmp(var, "patterns-dialplan")) { + profile->patterns_dialplan = switch_core_strdup(profile->pool, val); + } else if (!strcasecmp(var, "patterns-context")) { + profile->patterns_context = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "date-format")) { strncpy(profile->date_format, val, 6); } else if (!strcasecmp(var, "odbc-dsn") && !zstr(val)) { @@ -1499,6 +1505,10 @@ static switch_status_t load_skinny_config(void) skinny_profile_set(profile, "dialplan", val); } else if (!strcmp(var, "context")) { skinny_profile_set(profile, "context", val); + } else if (!strcmp(var, "patterns-dialplan")) { + skinny_profile_set(profile, "patterns-dialplan", val); + } else if (!strcmp(var, "patterns-context")) { + skinny_profile_set(profile, "patterns-context", val); } else if (!strcmp(var, "keep-alive")) { profile->keep_alive = atoi(val); } else if (!strcmp(var, "date-format")) { @@ -1511,11 +1521,19 @@ static switch_status_t load_skinny_config(void) } /* param */ if (!profile->dialplan) { - skinny_profile_set(profile, "dialplan","default"); + skinny_profile_set(profile, "dialplan","XML"); } if (!profile->context) { - skinny_profile_set(profile, "context","public"); + skinny_profile_set(profile, "context","default"); + } + + if (!profile->patterns_dialplan) { + skinny_profile_set(profile, "patterns-dialplan","XML"); + } + + if (!profile->patterns_context) { + skinny_profile_set(profile, "patterns-context","skinny-patterns"); } if (profile->port == 0) { diff --git a/src/mod/endpoints/mod_skinny/mod_skinny.h b/src/mod/endpoints/mod_skinny/mod_skinny.h index d8728510a6..314e29ba73 100644 --- a/src/mod/endpoints/mod_skinny/mod_skinny.h +++ b/src/mod/endpoints/mod_skinny/mod_skinny.h @@ -64,6 +64,8 @@ struct skinny_profile { unsigned int port; char *dialplan; char *context; + char *patterns_dialplan; + char *patterns_context; uint32_t keep_alive; char date_format[6]; int debug; @@ -99,6 +101,12 @@ struct skinny_device_type_params { }; typedef struct skinny_device_type_params skinny_device_type_params_t; +typedef enum { + SKINNY_ACTION_ROUTE, + SKINNY_ACTION_DROP, + SKINNY_ACTION_WAIT +} skinny_action_t; + /*****************************************************************************/ /* LISTENERS TYPES */ /*****************************************************************************/ diff --git a/src/mod/endpoints/mod_skinny/skinny_protocol.c b/src/mod/endpoints/mod_skinny/skinny_protocol.c index 261ef98789..7acede0da5 100644 --- a/src/mod/endpoints/mod_skinny/skinny_protocol.c +++ b/src/mod/endpoints/mod_skinny/skinny_protocol.c @@ -500,12 +500,13 @@ switch_status_t skinny_create_ingoing_session(listener_t *listener, uint32_t *li "Error Locking Session\n"); goto error; } + /* First create the caller profile in the patterns Dialplan */ if (!(tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(nsession), - NULL, listener->profile->dialplan, + NULL, listener->profile->patterns_dialplan, button->shortname, button->name, listener->remote_ip, NULL, NULL, NULL, "skinny" /* modname */, - listener->profile->context, + listener->profile->patterns_context, "")) != 0) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(nsession), SWITCH_LOG_CRIT, "Error Creating Session caller profile\n"); @@ -548,6 +549,75 @@ done: return SWITCH_STATUS_SUCCESS; } +skinny_action_t skinny_session_dest_match_pattern(switch_core_session_t *session, char **data) +{ + skinny_action_t action = SKINNY_ACTION_DROP; + switch_channel_t *channel = NULL; + private_t *tech_pvt = NULL; + + switch_assert(session); + + channel = switch_core_session_get_channel(session); + tech_pvt = switch_core_session_get_private(session); + + /* this part of the code is similar to switch_core_standard_on_routing() */ + if (!zstr(tech_pvt->profile->patterns_dialplan)) { + switch_dialplan_interface_t *dialplan_interface = NULL; + switch_caller_extension_t *extension = NULL; + char *expanded = NULL; + char *dpstr = NULL; + char *dp[25]; + int argc, x; + + if ((dpstr = switch_core_session_strdup(session, tech_pvt->profile->patterns_dialplan))) { + expanded = switch_channel_expand_variables(channel, dpstr); + argc = switch_separate_string(expanded, ',', dp, (sizeof(dp) / sizeof(dp[0]))); + for (x = 0; x < argc; x++) { + char *dpname = dp[x]; + char *dparg = NULL; + + if (dpname) { + if ((dparg = strchr(dpname, ':'))) { + *dparg++ = '\0'; + } + } else { + continue; + } + if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(dpname))) { + continue; + } + + extension = dialplan_interface->hunt_function(session, dparg, NULL); + UNPROTECT_INTERFACE(dialplan_interface); + + if (extension) { + goto found; + } + } + } +found: + while (extension && extension->current_application) { + switch_caller_application_t *current_application = extension->current_application; + + extension->current_application = extension->current_application->next; + + if (!strcmp(current_application->application_name, "skinny-route")) { + action = SKINNY_ACTION_ROUTE; + } else if (!strcmp(current_application->application_name, "skinny-drop")) { + action = SKINNY_ACTION_DROP; + } else if (!strcmp(current_application->application_name, "skinny-wait")) { + action = SKINNY_ACTION_WAIT; + *data = switch_core_session_strdup(session, current_application->application_data); + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, + "Unknown skinny dialplan application %s\n", current_application->application_name); + } + } + } + return action; +} + + struct skinny_session_process_dest_helper { private_t *tech_pvt; listener_t *listener; @@ -597,8 +667,11 @@ int skinny_session_process_dest_callback(void *pArg, int argc, char **argv, char switch_status_t skinny_session_process_dest(switch_core_session_t *session, listener_t *listener, uint32_t line_instance, char *dest, char append_dest, uint32_t backspace) { + skinny_action_t action; switch_channel_t *channel = NULL; private_t *tech_pvt = NULL; + char *data = NULL; + struct skinny_session_process_dest_helper helper = {0}; switch_assert(session); switch_assert(listener); @@ -633,19 +706,32 @@ switch_status_t skinny_session_process_dest(switch_core_session_t *session, list tech_pvt->caller_profile->destination_number = switch_core_strdup(tech_pvt->caller_profile->pool, dest); } - /* TODO Number is complete -> check against dialplan */ - if ((strlen(tech_pvt->caller_profile->destination_number) >= 4) || dest) { - struct skinny_session_process_dest_helper helper = {0}; - send_dialed_number(listener, tech_pvt->caller_profile->destination_number, line_instance, tech_pvt->call_id); - skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_PROCEED); - skinny_send_call_info(session, listener, line_instance); + if(dest) { + action = SKINNY_ACTION_ROUTE; + } else { + action = skinny_session_dest_match_pattern(session, &data); + } + switch(action) { + case SKINNY_ACTION_ROUTE: + tech_pvt->caller_profile->dialplan = switch_core_strdup(tech_pvt->caller_profile->pool, listener->profile->dialplan); + tech_pvt->caller_profile->context = switch_core_strdup(tech_pvt->caller_profile->pool, listener->profile->context); + send_dialed_number(listener, tech_pvt->caller_profile->destination_number, line_instance, tech_pvt->call_id); + skinny_line_set_state(listener, line_instance, tech_pvt->call_id, SKINNY_PROCEED); + skinny_send_call_info(session, listener, line_instance); - skinny_session_start_media(session, listener, line_instance); - - helper.tech_pvt = tech_pvt; - helper.listener = listener; - helper.line_instance = line_instance; - skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), skinny_session_process_dest_callback, &helper); + skinny_session_start_media(session, listener, line_instance); + + helper.tech_pvt = tech_pvt; + helper.listener = listener; + helper.line_instance = line_instance; + skinny_session_walk_lines(tech_pvt->profile, switch_core_session_get_uuid(session), skinny_session_process_dest_callback, &helper); + break; + case SKINNY_ACTION_WAIT: + /* for now, wait forever */ + break; + case SKINNY_ACTION_DROP: + default: + switch_channel_hangup(channel, SWITCH_CAUSE_UNALLOCATED_NUMBER); } return SWITCH_STATUS_SUCCESS; From 8aebc016d070d00b4fdc04b4b07ed791145bfe5f Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Tue, 20 Apr 2010 17:05:47 -0400 Subject: [PATCH 36/62] freetdm:Bug fixes in freetdm queue mode freetdm:Added freetdm to compile/install list --- bootstrap.sh | 2 +- configure.in | 1 + .../ftmod_sangoma_boost/ftmod_sangoma_boost.c | 26 +++++++++++-------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 861ce6c918..4755bc75c5 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -4,7 +4,7 @@ echo "bootstrap: checking installation..." BASEDIR=`pwd`; LIBDIR=${BASEDIR}/libs; SUBDIRS="ilbc curl iksemel js js/nsprpub libdingaling libedit libsndfile pcre sofia-sip \ - speex sqlite srtp openzap spandsp libg722_1 portaudio unimrcp tiff-3.8.2 broadvoice silk"; + speex sqlite srtp openzap freetdm spandsp libg722_1 portaudio unimrcp tiff-3.8.2 broadvoice silk"; if [ ! -f modules.conf ]; then cp build/modules.conf.in modules.conf diff --git a/configure.in b/configure.in index 16ba3e6999..23ff3d5680 100644 --- a/configure.in +++ b/configure.in @@ -954,6 +954,7 @@ AC_CONFIG_SUBDIRS([libs/sofia-sip]) AC_CONFIG_SUBDIRS([libs/speex]) AC_CONFIG_SUBDIRS([libs/portaudio]) AC_CONFIG_SUBDIRS([libs/openzap]) +AC_CONFIG_SUBDIRS([libs/freetdm]) AC_CONFIG_SUBDIRS([libs/unimrcp]) AC_CONFIG_SUBDIRS([libs/tiff-3.8.2]) AC_CONFIG_SUBDIRS([libs/spandsp]) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index 65a929248a..af92ac6775 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@ -691,13 +691,13 @@ static void handle_call_start_ack(sangomabc_connection_t *mcon, sangomabc_short_ if (ftdmchan->state == FTDM_CHANNEL_STATE_UP || ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA || ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS) { - ftdm_log(FTDM_LOG_CRIT, "ZCHAN CALL ACK STATE UP -> Changed to TERMINATING %d:%d\n", event->span+1,event->chan+1); + ftdm_log(FTDM_LOG_CRIT, "FTDMCHAN CALL ACK STATE UP -> Changed to TERMINATING %d:%d\n", event->span+1,event->chan+1); ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r); } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP || ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) { - ftdm_log(FTDM_LOG_CRIT, "ZCHAN CALL ACK STATE HANGUP -> Changed to HANGUP COMPLETE %d:%d\n", event->span+1,event->chan+1); + ftdm_log(FTDM_LOG_CRIT, "FTDMCHAN CALL ACK STATE HANGUP -> Changed to HANGUP COMPLETE %d:%d\n", event->span+1,event->chan+1); ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, 0, r); } else { - ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE INVALID State %s on IN CALL ACK %d:%d\n", + ftdm_log(FTDM_LOG_CRIT, "FTDMCHAN STATE INVALID State %s on IN CALL ACK %d:%d\n", ftdm_channel_state2str(ftdmchan->state),event->span+1,event->chan+1); } ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG); @@ -817,7 +817,9 @@ static void handle_call_start_nack(ftdm_span_t *span, sangomabc_connection_t *mc if (sangoma_boost_data->sigmod) { ftdmchan = OUTBOUND_REQUESTS[event->call_setup_id].ftdmchan; CALL_DATA(ftdmchan)->last_event_id = event->event_id; + CALL_DATA(ftdmchan)->call_setup_id = event->call_setup_id; ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); + ftdm_clear_sflag_locked(ftdmchan, SFLAG_SENT_FINAL_MSG); } else { sangomabc_exec_command(mcon, 0, @@ -859,7 +861,7 @@ static void handle_call_start_nack(ftdm_span_t *span, sangomabc_connection_t *mc sangomabc_exec_command(mcon, event->span, event->chan, - 0, + event->call_setup_id, SIGBOOST_EVENT_CALL_START_NACK_ACK, 0, 0); } @@ -1004,23 +1006,25 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s if (ftdmchan->state == FTDM_CHANNEL_STATE_UP || ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS_MEDIA || ftdmchan->state == FTDM_CHANNEL_STATE_PROGRESS) { - ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE UP -> Changed to TERMINATING %d:%d\n", event->span+1,event->chan+1); + ftdm_log(FTDM_LOG_CRIT, "s%dc%d:FTDMCHAN STATE UP -> Changed to TERMINATING\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r); } else if (ftdmchan->state == FTDM_CHANNEL_STATE_HANGUP || ftdm_test_sflag(ftdmchan, SFLAG_HANGUP)) { - ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE HANGUP -> Changed to HANGUP COMPLETE %d:%d\n", event->span+1,event->chan+1); + ftdm_log(FTDM_LOG_CRIT, "s%dc%d:FTDMCHAN STATE HANGUP -> Changed to HANGUP COMPLETE\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, 0, r); + } else if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { + ftdm_log(FTDM_LOG_WARNING, "s%dc%d:Collision, hanging up incoming call\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); } else { - ftdm_log(FTDM_LOG_CRIT, "ZCHAN STATE INVALID %s on IN CALL %d:%d\n", ftdm_channel_state2str(ftdmchan->state),event->span+1,event->chan+1); + ftdm_log(FTDM_LOG_CRIT, "s%dc%d:FTDMCHAN STATE INVALID %s on IN CALL\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event), ftdm_channel_state2str(ftdmchan->state)); } ftdm_set_sflag(ftdmchan, SFLAG_SENT_FINAL_MSG); ftdmchan = NULL; } - ftdm_log(FTDM_LOG_CRIT, "START CANT FIND CHAN %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); + ftdm_log(FTDM_LOG_CRIT, "s%dc%d:START CANT FIND CHAN\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); goto error; } if (ftdm_channel_open_chan(ftdmchan) != FTDM_SUCCESS) { - ftdm_log(FTDM_LOG_CRIT, "START CANT OPEN CHAN %d:%d\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); + ftdm_log(FTDM_LOG_CRIT, "s%dc%d:START CANT OPEN CHAN\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); goto error; } @@ -1074,7 +1078,7 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s sangomabc_exec_command(mcon, event->span, event->chan, - 0, + event->call_setup_id, SIGBOOST_EVENT_CALL_START_NACK, hangup_cause, 0); @@ -1375,7 +1379,7 @@ static __inline__ void state_advance(ftdm_channel_t *ftdmchan) sangomabc_exec_command(mcon, BOOST_SPAN(ftdmchan), BOOST_CHAN(ftdmchan), - 0, + CALL_DATA(ftdmchan)->call_setup_id, SIGBOOST_EVENT_CALL_START_NACK_ACK, 0, 0); From aa4816659ce4c04c3bae368a0ced9d0ef9e156bf Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 20 Apr 2010 16:15:37 -0500 Subject: [PATCH 37/62] add rtcp seperate on audio and video and add passthru --- conf/sip_profiles/internal.xml | 5 +- src/include/switch_rtp.h | 2 +- src/include/switch_types.h | 4 +- src/mod/endpoints/mod_sofia/mod_sofia.h | 3 +- src/mod/endpoints/mod_sofia/sofia.c | 12 ++- src/mod/endpoints/mod_sofia/sofia_glue.c | 53 ++++++++++-- src/switch_rtp.c | 105 +++++++++++++++++++---- 7 files changed, 154 insertions(+), 30 deletions(-) diff --git a/conf/sip_profiles/internal.xml b/conf/sip_profiles/internal.xml index dcce589013..2f5636e5a6 100644 --- a/conf/sip_profiles/internal.xml +++ b/conf/sip_profiles/internal.xml @@ -208,8 +208,9 @@ - - + + + diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index 4ad264ae8e..c4bab48190 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -219,7 +219,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_ice(switch_rtp_t *rtp_sessio \param send_rate interval in milliseconds to send at \return SWITCH_STATUS_SUCCESS */ -SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate); +SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port); /*! \brief Acvite a jitter buffer on an RTP session diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 52f8ac1c24..2589e2b8c3 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -535,7 +535,9 @@ typedef enum { SWITCH_RTP_FLAG_DEBUG_RTP_READ = (1 << 27), SWITCH_RTP_FLAG_DEBUG_RTP_WRITE = (1 << 28), SWITCH_RTP_FLAG_VIDEO = (1 << 29), - SWITCH_RTP_FLAG_ENABLE_RTCP = (1 << 30) + SWITCH_RTP_FLAG_ENABLE_RTCP = (1 << 30), + SWITCH_RTP_FLAG_RTCP_PASSTHRU = (1 << 31) + /* don't add any more 31 is the limit! gotta chnge to an array to add more */ } switch_rtp_flag_enum_t; typedef uint32_t switch_rtp_flag_t; diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index ebf669028f..e1b1e61d53 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -466,7 +466,8 @@ struct sofia_profile { char *record_path; char *presence_hosts; char *challenge_realm; - char *rtcp_interval_msec; + char *rtcp_audio_interval_msec; + char *rtcp_video_interval_msec; sofia_cid_type_t cid_type; sofia_dtmf_t dtmf_type; int auto_restart; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 71faa4e782..89940a8cd7 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2459,8 +2459,10 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) profile->hold_music = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "outbound-proxy")) { profile->outbound_proxy = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "rtcp-interval-msec")) { - profile->rtcp_interval_msec = switch_core_strdup(profile->pool, val); + } else if (!strcasecmp(var, "rtcp-audio-interval-msec")) { + profile->rtcp_audio_interval_msec = switch_core_strdup(profile->pool, val); + } else if (!strcasecmp(var, "rtcp-video-interval-msec")) { + profile->rtcp_video_interval_msec = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "session-timeout")) { int v_session_timeout = atoi(val); if (v_session_timeout >= 0) { @@ -2998,8 +3000,10 @@ switch_status_t config_sofia(int reload, char *profile_name) profile->hold_music = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "outbound-proxy")) { profile->outbound_proxy = switch_core_strdup(profile->pool, val); - } else if (!strcasecmp(var, "rtcp-interval-msec")) { - profile->rtcp_interval_msec = switch_core_strdup(profile->pool, val); + } else if (!strcasecmp(var, "rtcp-audio-interval-msec")) { + profile->rtcp_audio_interval_msec = switch_core_strdup(profile->pool, val); + } else if (!strcasecmp(var, "rtcp-video-interval-msec")) { + profile->rtcp_video_interval_msec = switch_core_strdup(profile->pool, val); } else if (!strcasecmp(var, "session-timeout")) { int v_session_timeout = atoi(val); if (v_session_timeout >= 0) { diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 1143fda5f0..49b302b7ff 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -691,7 +691,7 @@ const char *sofia_glue_get_unknown_header(sip_t const *sip, const char *name) switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int force) { char *lookup_rtpip = tech_pvt->profile->rtpip; /* Pointer to externally looked up address */ - switch_port_t sdp_port; /* The external port to be sent in the SDP */ + switch_port_t sdp_port, rtcp_port; /* The external port to be sent in the SDP */ const char *use_ip = NULL; /* The external IP to be sent in the SDP */ /* Don't do anything if we're in proxy mode or if a (remote) port already has been found */ @@ -734,6 +734,7 @@ switch_status_t sofia_glue_tech_choose_port(private_object_t *tech_pvt, int forc if (!zstr(tech_pvt->remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->remote_ip)) { /* Yes, map the port through switch_nat */ switch_nat_add_mapping(tech_pvt->local_sdp_audio_port, SWITCH_NAT_UDP, &sdp_port, SWITCH_FALSE); + switch_nat_add_mapping(tech_pvt->local_sdp_audio_port + 1, SWITCH_NAT_UDP, &rtcp_port, SWITCH_FALSE); } else { /* No NAT detected */ use_ip = tech_pvt->profile->rtpip; @@ -2726,12 +2727,23 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f (tech_pvt->stun_flags & STUN_FLAG_FUNNY) ? 1 : 0); } - if ((val = switch_channel_get_variable(tech_pvt->channel, "rtcp_interval_msec")) || (val = tech_pvt->profile->rtcp_interval_msec)) { - int interval = atoi(val); - if (interval < 100 || interval > 5000) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval); + printf("WTF [%s][%s]\n", switch_channel_get_variable(tech_pvt->channel, "rtcp_audio_interval_msec"), tech_pvt->profile->rtcp_audio_interval_msec); + + if ((val = switch_channel_get_variable(tech_pvt->channel, "rtcp_audio_interval_msec")) || (val = tech_pvt->profile->rtcp_audio_interval_msec)) { + const char *rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port"); + switch_port_t remote_port = 0; + if (rport) { + remote_port = atoi(rport); + } + if (!strcasecmp(val, "passthru")) { + switch_rtp_activate_rtcp(tech_pvt->rtp_session, -1, remote_port); } else { - switch_rtp_activate_rtcp(tech_pvt->rtp_session, interval); + int interval = atoi(val); + if (interval < 100 || interval > 5000) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval); + } else { + switch_rtp_activate_rtcp(tech_pvt->rtp_session, interval, remote_port); + } } } @@ -2949,6 +2961,27 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f switch_channel_set_variable_printf(tech_pvt->channel, "sip_use_video_pt", "%d", tech_pvt->video_agreed_pt); tech_pvt->video_ssrc = switch_rtp_get_ssrc(tech_pvt->rtp_session); switch_channel_set_variable_printf(tech_pvt->channel, "rtp_use_video_ssrc", "%u", tech_pvt->ssrc); + + + if ((val = switch_channel_get_variable(tech_pvt->channel, "rtcp_audio_interval_msec")) || (val = tech_pvt->profile->rtcp_audio_interval_msec)) { + const char *rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"); + switch_port_t remote_port = 0; + if (rport) { + remote_port = atoi(rport); + } + if (!strcasecmp(val, "passthru")) { + switch_rtp_activate_rtcp(tech_pvt->rtp_session, -1, remote_port); + } else { + int interval = atoi(val); + if (interval < 100 || interval > 5000) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Invalid rtcp interval spec [%d] must be between 100 and 5000\n", interval); + } else { + switch_rtp_activate_rtcp(tech_pvt->rtp_session, interval, remote_port); + } + } + } + + } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", switch_str_nil(err)); switch_channel_hangup(tech_pvt->channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); @@ -3378,6 +3411,11 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, sdp_session_t * } else if (m->m_type == sdp_media_audio && m->m_port && !got_audio) { sdp_rtpmap_t *map; for (attr = m->m_attributes; attr; attr = attr->a_next) { + + if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value) { + switch_channel_set_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port", attr->a_value); + } + if (!strcasecmp(attr->a_name, "ptime") && attr->a_value) { ptime = atoi(attr->a_value); } else if (!strcasecmp(attr->a_name, "maxptime") && attr->a_value) { @@ -3708,6 +3746,9 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, sdp_session_t * if (!strcasecmp(attr->a_name, "framerate") && attr->a_value) { framerate = atoi(attr->a_value); } + if (!strcasecmp(attr->a_name, "rtcp") && attr->a_value) { + switch_channel_set_variable(tech_pvt->channel, "sip_remote_video_rtcp_port", attr->a_value); + } } if (!(rm_encoding = map->rm_encoding)) { rm_encoding = ""; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 0cacc3bded..c2b2b457d7 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -195,6 +195,7 @@ struct switch_rtp { uint32_t ms_per_packet; switch_port_t local_port; switch_port_t remote_port; + switch_port_t remote_rtcp_port; uint32_t stuncount; uint32_t funny_stun; uint32_t default_stuncount; @@ -773,10 +774,8 @@ static switch_status_t enable_remote_rtcp_socket(switch_rtp_t *rtp_session, cons if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { - rtp_session->rtcp_remote_addr = rtp_session->remote_addr; - if (switch_sockaddr_info_get(&rtp_session->rtcp_remote_addr, rtp_session->remote_host_str, SWITCH_UNSPEC, - rtp_session->remote_port + 1, 0, rtp_session->pool) != SWITCH_STATUS_SUCCESS || !rtp_session->rtcp_remote_addr) { + rtp_session->remote_rtcp_port, 0, rtp_session->pool) != SWITCH_STATUS_SUCCESS || !rtp_session->rtcp_remote_addr) { *err = "RTCP Remote Address Error!"; return SWITCH_STATUS_FALSE; } @@ -1248,6 +1247,9 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session { switch_rtp_t *rtp_session = NULL; switch_core_session_t *session = switch_core_memory_pool_get_data(pool, "__session"); + switch_channel_t *channel = NULL; + + if (session) channel = switch_core_session_get_channel(session); *new_rtp_session = NULL; @@ -1303,13 +1305,13 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session rtp_session->payload = payload; - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { - rtp_session->rtcp_send_msg.header.version = 2; - rtp_session->rtcp_send_msg.header.p = 0; - rtp_session->rtcp_send_msg.header.type = 200; - rtp_session->rtcp_send_msg.header.count = 0; - rtp_session->rtcp_send_msg.header.length = htons(6); - } + + rtp_session->rtcp_send_msg.header.version = 2; + rtp_session->rtcp_send_msg.header.p = 0; + rtp_session->rtcp_send_msg.header.type = 200; + rtp_session->rtcp_send_msg.header.count = 0; + rtp_session->rtcp_send_msg.header.length = htons(6); + switch_rtp_set_interval(rtp_session, ms_per_packet, samples_per_interval); rtp_session->conf_samples_per_interval = samples_per_interval; @@ -1341,12 +1343,13 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_create(switch_rtp_t **new_rtp_session switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_NOBLOCK); } + switch_channel_set_private(channel, "__rtcp_audio_rtp_session", rtp_session); + #ifdef ENABLE_ZRTP if (zrtp_on) { switch_rtp_t *master_rtp_session = NULL; int initiator = 0; - switch_channel_t *channel = switch_core_session_get_channel(session); const char *zrtp_enabled = switch_channel_get_variable(channel, "zrtp_secure_media"); const char *srtp_enabled = switch_channel_get_variable(channel, "sip_secure_media"); @@ -1531,14 +1534,24 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t * return SWITCH_STATUS_SUCCESS; } -SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate) +SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_session, int send_rate, switch_port_t remote_port) { const char *err = NULL; switch_set_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "RTCP send rate is: %d and packet rate is: %d\n", send_rate, rtp_session->ms_per_packet); - rtp_session->rtcp_interval = send_rate/(rtp_session->ms_per_packet/1000); + if (!(rtp_session->remote_rtcp_port = remote_port)) { + rtp_session->remote_rtcp_port = rtp_session->remote_port + 1; + } + + if (send_rate == -1) { + switch_set_flag(rtp_session, SWITCH_RTP_FLAG_RTCP_PASSTHRU); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "RTCP passthru enabled. Remote Port: %d\n", rtp_session->remote_rtcp_port); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "RTCP send rate is: %d and packet rate is: %d Remote Port: %d\n", + send_rate, rtp_session->ms_per_packet, rtp_session->remote_rtcp_port); + rtp_session->rtcp_interval = send_rate/(rtp_session->ms_per_packet/1000); + } return enable_local_rtcp_socket(rtp_session, &err) || enable_remote_rtcp_socket(rtp_session, &err); @@ -2236,6 +2249,68 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ if (rtcp_poll_status == SWITCH_STATUS_SUCCESS) { rtcp_status = read_rtcp_packet(rtp_session, &rtcp_bytes, flags); + + if (rtcp_status == SWITCH_STATUS_SUCCESS && switch_test_flag(rtp_session, SWITCH_RTP_FLAG_RTCP_PASSTHRU)) { + switch_core_session_t *session = switch_core_memory_pool_get_data(rtp_session->pool, "__session"); + switch_channel_t *channel = switch_core_session_get_channel(session); + + const char *uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE); + if (uuid) { + switch_core_session_t *other_session; + switch_rtp_t *other_rtp_session = NULL; + + if ((other_session = switch_core_session_locate(uuid))) { + switch_channel_t *other_channel = switch_core_session_get_channel(other_session); + if ((other_rtp_session = switch_channel_get_private(other_channel, "__rtcp_audio_rtp_session")) && + switch_test_flag(other_rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { + *other_rtp_session->rtcp_send_msg.body = *rtp_session->rtcp_recv_msg.body; + + if (switch_test_flag(other_rtp_session, SWITCH_RTP_FLAG_SECURE_SEND)) { + int sbytes = (int) rtcp_bytes; + int stat = srtp_protect_rtcp(other_rtp_session->send_ctx, &other_rtp_session->rtcp_send_msg.header, &sbytes); + if (stat) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: SRTP RTCP protection failed with code %d\n", stat); + } + rtcp_bytes = sbytes; + } + +#ifdef ENABLE_ZRTP + /* ZRTP Send */ + if (1) { + unsigned int sbytes = (int) bytes; + zrtp_status_t stat = zrtp_status_fail; + + stat = zrtp_process_rtcp(other_rtp_session->zrtp_stream, (void *) &other_rtp_session->rtcp_send_msg, &sbytes); + + switch (stat) { + case zrtp_status_ok: + break; + case zrtp_status_drop: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection drop with code %d\n", stat); + ret = (int) bytes; + goto end; + break; + case zrtp_status_fail: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: zRTP protection fail with code %d\n", stat); + break; + default: + break; + } + + bytes = sbytes; + } +#endif + if (switch_socket_sendto(other_rtp_session->rtcp_sock_output, other_rtp_session->rtcp_remote_addr, 0, + (const char*)&other_rtp_session->rtcp_send_msg, &rtcp_bytes ) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"RTCP packet not written\n"); + } + + + } + } + } + + } } } @@ -3244,7 +3319,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session, rtp_session->last_write_ts = this_ts; - if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && + if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_RTCP_PASSTHRU) && rtp_session->rtcp_interval && (rtp_session->stats.outbound.packet_count % rtp_session->rtcp_interval) == 0) { struct switch_rtcp_senderinfo* sr = (struct switch_rtcp_senderinfo*)rtp_session->rtcp_send_msg.body; From 76776ff217a3d47a4c37d1bdf5c1fe19557897aa Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 20 Apr 2010 16:50:40 -0500 Subject: [PATCH 38/62] add outbound_redirect_fatal --- src/mod/endpoints/mod_sofia/sofia.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 89940a8cd7..8338663e30 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -3752,6 +3752,12 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status char *full_contact = NULL; char *invite_contact; const char *br; + const char *v; + + if ((v = switch_channel_get_variable(channel, "outbound_redirect_fatal")) && switch_true(v)) { + switch_channel_hangup(channel, SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL); + goto end; + } if (!p_contact) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Missing contact header in redirect request\n"); From c8981ef818fa384dae0c4ac62a1b5f449b468b9d Mon Sep 17 00:00:00 2001 From: Michael S Collins Date: Tue, 20 Apr 2010 19:32:54 -0700 Subject: [PATCH 39/62] Update ChangeLog through April 20th --- docs/ChangeLog | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/docs/ChangeLog b/docs/ChangeLog index eb93bd70ff..28ab06c2ec 100644 --- a/docs/ChangeLog +++ b/docs/ChangeLog @@ -1,3 +1,20 @@ +freeswitch (1.0.7) + + config: move limit.conf to db.conf + libesl: Fix potential race condition (ESL-36) + mod_db: fix stack corruption (MODAPP-407) + mod_tts_commandline: fix core dump, temp file problem. flush can be called several times (FSMOD-35) + mod_lcr: Expand variables (MODAPP-418) + mod_sofia: Send SIP MESSAGE to unregistered users by prefixing sip: to user@domain + mod_sofia: fix callee being updated with callee information + + +freeswitch (1.0.6) + + all: migrate to git + core: add ... and shutdown as a fail-safe when no modules are loaded + core: fix high mem usage during shutdown + freeswitch (1.0.5) all: run indent on the whole tree and update copyright dates in prep for 1.0.5 (r:16579) @@ -50,6 +67,7 @@ freeswitch (1.0.5) build: Remove libuuid from tree (r:16072) build: Avoid building static version of modules (e.g. mod_enum.a) by adding the "-shared" libtool option. (r:16225) build: Fix pidfile path in debian init script (FSBUILD-264/r:17040) + build: Numerous debian improvements (r:17119) config: improvements to French language handling (MODASRTTS-20/r:14911) config: Add valet_parking to default config (r:15124) config: Add valet macros (r:15156) @@ -66,6 +84,7 @@ freeswitch (1.0.5) config: Allow specifying auth-scheme in config (r:16350/MDXMLINT-56) config: Improvements to french lang (FSCONFIG-18/r:16585) config: Add new English sounds, sound prompts (r:16911) + config: Improvements to French sound prompts (FSCONFIG-23/r:17118) core: Add per-call logging (r:14509) core: Fix IVR menu timeout when caller presses no digits (DP-4/r:14548) core: re-factor node allocation and make a copy of userdata in case the session gets killed before the logger module gets the node (r:14555) @@ -253,6 +272,9 @@ freeswitch (1.0.5) core: Break the loop in switch_ivr_parse_all_events() if CF_BREAK flag has been set (FSCORE-577/r:17074) core: Fix memory leak caused by the function switch_core_codec_copy (FSCORE-579/r:17105) core: add sanity check to project size of decoded codec data (r:17108) + core: handle some errors on missing db handle conditions (r:17136) + core: Fix warning message (FSCORE-578) + core: add switch_channel_export_variable docs: Add large Doxygen update (thanks Muhammed Shahzad) (r:14973) docs: update es phrase file (MODAPP-317/r:15575) embedded_languages: Prevent unloading of embedded languages modules (also fixes MODLANG-121/r:14491) @@ -387,6 +409,7 @@ freeswitch (1.0.5) mod_dptools: Fix bypass_media ignored in dial string (DP-14/r:16588) mod_dptools: add param setting function to asr (r:16600) mod_dptools: add action='user_call' to xml_curl lookups for the user endpoint (r:17115) + mod_enum: fix mod_enum build when udns is already on the base system mod_erlang_event: Add support for simply sending an arbitrary message to an arbitrary registered process at a node (r:14875) mod_erlang_event: Deprecate new_pid message in favor of get_pid which has an extra element, the call's UUID (r:14877) mod_erlang_event: optionally allow compatibility with nodes running older OTP releases (R7 through current) (r:15189) @@ -455,6 +478,7 @@ freeswitch (1.0.5) mod_memcache: update to libmemcached 0.32 (r:14935) mod_memcache: add --with-memcached=no to libmemcached configure (r:14938) mod_nibblebill: Support custom sql with var expansion (MODAPP-409/r:17081) + mod_nibblebill: Fix url (FSCORE-580/r:17129) mod_opal: Added setting of outgoing number and display name from extension number so H.323/Q.931 fields are set correctly in ALERTING and CONNECT messages sent for incoming calls.(r:14900) mod_opal: Fixed compile issues with latest Opal (r:15545) mod_portaudio: fix compilation failure in mod_portaudio_stream (MODFORM-35/r:14531) @@ -624,6 +648,7 @@ freeswitch (1.0.5) mod_sofia: prevent race in killgw followed by an immediate rescan with the same gateway name (r:17096) mod_sofia: fix telephone-event negotiation with devices that don't do what the rfc says they SHOULD do (r:17097) mod_sofia: Double @ in To header (MODENDP-300/r:17098) + mod_sofia: add killgw _all_ to delete all gws mod_spidermonkey: allow inline javascript, use a ~ as first script character (r:15598) mod_spidermonkey: fix mod_spidermonkey on OSX 10.6 (lets see if this breaks any other platforms) (r:15650) mod_spidermonkey: fix teletone issues in javascript (MODLANG-159/MODLANG-162/r:16909) From 90913b8e26265fd381318334f40e0b1a038bb066 Mon Sep 17 00:00:00 2001 From: Mathieu Parent Date: Wed, 21 Apr 2010 08:18:24 +0200 Subject: [PATCH 40/62] Debian: add new skinny conffiles --- debian/freeswitch.conffiles | 5 +++++ debian/freeswitch.install | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/debian/freeswitch.conffiles b/debian/freeswitch.conffiles index 40c6bf90ed..a9cd17804b 100644 --- a/debian/freeswitch.conffiles +++ b/debian/freeswitch.conffiles @@ -48,6 +48,11 @@ /opt/freeswitch/conf/dialplan/features.xml /opt/freeswitch/conf/dialplan/public/00_inbound_did.xml /opt/freeswitch/conf/dialplan/public.xml +/opt/freeswitch/conf/dialplan/skinny-patterns/20-Demo.xml +/opt/freeswitch/conf/dialplan/skinny-patterns/99-Default_Drop.xml +/opt/freeswitch/conf/dialplan/skinny-patterns/20-Local_extension.xml +/opt/freeswitch/conf/dialplan/skinny-patterns/90-External.xml +/opt/freeswitch/conf/dialplan/skinny-patterns.xml /opt/freeswitch/conf/directory/default/1000.xml /opt/freeswitch/conf/directory/default/1001.xml /opt/freeswitch/conf/directory/default/1002.xml diff --git a/debian/freeswitch.install b/debian/freeswitch.install index bb09e6843d..820039c806 100644 --- a/debian/freeswitch.install +++ b/debian/freeswitch.install @@ -55,6 +55,11 @@ opt/freeswitch/conf/dialplan/default.xml opt/freeswitch/conf/dialplan/features.xml opt/freeswitch/conf/dialplan/public/00_inbound_did.xml opt/freeswitch/conf/dialplan/public.xml +opt/freeswitch/conf/dialplan/skinny-patterns/20-Demo.xml +opt/freeswitch/conf/dialplan/skinny-patterns/99-Default_Drop.xml +opt/freeswitch/conf/dialplan/skinny-patterns/20-Local_extension.xml +opt/freeswitch/conf/dialplan/skinny-patterns/90-External.xml +opt/freeswitch/conf/dialplan/skinny-patterns.xml opt/freeswitch/conf/directory/default/1000.xml opt/freeswitch/conf/directory/default/1001.xml opt/freeswitch/conf/directory/default/1002.xml From 08dcb793601b16c548fdf65f0ab64cfa8699a08e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Apr 2010 08:26:54 -0500 Subject: [PATCH 41/62] change SVN to source so even if we change repos again we won't say the wrong one --- bootstrap.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 4755bc75c5..f4da83706f 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -22,7 +22,7 @@ ac_version=`${AUTOCONF:-autoconf} --version 2>/dev/null|sed -e 's/^[^0-9]*//;s/[ if test -z "$ac_version"; then echo "bootstrap: autoconf not found." echo " You need autoconf version 2.59 or newer installed" -echo " to build FreeSWITCH from SVN." +echo " to build FreeSWITCH from source." exit 1 fi @@ -37,7 +37,7 @@ IFS=.; set $ac_version; IFS=' ' if test "$1" = "2" -a "$2" -lt "59" || test "$1" -lt "2"; then echo "bootstrap: autoconf version $ac_version found." echo " You need autoconf version 2.59 or newer installed" -echo " to build FreeSWITCH from SVN." +echo " to build FreeSWITCH from source." exit 1 else echo "bootstrap: autoconf version $ac_version (ok)" @@ -50,7 +50,7 @@ am_version=`${AUTOMAKE:-automake} --version 2>/dev/null|sed -e 's/^[^0-9]*//;s/[ if test -z "$am_version"; then echo "bootstrap: automake not found." echo " You need automake version 1.7 or newer installed" -echo " to build FreeSWITCH from SVN." +echo " to build FreeSWITCH from source." exit 1 fi IFS=_; set $am_version; IFS=' ' @@ -59,7 +59,7 @@ IFS=.; set $am_version; IFS=' ' if test "$1" = "1" -a "$2" -lt "7"; then echo "bootstrap: automake version $am_version found." echo " You need automake version 1.7 or newer installed" -echo " to build FreeSWITCH from SVN." +echo " to build FreeSWITCH from source." exit 1 else echo "bootstrap: automake version $am_version (ok)" @@ -71,7 +71,7 @@ acl_version=`${ACLOCAL:-aclocal} --version 2>/dev/null|sed -e 's/^[^0-9]*//;s/[a if test -z "$acl_version"; then echo "bootstrap: aclocal not found." echo " You need aclocal version 1.7 or newer installed" -echo " to build FreeSWITCH from SVN." +echo " to build FreeSWITCH from source." exit 1 fi IFS=_; set $acl_version; IFS=' ' @@ -80,7 +80,7 @@ IFS=.; set $acl_version; IFS=' ' if test "$1" = "1" -a "$2" -lt "7"; then echo "bootstrap: aclocal version $acl_version found." echo " You need aclocal version 1.7 or newer installed" -echo " to build FreeSWITCH from SVN." +echo " to build FreeSWITCH from source." exit 1 else echo "bootstrap: aclocal version $acl_version (ok)" @@ -96,7 +96,7 @@ libtool=${LIBTOOL:-`${LIBDIR}/apr/build/PrintPath glibtool libtool libtool22 lib lt_pversion=`$libtool --version 2>/dev/null|sed -e 's/([^)]*)//g;s/^[^0-9]*//;s/[- ].*//g;q'` if test -z "$lt_pversion"; then echo "bootstrap: libtool not found." - echo " You need libtool version 1.5.14 or newer to build FreeSWITCH from SVN." + echo " You need libtool version 1.5.14 or newer to build FreeSWITCH from source." exit 1 fi lt_version=`echo $lt_pversion|sed -e 's/\([a-z]*\)$/.\1/'` @@ -121,7 +121,7 @@ if test $lt_status = "good"; then echo "bootstrap: libtool version $lt_pversion (ok)" else echo "bootstrap: libtool version $lt_pversion found." - echo " You need libtool version 1.5.14 or newer to build FreeSWITCH from SVN." + echo " You need libtool version 1.5.14 or newer to build FreeSWITCH from source." exit 1 fi From 964d59c56e245b9c1cf53a73af87b2834c2c5ad8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Apr 2010 09:53:26 -0500 Subject: [PATCH 42/62] proper checking for dlerror on failed dso load --- src/switch_dso.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/switch_dso.c b/src/switch_dso.c index 6fc5c7b86c..152c280d5d 100644 --- a/src/switch_dso.c +++ b/src/switch_dso.c @@ -127,7 +127,16 @@ void *switch_dso_data_sym(switch_dso_lib_t lib, const char *sym, char **err) { void *addr = dlsym(lib, sym); if (!addr) { - *err = strdup(dlerror()); + char *err_str = NULL; + dlerror(); + + if (!(addr = dlsym(lib, sym))) { + err_str = dlerror(); + } + + if (err_str) { + *err = strdup(err_str); + } } return addr; } From 95665f0096d6d8af74257fd0e17c6522f31ee6c1 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Apr 2010 10:11:13 -0500 Subject: [PATCH 43/62] JANITOR-4 --- src/mod/endpoints/mod_loopback/mod_loopback.c | 6 ------ src/mod/formats/mod_sndfile/mod_sndfile.c | 9 ++------- src/mod/loggers/mod_logfile/mod_logfile.c | 2 ++ src/switch.c | 1 + src/switch_core.c | 10 ++++++++++ src/switch_loadable_module.c | 3 ++- src/switch_time.c | 4 ++++ 7 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index 8dde5042b6..9e11c5b474 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -44,8 +44,6 @@ SWITCH_MODULE_DEFINITION(mod_loopback, mod_loopback_load, mod_loopback_shutdown, static switch_endpoint_interface_t *loopback_endpoint_interface = NULL; -static switch_memory_pool_t *module_pool = NULL; - typedef enum { TFLAG_LINKED = (1 << 0), TFLAG_OUTBOUND = (1 << 1), @@ -887,10 +885,6 @@ static switch_io_routines_t channel_io_routines = { SWITCH_MODULE_LOAD_FUNCTION(mod_loopback_load) { - if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n"); - return SWITCH_STATUS_TERM; - } memset(&globals, 0, sizeof(globals)); diff --git a/src/mod/formats/mod_sndfile/mod_sndfile.c b/src/mod/formats/mod_sndfile/mod_sndfile.c index 020943ce5a..c017ad9f06 100644 --- a/src/mod/formats/mod_sndfile/mod_sndfile.c +++ b/src/mod/formats/mod_sndfile/mod_sndfile.c @@ -36,7 +36,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sndfile_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sndfile_shutdown); SWITCH_MODULE_DEFINITION(mod_sndfile, mod_sndfile_load, mod_sndfile_shutdown, NULL); -static switch_memory_pool_t *module_pool = NULL; static struct { switch_hash_t *format_hash; @@ -415,12 +414,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sndfile_load) { switch_file_interface_t *file_interface; - if (switch_core_new_memory_pool(&module_pool) != SWITCH_STATUS_SUCCESS) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n"); - return SWITCH_STATUS_TERM; - } - - switch_core_hash_init(&globals.format_hash, module_pool); + switch_core_hash_init(&globals.format_hash, pool); if (setup_formats() != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_FALSE; @@ -447,6 +441,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sndfile_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_sndfile_shutdown) { switch_core_hash_destroy(&globals.format_hash); + return SWITCH_STATUS_SUCCESS; } diff --git a/src/mod/loggers/mod_logfile/mod_logfile.c b/src/mod/loggers/mod_logfile/mod_logfile.c index 3645cb1ea1..8cdaf9615a 100644 --- a/src/mod/loggers/mod_logfile/mod_logfile.c +++ b/src/mod/loggers/mod_logfile/mod_logfile.c @@ -398,9 +398,11 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_logfile_shutdown) if ((profile = (logfile_profile_t *) val)) { switch_file_close(profile->log_afd); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Closing %s\n", profile->logfile); + switch_safe_free(profile->logfile); } } + switch_core_hash_destroy(&profile_hash); return SWITCH_STATUS_SUCCESS; diff --git a/src/switch.c b/src/switch.c index 5c761e372c..77aea8dc00 100644 --- a/src/switch.c +++ b/src/switch.c @@ -791,6 +791,7 @@ int main(int argc, char *argv[]) destroy_status = switch_core_destroy(); switch_file_close(fd); + apr_pool_destroy(pool); if (unlink(pid_path) != 0) { fprintf(stderr, "Failed to delete pid file [%s]\n", pid_path); diff --git a/src/switch_core.c b/src/switch_core.c index fe0ffcbaba..78296ebe7b 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1867,13 +1867,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void) switch_safe_free(SWITCH_GLOBAL_dirs.script_dir); switch_safe_free(SWITCH_GLOBAL_dirs.htdocs_dir); switch_safe_free(SWITCH_GLOBAL_dirs.grammar_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.storage_dir); switch_safe_free(SWITCH_GLOBAL_dirs.recordings_dir); switch_safe_free(SWITCH_GLOBAL_dirs.sounds_dir); + switch_safe_free(SWITCH_GLOBAL_dirs.run_dir); switch_safe_free(SWITCH_GLOBAL_dirs.temp_dir); switch_core_hash_destroy(&runtime.global_vars); switch_core_hash_destroy(&runtime.mime_types); + if (IP_LIST.hash) { + switch_core_hash_destroy(&IP_LIST.hash); + } + + if (IP_LIST.pool) { + switch_core_destroy_memory_pool(&IP_LIST.pool); + } + if (runtime.memory_pool) { apr_pool_destroy(runtime.memory_pool); apr_terminate(); diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 62ca411609..2e37585e52 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -788,7 +788,7 @@ static switch_status_t switch_loadable_module_load_file(char *path, char *filena switch_loadable_module_interface_t *module_interface = NULL; char *derr = NULL; const char *err = NULL; - switch_memory_pool_t *pool; + switch_memory_pool_t *pool = NULL; switch_bool_t load_global = global; switch_assert(path != NULL); @@ -1349,6 +1349,7 @@ SWITCH_DECLARE(void) switch_loadable_module_shutdown(void) switch_core_hash_destroy(&loadable_modules.management_hash); switch_core_hash_destroy(&loadable_modules.dialplan_hash); + switch_core_destroy_memory_pool(&loadable_modules.pool); } SWITCH_DECLARE(switch_endpoint_interface_t *) switch_loadable_module_get_endpoint_interface(const char *name) diff --git a/src/switch_time.c b/src/switch_time.c index cbdc2f8eb1..2d74e60594 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -1064,6 +1064,10 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(softtimer_shutdown) switch_core_destroy_memory_pool(&TIMEZONES_LIST.pool); } + if (NODE) { + switch_event_unbind(&NODE); + } + return SWITCH_STATUS_SUCCESS; } From 118ddcf5d34a97d2dc02be0295a6c2130088e5ff Mon Sep 17 00:00:00 2001 From: Christopher Rienzo Date: Wed, 21 Apr 2010 19:57:23 +0100 Subject: [PATCH 44/62] fixed RTCP configuration in internal.xml --- conf/sip_profiles/internal.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conf/sip_profiles/internal.xml b/conf/sip_profiles/internal.xml index 2f5636e5a6..2196eff20d 100644 --- a/conf/sip_profiles/internal.xml +++ b/conf/sip_profiles/internal.xml @@ -209,8 +209,8 @@ - - + + From 0b45537ec8584a28251e8a3d4836c2d22cb8f272 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 21 Apr 2010 14:52:25 -0400 Subject: [PATCH 45/62] freetdm: make sure gains are not applied to non-voice channels --- libs/freetdm/src/ftdm_io.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 356eba5cb8..f00e7988e3 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -2050,6 +2050,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co case FTDM_COMMAND_SET_RX_GAIN: { + if (!FTDM_IS_VOICE_CHANNEL(ftdmchan)) { + ftdm_log(FTDM_LOG_ERROR, "Cannot set rx gain in non-voice channel of type: %s\n", ftdm_chan_type2str(ftdmchan->type)); + GOTO_STATUS(done, FTDM_FAIL); + } ftdmchan->rxgain = FTDM_COMMAND_OBJ_FLOAT; reset_gain_table(ftdmchan->rxgain_table, ftdmchan->rxgain, ftdmchan->native_codec); if (ftdmchan->rxgain == 0.0) { @@ -2068,6 +2072,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_command(ftdm_channel_t *ftdmchan, ftdm_co break; case FTDM_COMMAND_SET_TX_GAIN: { + if (!FTDM_IS_VOICE_CHANNEL(ftdmchan)) { + ftdm_log(FTDM_LOG_ERROR, "Cannot set tx gain in non-voice channel of type: %s\n", ftdm_chan_type2str(ftdmchan->type)); + GOTO_STATUS(done, FTDM_FAIL); + } ftdmchan->txgain = FTDM_COMMAND_OBJ_FLOAT; reset_gain_table(ftdmchan->txgain_table, ftdmchan->txgain, ftdmchan->native_codec); if (ftdmchan->txgain == 0.0) { @@ -2468,17 +2476,17 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "ftdmchan is null\n"); ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "No I/O module attached to ftdmchan\n"); - if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { + if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) { snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "channel not open"); - return FTDM_FAIL; - } + return FTDM_FAIL; + } if (!ftdmchan->fio->read) { snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "method not implemented"); return FTDM_FAIL; } - status = ftdmchan->fio->read(ftdmchan, data, datalen); + status = ftdmchan->fio->read(ftdmchan, data, datalen); if (ftdmchan->fds[0] > -1) { int dlen = (int) *datalen; if (write(ftdmchan->fds[0], data, dlen) != dlen) { From e9829d1ed85c93ca14b91457b8c8b2513e112ae5 Mon Sep 17 00:00:00 2001 From: Mathieu Rene Date: Wed, 21 Apr 2010 16:41:08 -0400 Subject: [PATCH 46/62] Add SAF_SUPPORT_NOMEDIA to nibblebill --- src/mod/applications/mod_nibblebill/mod_nibblebill.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mod/applications/mod_nibblebill/mod_nibblebill.c b/src/mod/applications/mod_nibblebill/mod_nibblebill.c index 093fbd4ef2..b1b124bc67 100755 --- a/src/mod/applications/mod_nibblebill/mod_nibblebill.c +++ b/src/mod/applications/mod_nibblebill/mod_nibblebill.c @@ -944,7 +944,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_nibblebill_load) /* Add dialplan applications */ SWITCH_ADD_APP(app_interface, "nibblebill", "Handle billing for the current channel/call", "Pause, resume, reset, adjust, flush, heartbeat commands to handle billing.", nibblebill_app_function, APP_SYNTAX, - SAF_NONE | SAF_ROUTING_EXEC); + SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC); /* register state handlers for billing */ switch_core_add_state_handler(&nibble_state_handler); From 5ce95b8443cd6000a5003e31c69963a0bbc477f4 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Apr 2010 14:50:17 -0500 Subject: [PATCH 47/62] fix errs --- src/switch_rtp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/switch_rtp.c b/src/switch_rtp.c index c2b2b457d7..e14bf3ad20 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1546,9 +1546,9 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_rtcp(switch_rtp_t *rtp_sessi if (send_rate == -1) { switch_set_flag(rtp_session, SWITCH_RTP_FLAG_RTCP_PASSTHRU); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "RTCP passthru enabled. Remote Port: %d\n", rtp_session->remote_rtcp_port); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "RTCP passthru enabled. Remote Port: %d\n", rtp_session->remote_rtcp_port); } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "RTCP send rate is: %d and packet rate is: %d Remote Port: %d\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "RTCP send rate is: %d and packet rate is: %d Remote Port: %d\n", send_rate, rtp_session->ms_per_packet, rtp_session->remote_rtcp_port); rtp_session->rtcp_interval = send_rate/(rtp_session->ms_per_packet/1000); } From 4616d9424e736af1653361749e37f2f9c2c62e4d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 21 Apr 2010 17:13:10 -0500 Subject: [PATCH 48/62] wtf --- src/mod/endpoints/mod_sofia/sofia_glue.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 49b302b7ff..9df96c280d 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -2727,8 +2727,6 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f (tech_pvt->stun_flags & STUN_FLAG_FUNNY) ? 1 : 0); } - printf("WTF [%s][%s]\n", switch_channel_get_variable(tech_pvt->channel, "rtcp_audio_interval_msec"), tech_pvt->profile->rtcp_audio_interval_msec); - if ((val = switch_channel_get_variable(tech_pvt->channel, "rtcp_audio_interval_msec")) || (val = tech_pvt->profile->rtcp_audio_interval_msec)) { const char *rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port"); switch_port_t remote_port = 0; From fb9e6a104babca9616abd9e45b1f4f3b9a9d3a7b Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Wed, 21 Apr 2010 18:46:52 -0400 Subject: [PATCH 49/62] freetdm: fix boost unload crash --- .../ftmod_sangoma_boost/ftmod_sangoma_boost.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index af92ac6775..f6138c2f43 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@ -2136,23 +2136,23 @@ static ftdm_status_t ftdm_sangoma_boost_start(ftdm_span_t *span) static ftdm_status_t ftdm_sangoma_boost_stop(ftdm_span_t *span) { - int cnt = 10; ftdm_status_t status = FTDM_SUCCESS; ftdm_sangoma_boost_data_t *sangoma_boost_data = span->signal_data; if (sangoma_boost_data->sigmod) { - - /* FIXME: we should make sure the span thread is stopped (use pthread_kill or freetdm thread kill function) */ /* I think stopping the span before destroying the queue makes sense otherwise may be boost events would still arrive when the queue is already destroyed! */ status = sangoma_boost_data->sigmod->stop_span(span); ftdm_queue_enqueue(sangoma_boost_data->boost_queue, NULL); - while(ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING) && cnt-- > 0) { - ftdm_log(FTDM_LOG_DEBUG, "Waiting for boost thread\n"); - ftdm_sleep(500); - } + } + + while (ftdm_test_flag(sangoma_boost_data, FTDM_SANGOMA_BOOST_RUNNING)) { + ftdm_log(FTDM_LOG_DEBUG, "Waiting for boost thread\n"); + ftdm_sleep(100); + } + + if (sangoma_boost_data->sigmod) { ftdm_queue_destroy(&sangoma_boost_data->boost_queue); - return status; } return status; } From 70ab76902e6dbf445ca7590d745108118845bd5c Mon Sep 17 00:00:00 2001 From: Giovanni Date: Thu, 22 Apr 2010 13:28:23 +0200 Subject: [PATCH 50/62] skypopen: updating Windows solution --- src/mod/endpoints/mod_gsmopen/mod_gsmopen.2008.vcproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.2008.vcproj b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.2008.vcproj index edfccb09e5..98c5d842ab 100644 --- a/src/mod/endpoints/mod_gsmopen/mod_gsmopen.2008.vcproj +++ b/src/mod/endpoints/mod_gsmopen/mod_gsmopen.2008.vcproj @@ -39,7 +39,7 @@ /> Date: Thu, 22 Apr 2010 10:22:28 -0500 Subject: [PATCH 51/62] FSCORE-594 --- src/include/switch_rtp.h | 2 +- src/mod/endpoints/mod_sofia/sofia_glue.c | 38 +++++++++++++++++++--- src/switch_rtp.c | 41 ++++++++++++++++-------- 3 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/include/switch_rtp.h b/src/include/switch_rtp.h index c4bab48190..8e0693cdc1 100644 --- a/src/include/switch_rtp.h +++ b/src/include/switch_rtp.h @@ -168,7 +168,7 @@ SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(const char *rx_host, \param port the remote port \param err pointer for error messages */ -SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, +SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, switch_port_t remote_rtcp_port, switch_bool_t change_adv_addr, const char **err); SWITCH_DECLARE(char *) switch_rtp_get_remote_host(switch_rtp_t *rtp_session); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index 9df96c280d..77b82b0665 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -1127,8 +1127,16 @@ switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt) sofia_set_flag_locked(tech_pvt, TFLAG_VIDEO); switch_channel_set_flag(tech_pvt->channel, CF_VIDEO); if (switch_rtp_ready(tech_pvt->video_rtp_session)) { + const char *rport = NULL; + switch_port_t remote_rtcp_port = 0; + + if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"))) { + remote_rtcp_port = atoi(rport); + } + + if (switch_rtp_set_remote_address(tech_pvt->video_rtp_session, tech_pvt->remote_sdp_video_ip, - tech_pvt->remote_sdp_video_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + tech_pvt->remote_sdp_video_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", err); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "VIDEO RTP CHANGING DEST TO: [%s:%d]\n", @@ -1149,6 +1157,8 @@ switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt) if (switch_rtp_ready(tech_pvt->rtp_session)) { char *remote_host = switch_rtp_get_remote_host(tech_pvt->rtp_session); switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session); + const char *rport = NULL; + switch_port_t remote_rtcp_port = 0; if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_audio_ip) && remote_port == tech_pvt->remote_sdp_audio_port) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Remote address:port [%s:%d] has not changed.\n", @@ -1156,8 +1166,13 @@ switch_status_t sofia_glue_tech_proxy_remote_addr(private_object_t *tech_pvt) return SWITCH_STATUS_SUCCESS; } + if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port"))) { + remote_rtcp_port = atoi(rport); + } + + if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip, - tech_pvt->remote_sdp_audio_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { + tech_pvt->remote_sdp_audio_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err); } else { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "AUDIO RTP CHANGING DEST TO: [%s:%d]\n", @@ -2605,9 +2620,17 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE, tmp); if (tech_pvt->rtp_session && sofia_test_flag(tech_pvt, TFLAG_REINVITE)) { + const char *rport = NULL; + switch_port_t remote_rtcp_port = 0; + sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE); - if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port, SWITCH_TRUE, &err) != + if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_audio_rtcp_port"))) { + remote_rtcp_port = atoi(rport); + } + + if (switch_rtp_set_remote_address(tech_pvt->rtp_session, tech_pvt->remote_sdp_audio_ip, tech_pvt->remote_sdp_audio_port, + remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "AUDIO RTP REPORTS ERROR: [%s]\n", err); } else { @@ -2859,10 +2882,17 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f switch_channel_set_variable(tech_pvt->channel, SWITCH_LOCAL_VIDEO_PORT_VARIABLE, tmp); if (tech_pvt->video_rtp_session && sofia_test_flag(tech_pvt, TFLAG_REINVITE)) { + const char *rport = NULL; + switch_port_t remote_rtcp_port = 0; + sofia_clear_flag_locked(tech_pvt, TFLAG_REINVITE); + if ((rport = switch_channel_get_variable(tech_pvt->channel, "sip_remote_video_rtcp_port"))) { + remote_rtcp_port = atoi(rport); + } + if (switch_rtp_set_remote_address - (tech_pvt->video_rtp_session, tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port, SWITCH_TRUE, + (tech_pvt->video_rtp_session, tech_pvt->remote_sdp_video_ip, tech_pvt->remote_sdp_video_port, remote_rtcp_port, SWITCH_TRUE, &err) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "VIDEO RTP REPORTS ERROR: [%s]\n", err); } else { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index e14bf3ad20..d1126703e6 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -778,19 +778,27 @@ static switch_status_t enable_remote_rtcp_socket(switch_rtp_t *rtp_session, cons rtp_session->remote_rtcp_port, 0, rtp_session->pool) != SWITCH_STATUS_SUCCESS || !rtp_session->rtcp_remote_addr) { *err = "RTCP Remote Address Error!"; return SWITCH_STATUS_FALSE; + } else { + const char *host; + char bufa[30]; + host = switch_get_addr(bufa, sizeof(bufa), rtp_session->rtcp_remote_addr); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Setting RTCP remote addr to %s:%d\n", host, rtp_session->remote_rtcp_port); } - if (rtp_session->rtcp_sock_input && switch_sockaddr_get_family(rtp_session->rtcp_remote_addr) == - switch_sockaddr_get_family(rtp_session->rtcp_local_addr)) { - rtp_session->rtcp_sock_output = rtp_session->rtcp_sock_input; - } else { - if (rtp_session->rtcp_sock_output && rtp_session->rtcp_sock_output != rtp_session->rtcp_sock_input) { - switch_socket_close(rtp_session->rtcp_sock_output); - } - if ((status = switch_socket_create(&rtp_session->rtcp_sock_output, - switch_sockaddr_get_family(rtp_session->rtcp_remote_addr), - SOCK_DGRAM, 0, rtp_session->pool)) != SWITCH_STATUS_SUCCESS) { - *err = "RTCP Socket Error!"; + if (!(rtp_session->rtcp_sock_input && rtp_session->rtcp_sock_output)) { + if (rtp_session->rtcp_sock_input && switch_sockaddr_get_family(rtp_session->rtcp_remote_addr) == + switch_sockaddr_get_family(rtp_session->rtcp_local_addr)) { + rtp_session->rtcp_sock_output = rtp_session->rtcp_sock_input; + } else { + if (rtp_session->rtcp_sock_output && rtp_session->rtcp_sock_output != rtp_session->rtcp_sock_input) { + switch_socket_close(rtp_session->rtcp_sock_output); + } + if ((status = switch_socket_create(&rtp_session->rtcp_sock_output, + switch_sockaddr_get_family(rtp_session->rtcp_remote_addr), + SOCK_DGRAM, 0, rtp_session->pool)) != SWITCH_STATUS_SUCCESS) { + *err = "RTCP Socket Error!"; + } } } } else { @@ -1020,7 +1028,7 @@ SWITCH_DECLARE(switch_port_t) switch_rtp_get_remote_port(switch_rtp_t *rtp_sessi } -SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, +SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_session, const char *host, switch_port_t port, switch_port_t remote_rtcp_port, switch_bool_t change_adv_addr, const char **err) { switch_sockaddr_t *remote_addr; @@ -1056,6 +1064,11 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_remote_address(switch_rtp_t *rtp_ } if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP)) { + if (remote_rtcp_port) { + rtp_session->remote_rtcp_port = remote_rtcp_port; + } else { + rtp_session->remote_rtcp_port = rtp_session->remote_port + 1; + } status = enable_remote_rtcp_socket(rtp_session, err); } @@ -1462,7 +1475,7 @@ SWITCH_DECLARE(switch_rtp_t *) switch_rtp_new(const char *rx_host, goto end; } - if (switch_rtp_set_remote_address(rtp_session, tx_host, tx_port, SWITCH_TRUE, err) != SWITCH_STATUS_SUCCESS) { + if (switch_rtp_set_remote_address(rtp_session, tx_host, tx_port, 0, SWITCH_TRUE, err) != SWITCH_STATUS_SUCCESS) { switch_mutex_unlock(rtp_session->flag_mutex); rtp_session = NULL; goto end; @@ -2426,7 +2439,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ switch_channel_set_variable(channel, "rtp_auto_adjust", "true"); } - switch_rtp_set_remote_address(rtp_session, tx_host, switch_sockaddr_get_port(rtp_session->from_addr), SWITCH_FALSE, &err); + switch_rtp_set_remote_address(rtp_session, tx_host, switch_sockaddr_get_port(rtp_session->from_addr), 0, SWITCH_FALSE, &err); switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_AUTOADJ); } } else { From 90e7da1c59537951f953599f1b991386ef95c9cd Mon Sep 17 00:00:00 2001 From: David Yat Sin Date: Thu, 22 Apr 2010 14:20:32 -0400 Subject: [PATCH 52/62] freetdm: bug fix for queue mode and call collision --- libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index af92ac6775..5ea5abc4a8 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@ -1013,6 +1013,7 @@ static void handle_call_start(ftdm_span_t *span, sangomabc_connection_t *mcon, s ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE, 0, r); } else if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { ftdm_log(FTDM_LOG_WARNING, "s%dc%d:Collision, hanging up incoming call\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event)); + ftdm_set_state_r(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING, 0, r); } else { ftdm_log(FTDM_LOG_CRIT, "s%dc%d:FTDMCHAN STATE INVALID %s on IN CALL\n", BOOST_EVENT_SPAN(mcon->sigmod, event), BOOST_EVENT_CHAN(mcon->sigmod, event), ftdm_channel_state2str(ftdmchan->state)); } From 631f5407448ad0c78bcc5c6e06736764ec763c02 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 22 Apr 2010 13:28:44 -0500 Subject: [PATCH 53/62] try harder to get db handle in sql thread and fail out if it can't get one --- src/switch_core_sqldb.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/switch_core_sqldb.c b/src/switch_core_sqldb.c index 530d700873..9e02a91c8e 100644 --- a/src/switch_core_sqldb.c +++ b/src/switch_core_sqldb.c @@ -809,6 +809,7 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, int lc = 0; uint32_t loops = 0, sec = 0; uint32_t l1 = 1000; + uint32_t sanity = 120; switch_assert(sqlbuf); @@ -816,10 +817,19 @@ static void *SWITCH_THREAD_FUNC switch_core_sql_thread(switch_thread_t *thread, l1 = 10; } - if (!sql_manager.event_db) { - switch_core_db_handle(&sql_manager.event_db); + while (!sql_manager.event_db) { + if (switch_core_db_handle(&sql_manager.event_db) == SWITCH_STATUS_SUCCESS && sql_manager.event_db) break; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Error getting core db, Retrying\n"); + switch_yield(500000); + sanity--; } + if (!sql_manager.event_db) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error getting core db Disabling core sql functionality\n"); + return NULL; + } + + sql_manager.thread_running = 1; while (sql_manager.thread_running == 1) { From a96c2fcbfb59ed24d48c6dec21ff61bd5174ea19 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 22 Apr 2010 15:30:55 -0500 Subject: [PATCH 54/62] always export 'export_vars' --- src/switch_ivr_originate.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index 2df902bcc4..27dd189600 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -1366,6 +1366,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_enterprise_originate(switch_core_sess int argc; char *argv[256]; + switch_event_del_header(var_event, SWITCH_EXPORT_VARS_VARIABLE); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, SWITCH_EXPORT_VARS_VARIABLE, export_vars); + if ((argc = switch_separate_string(cptmp, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) { int x; From 8a91066d5a919f44140f6f14c7dd9dcc5da88ad8 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 22 Apr 2010 20:32:29 -0500 Subject: [PATCH 55/62] MODEVENT-63 vcproj changes - the rest waiting on tarball update --- Freeswitch.2008.express.sln | 44 ++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/Freeswitch.2008.express.sln b/Freeswitch.2008.express.sln index 5d298734c8..e621622630 100644 --- a/Freeswitch.2008.express.sln +++ b/Freeswitch.2008.express.sln @@ -613,6 +613,24 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_valet_parking", "src\mo {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download JSON", "libs\win32\Download JSON.2008.vcproj", "{B808178B-82F0-4CF4-A2B1-921939FA24D0}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libjson", "libs\win32\json\libjson.2008.vcproj", "{9778F1C0-09BC-4698-8EBC-BD982247209A}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_curl", "src\mod\applications\mod_curl\mod_curl.2008.vcproj", "{EF300386-A8DF-4372-B6D8-FB9BFFCA9AED}" + ProjectSection(ProjectDependencies) = postProject + {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} + {87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588} + {9778F1C0-09BC-4698-8EBC-BD982247209A} = {9778F1C0-09BC-4698-8EBC-BD982247209A} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_json_cdr", "src\mod\event_handlers\mod_json_cdr\mod_json_cdr.2008.vcproj", "{EBE7452D-B3F7-4798-8EED-A0DDE2D738F5}" + ProjectSection(ProjectDependencies) = postProject + {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF} + {87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588} + {9778F1C0-09BC-4698-8EBC-BD982247209A} = {9778F1C0-09BC-4698-8EBC-BD982247209A} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution All|Win32 = All|Win32 @@ -1602,7 +1620,6 @@ Global {D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.All|Win32.Build.0 = Release|Win32 {D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.All|x64.ActiveCfg = Release|Win32 {D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.Debug|Win32.ActiveCfg = Debug|Win32 - {D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.Debug|Win32.Build.0 = Debug|Win32 {D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.Debug|x64.ActiveCfg = Debug|Win32 {D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.Debug|x64.Build.0 = Debug|Win32 {D5D2BF72-29FE-4982-A9FA-82AB2086DB1B}.Release|Win32.ActiveCfg = Release|Win32 @@ -2002,6 +2019,31 @@ Global {432DB165-1EB2-4781-A9C0-71E62610B20A}.Release|Win32.Build.0 = Release|Win32 {432DB165-1EB2-4781-A9C0-71E62610B20A}.Release|x64.ActiveCfg = Release|x64 {432DB165-1EB2-4781-A9C0-71E62610B20A}.Release|x64.Build.0 = Release|x64 + {B808178B-82F0-4CF4-A2B1-921939FA24D0}.All|Win32.ActiveCfg = Release|Win32 + {B808178B-82F0-4CF4-A2B1-921939FA24D0}.All|x64.ActiveCfg = Release|Win32 + {B808178B-82F0-4CF4-A2B1-921939FA24D0}.Debug|Win32.ActiveCfg = Debug|Win32 + {B808178B-82F0-4CF4-A2B1-921939FA24D0}.Debug|Win32.Build.0 = Debug|Win32 + {B808178B-82F0-4CF4-A2B1-921939FA24D0}.Debug|x64.ActiveCfg = Debug|Win32 + {B808178B-82F0-4CF4-A2B1-921939FA24D0}.Release|Win32.ActiveCfg = Release|Win32 + {B808178B-82F0-4CF4-A2B1-921939FA24D0}.Release|x64.ActiveCfg = Release|Win32 + {9778F1C0-09BC-4698-8EBC-BD982247209A}.All|Win32.ActiveCfg = Release|Win32 + {9778F1C0-09BC-4698-8EBC-BD982247209A}.All|x64.ActiveCfg = Release|Win32 + {9778F1C0-09BC-4698-8EBC-BD982247209A}.Debug|Win32.ActiveCfg = Debug|Win32 + {9778F1C0-09BC-4698-8EBC-BD982247209A}.Debug|x64.ActiveCfg = Debug|Win32 + {9778F1C0-09BC-4698-8EBC-BD982247209A}.Release|Win32.ActiveCfg = Release|Win32 + {9778F1C0-09BC-4698-8EBC-BD982247209A}.Release|x64.ActiveCfg = Release|Win32 + {EF300386-A8DF-4372-B6D8-FB9BFFCA9AED}.All|Win32.ActiveCfg = Release|Win32 + {EF300386-A8DF-4372-B6D8-FB9BFFCA9AED}.All|x64.ActiveCfg = Release|Win32 + {EF300386-A8DF-4372-B6D8-FB9BFFCA9AED}.Debug|Win32.ActiveCfg = Debug|Win32 + {EF300386-A8DF-4372-B6D8-FB9BFFCA9AED}.Debug|x64.ActiveCfg = Debug|Win32 + {EF300386-A8DF-4372-B6D8-FB9BFFCA9AED}.Release|Win32.ActiveCfg = Release|Win32 + {EF300386-A8DF-4372-B6D8-FB9BFFCA9AED}.Release|x64.ActiveCfg = Release|Win32 + {EBE7452D-B3F7-4798-8EED-A0DDE2D738F5}.All|Win32.ActiveCfg = Release|Win32 + {EBE7452D-B3F7-4798-8EED-A0DDE2D738F5}.All|x64.ActiveCfg = Release|Win32 + {EBE7452D-B3F7-4798-8EED-A0DDE2D738F5}.Debug|Win32.ActiveCfg = Debug|Win32 + {EBE7452D-B3F7-4798-8EED-A0DDE2D738F5}.Debug|x64.ActiveCfg = Debug|Win32 + {EBE7452D-B3F7-4798-8EED-A0DDE2D738F5}.Release|Win32.ActiveCfg = Release|Win32 + {EBE7452D-B3F7-4798-8EED-A0DDE2D738F5}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 05e5667d16f7fba8c0a274b1de23f765c9c70905 Mon Sep 17 00:00:00 2001 From: Brian West Date: Thu, 22 Apr 2010 23:26:33 -0500 Subject: [PATCH 56/62] MP4V-ES passthru for washibechi on IRC --- src/mod/codecs/mod_mp4v/Makefile | 2 + src/mod/codecs/mod_mp4v/mod_mp4v.c | 102 +++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 src/mod/codecs/mod_mp4v/Makefile create mode 100644 src/mod/codecs/mod_mp4v/mod_mp4v.c diff --git a/src/mod/codecs/mod_mp4v/Makefile b/src/mod/codecs/mod_mp4v/Makefile new file mode 100644 index 0000000000..2c35e6e98f --- /dev/null +++ b/src/mod/codecs/mod_mp4v/Makefile @@ -0,0 +1,2 @@ +BASE=../../../.. +include $(BASE)/build/modmake.rules diff --git a/src/mod/codecs/mod_mp4v/mod_mp4v.c b/src/mod/codecs/mod_mp4v/mod_mp4v.c new file mode 100644 index 0000000000..9500075de3 --- /dev/null +++ b/src/mod/codecs/mod_mp4v/mod_mp4v.c @@ -0,0 +1,102 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2010, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Anthony Minessale II + * + * + * mod_mp4v.c -- MP4V Signed Linear Codec + * + */ + +#include + +SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v_load); +SWITCH_MODULE_DEFINITION(mod_mp4v, mod_mp4v_load, NULL, NULL); + +static switch_status_t switch_mp4v_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings) +{ + int encoding, decoding; + + encoding = (flags & SWITCH_CODEC_FLAG_ENCODE); + decoding = (flags & SWITCH_CODEC_FLAG_DECODE); + + if (!(encoding || decoding)) { + return SWITCH_STATUS_FALSE; + } else { + if (codec->fmtp_in) { + codec->fmtp_out = switch_core_strdup(codec->memory_pool, codec->fmtp_in); + } + return SWITCH_STATUS_SUCCESS; + } +} + +static switch_status_t switch_mp4v_encode(switch_codec_t *codec, + switch_codec_t *other_codec, + void *decoded_data, + uint32_t decoded_data_len, + uint32_t decoded_rate, void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, + unsigned int *flag) +{ + return SWITCH_STATUS_FALSE; +} + +static switch_status_t switch_mp4v_decode(switch_codec_t *codec, + switch_codec_t *other_codec, + void *encoded_data, + uint32_t encoded_data_len, + uint32_t encoded_rate, void *decoded_data, uint32_t *decoded_data_len, uint32_t *decoded_rate, + unsigned int *flag) +{ + return SWITCH_STATUS_FALSE; +} + +static switch_status_t switch_mp4v_destroy(switch_codec_t *codec) +{ + return SWITCH_STATUS_SUCCESS; +} + +SWITCH_MODULE_LOAD_FUNCTION(mod_mp4v_load) +{ + switch_codec_interface_t *codec_interface; + /* connect my internal structure to the blank pointer passed to me */ + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + SWITCH_ADD_CODEC(codec_interface, "H.264 Video (passthru)"); + switch_core_codec_add_implementation(pool, codec_interface, + SWITCH_CODEC_TYPE_VIDEO, 99, "MP4V-ES", NULL, 90000, 90000, 0, + 0, 0, 0, 0, 1, 1, switch_mp4v_init, switch_mp4v_encode, switch_mp4v_decode, switch_mp4v_destroy); + /* indicate that the module should continue to be loaded */ + return SWITCH_STATUS_SUCCESS; +} + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ From 16ebeb0eb902ba91c14d94121cc109e5b720a451 Mon Sep 17 00:00:00 2001 From: cypromis Date: Fri, 23 Apr 2010 10:12:45 +0200 Subject: [PATCH 57/62] bumped spec file vrersion up to 1.0.7-trunk for trunk added skinny dialplan stuff to specfile --- freeswitch.spec | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/freeswitch.spec b/freeswitch.spec index 7f4212b50b..3522c8c0d0 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -9,8 +9,8 @@ Name: freeswitch Summary: FreeSWITCH open source telephony platform License: MPL Group: Productivity/Telephony/Servers -Version: 1.0.4 -Release: 1 +Version: 1.0.7 +Release: trunk URL: http://www.freeswitch.org/ Packager: Michal Bielicki Vendor: http://www.freeswitch.org/ @@ -355,6 +355,7 @@ fi %dir %attr(0750, freeswitch, daemon) %{prefix}/conf %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/autoload_configs %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/dialplan +%dir %attr(0750, freeswitch, daemon) %{prefix}/conf/dialplan/skinny-patterns %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/directory %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/directory/default %dir %attr(0750, freeswitch, daemon) %{prefix}/conf/lang @@ -430,6 +431,7 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/dialplan/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/dialplan/default/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/dialplan/public/*.xml +%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/dialplan/skinny-patterns %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/directory/*.xml %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/directory/default/* %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/ivr_menus/*.xml @@ -614,6 +616,9 @@ fi %config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/lang/ru/dir/*.xml %changelog +* Fr Apr 23 2010 - michal.bielicki@seventhsignal.de +- bumped spec file vrersion up to 1.0.7-trunk for trunk +- added skinny dialplan stuff to specfile * Sun Mar 28 2010 - michal.bielicki@seventhsignal.de - added sangoma codec config file * Wed Dec 02 2009 - michal.bielicki@seventhsignal.de From 1668597833caecdaae6baad444a6f1ee08c4f213 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 23 Apr 2010 10:28:13 -0400 Subject: [PATCH 58/62] freetdm: add IN_LOOP state to the state 2 str macro --- libs/freetdm/src/include/ftdm_types.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/freetdm/src/include/ftdm_types.h b/libs/freetdm/src/include/ftdm_types.h index bf7720efd1..a4f4eda047 100644 --- a/libs/freetdm/src/include/ftdm_types.h +++ b/libs/freetdm/src/include/ftdm_types.h @@ -383,7 +383,8 @@ typedef enum { } ftdm_channel_state_t; #define CHANNEL_STATE_STRINGS "DOWN", "HOLD", "SUSPENDED", "DIALTONE", "COLLECT", \ "RING", "BUSY", "ATTN", "GENRING", "DIALING", "GET_CALLERID", "CALLWAITING", \ - "RESTART", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", "HANGUP", "HANGUP_COMPLETE", "INVALID" + "RESTART", "PROGRESS", "PROGRESS_MEDIA", "UP", "IDLE", "TERMINATING", "CANCEL", \ + "HANGUP", "HANGUP_COMPLETE", "IN_LOOP", "INVALID" FTDM_STR2ENUM_P(ftdm_str2ftdm_channel_state, ftdm_channel_state2str, ftdm_channel_state_t) typedef enum { From cad7f7044232247e6afbe8f269b9c6af0c05cda0 Mon Sep 17 00:00:00 2001 From: Moises Silva Date: Fri, 23 Apr 2010 10:37:06 -0400 Subject: [PATCH 59/62] freetdm: handle_call_done must be called on call start nack ack when there is no call setup id --- .../ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c index a45c5189d3..fb061f44f7 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_boost/ftmod_sangoma_boost.c @@ -1312,6 +1312,8 @@ static int parse_sangoma_event(ftdm_span_t *span, sangomabc_connection_t *mcon, if (event->call_setup_id) { nack_map[event->call_setup_id] = 0; release_request_id(event->call_setup_id); + } else { + handle_call_done(span, mcon, event); } break; case SIGBOOST_EVENT_INSERT_CHECK_LOOP: @@ -1923,11 +1925,15 @@ static void ftdm_cli_span_state_cmd(ftdm_span_t *span, char *state) { unsigned j; int cnt=0; + ftdm_channel_state_t state_e = ftdm_str2ftdm_channel_state(state); + if (state_e == FTDM_CHANNEL_STATE_INVALID) { + ftdm_log(FTDM_LOG_CRIT, "Checking for channels not in the INVALID state is probably not waht you want\n"); + } for(j = 1; j <= span->chan_count; j++) { - if (span->channels[j]->state != FTDM_CHANNEL_STATE_DOWN) { + if (span->channels[j]->state != state_e) { ftdm_channel_t *ftdmchan = span->channels[j]; ftdm_log(FTDM_LOG_CRIT, "Channel %i s%dc%d State=%s\n", - j,ftdmchan->physical_span_id-1,ftdmchan->physical_chan_id-1,ftdm_channel_state2str(ftdmchan->state)); + j, ftdmchan->physical_span_id-1, ftdmchan->physical_chan_id-1, ftdm_channel_state2str(ftdmchan->state)); cnt++; } } From 6d80b3db1167da127437f7164b2e78affd81cac5 Mon Sep 17 00:00:00 2001 From: Brian West Date: Fri, 23 Apr 2010 10:22:54 -0500 Subject: [PATCH 60/62] swigall --- .../languages/mod_managed/freeswitch_wrap.cxx | 189 ++++++++++++++++- src/mod/languages/mod_managed/managed/swig.cs | 195 +++++++++++++++++- 2 files changed, 374 insertions(+), 10 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index 49fb617ef6..df84f3ae43 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -3244,6 +3244,140 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_rtp_hdr_t(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtcp_hdr_t_version_set(void * jarg1, unsigned int jarg2) { + switch_rtcp_hdr_t *arg1 = (switch_rtcp_hdr_t *) 0 ; + unsigned int arg2 ; + + arg1 = (switch_rtcp_hdr_t *)jarg1; + arg2 = (unsigned int)jarg2; + if (arg1) (arg1)->version = arg2; + +} + + +SWIGEXPORT unsigned int SWIGSTDCALL CSharp_switch_rtcp_hdr_t_version_get(void * jarg1) { + unsigned int jresult ; + switch_rtcp_hdr_t *arg1 = (switch_rtcp_hdr_t *) 0 ; + unsigned int result; + + arg1 = (switch_rtcp_hdr_t *)jarg1; + result = (unsigned int) ((arg1)->version); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtcp_hdr_t_p_set(void * jarg1, unsigned int jarg2) { + switch_rtcp_hdr_t *arg1 = (switch_rtcp_hdr_t *) 0 ; + unsigned int arg2 ; + + arg1 = (switch_rtcp_hdr_t *)jarg1; + arg2 = (unsigned int)jarg2; + if (arg1) (arg1)->p = arg2; + +} + + +SWIGEXPORT unsigned int SWIGSTDCALL CSharp_switch_rtcp_hdr_t_p_get(void * jarg1) { + unsigned int jresult ; + switch_rtcp_hdr_t *arg1 = (switch_rtcp_hdr_t *) 0 ; + unsigned int result; + + arg1 = (switch_rtcp_hdr_t *)jarg1; + result = (unsigned int) ((arg1)->p); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtcp_hdr_t_count_set(void * jarg1, unsigned int jarg2) { + switch_rtcp_hdr_t *arg1 = (switch_rtcp_hdr_t *) 0 ; + unsigned int arg2 ; + + arg1 = (switch_rtcp_hdr_t *)jarg1; + arg2 = (unsigned int)jarg2; + if (arg1) (arg1)->count = arg2; + +} + + +SWIGEXPORT unsigned int SWIGSTDCALL CSharp_switch_rtcp_hdr_t_count_get(void * jarg1) { + unsigned int jresult ; + switch_rtcp_hdr_t *arg1 = (switch_rtcp_hdr_t *) 0 ; + unsigned int result; + + arg1 = (switch_rtcp_hdr_t *)jarg1; + result = (unsigned int) ((arg1)->count); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtcp_hdr_t_type_set(void * jarg1, unsigned int jarg2) { + switch_rtcp_hdr_t *arg1 = (switch_rtcp_hdr_t *) 0 ; + unsigned int arg2 ; + + arg1 = (switch_rtcp_hdr_t *)jarg1; + arg2 = (unsigned int)jarg2; + if (arg1) (arg1)->type = arg2; + +} + + +SWIGEXPORT unsigned int SWIGSTDCALL CSharp_switch_rtcp_hdr_t_type_get(void * jarg1) { + unsigned int jresult ; + switch_rtcp_hdr_t *arg1 = (switch_rtcp_hdr_t *) 0 ; + unsigned int result; + + arg1 = (switch_rtcp_hdr_t *)jarg1; + result = (unsigned int) ((arg1)->type); + jresult = result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtcp_hdr_t_length_set(void * jarg1, unsigned int jarg2) { + switch_rtcp_hdr_t *arg1 = (switch_rtcp_hdr_t *) 0 ; + unsigned int arg2 ; + + arg1 = (switch_rtcp_hdr_t *)jarg1; + arg2 = (unsigned int)jarg2; + if (arg1) (arg1)->length = arg2; + +} + + +SWIGEXPORT unsigned int SWIGSTDCALL CSharp_switch_rtcp_hdr_t_length_get(void * jarg1) { + unsigned int jresult ; + switch_rtcp_hdr_t *arg1 = (switch_rtcp_hdr_t *) 0 ; + unsigned int result; + + arg1 = (switch_rtcp_hdr_t *)jarg1; + result = (unsigned int) ((arg1)->length); + jresult = result; + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_rtcp_hdr_t() { + void * jresult ; + switch_rtcp_hdr_t *result = 0 ; + + result = (switch_rtcp_hdr_t *)new switch_rtcp_hdr_t(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_rtcp_hdr_t(void * jarg1) { + switch_rtcp_hdr_t *arg1 = (switch_rtcp_hdr_t *) 0 ; + + arg1 = (switch_rtcp_hdr_t *)jarg1; + delete arg1; + +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_t38_options_t_T38MaxBitRate_set(void * jarg1, unsigned long jarg2) { switch_t38_options_t *arg1 = (switch_t38_options_t *) 0 ; uint32_t arg2 ; @@ -25900,6 +26034,17 @@ SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_RTP_MAX_BUF_LEN_get() { } +SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_RTCP_MAX_BUF_LEN_get() { + int jresult ; + int result; + + result = (int) 16384; + + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_SWITCH_RTP_MAX_CRYPTO_LEN_get() { int jresult ; int result; @@ -26288,21 +26433,23 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_new(char * jarg1, unsigned short } -SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_set_remote_address(void * jarg1, char * jarg2, unsigned short jarg3, int jarg4, void * jarg5) { +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_set_remote_address(void * jarg1, char * jarg2, unsigned short jarg3, unsigned short jarg4, int jarg5, void * jarg6) { int jresult ; switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; char *arg2 = (char *) 0 ; switch_port_t arg3 ; - switch_bool_t arg4 ; - char **arg5 = (char **) 0 ; + switch_port_t arg4 ; + switch_bool_t arg5 ; + char **arg6 = (char **) 0 ; switch_status_t result; arg1 = (switch_rtp_t *)jarg1; arg2 = (char *)jarg2; arg3 = (switch_port_t)jarg3; - arg4 = (switch_bool_t)jarg4; - arg5 = (char **)jarg5; - result = (switch_status_t)switch_rtp_set_remote_address(arg1,(char const *)arg2,arg3,arg4,(char const **)arg5); + arg4 = (switch_port_t)jarg4; + arg5 = (switch_bool_t)jarg5; + arg6 = (char **)jarg6; + result = (switch_status_t)switch_rtp_set_remote_address(arg1,(char const *)arg2,arg3,arg4,arg5,(char const **)arg6); jresult = result; return jresult; } @@ -26420,6 +26567,22 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_ice(void * jarg1, char * j } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_rtcp(void * jarg1, int jarg2, unsigned short jarg3) { + int jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + int arg2 ; + switch_port_t arg3 ; + switch_status_t result; + + arg1 = (switch_rtp_t *)jarg1; + arg2 = (int)jarg2; + arg3 = (switch_port_t)jarg3; + result = (switch_status_t)switch_rtp_activate_rtcp(arg1,arg2,arg3); + jresult = result; + return jresult; +} + + SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_activate_jitter_buffer(void * jarg1, unsigned long jarg2) { int jresult ; switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; @@ -26638,6 +26801,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtp_zerocopy_read_frame(void * jarg1, v } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_rtcp_zerocopy_read_frame(void * jarg1, void * jarg2) { + int jresult ; + switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; + switch_rtcp_frame_t *arg2 = (switch_rtcp_frame_t *) 0 ; + switch_status_t result; + + arg1 = (switch_rtp_t *)jarg1; + arg2 = (switch_rtcp_frame_t *)jarg2; + result = (switch_status_t)switch_rtcp_zerocopy_read_frame(arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT void SWIGSTDCALL CSharp_rtp_flush_read_buffer(void * jarg1, int jarg2) { switch_rtp_t *arg1 = (switch_rtp_t *) 0 ; switch_rtp_flush_t arg2 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 1821bbb088..66be726ebd 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -4056,8 +4056,8 @@ public class freeswitch { return ret; } - public static switch_status_t switch_rtp_set_remote_address(SWIGTYPE_p_switch_rtp rtp_session, string host, ushort port, switch_bool_t change_adv_addr, ref string err) { - switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_set_remote_address(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), host, port, (int)change_adv_addr, ref err); + public static switch_status_t switch_rtp_set_remote_address(SWIGTYPE_p_switch_rtp rtp_session, string host, ushort port, ushort remote_rtcp_port, switch_bool_t change_adv_addr, ref string err) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_set_remote_address(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), host, port, remote_rtcp_port, (int)change_adv_addr, ref err); return ret; } @@ -4106,6 +4106,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_rtp_activate_rtcp(SWIGTYPE_p_switch_rtp rtp_session, int send_rate, ushort remote_port) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_activate_rtcp(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), send_rate, remote_port); + return ret; + } + public static switch_status_t switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp rtp_session, uint queue_frames) { switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtp_activate_jitter_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), queue_frames); return ret; @@ -4183,6 +4188,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_rtcp_zerocopy_read_frame(SWIGTYPE_p_switch_rtp rtp_session, SWIGTYPE_p_switch_rtcp_frame frame) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_rtcp_zerocopy_read_frame(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), SWIGTYPE_p_switch_rtcp_frame.getCPtr(frame)); + return ret; + } + public static void rtp_flush_read_buffer(SWIGTYPE_p_switch_rtp rtp_session, switch_rtp_flush_t flush) { freeswitchPINVOKE.rtp_flush_read_buffer(SWIGTYPE_p_switch_rtp.getCPtr(rtp_session), (int)flush); } @@ -4914,6 +4924,7 @@ public class freeswitch { public static readonly int SWITCH_SMIN = freeswitchPINVOKE.SWITCH_SMIN_get(); public static readonly int SWITCH_RESAMPLE_QUALITY = freeswitchPINVOKE.SWITCH_RESAMPLE_QUALITY_get(); public static readonly int SWITCH_RTP_MAX_BUF_LEN = freeswitchPINVOKE.SWITCH_RTP_MAX_BUF_LEN_get(); + public static readonly int SWITCH_RTCP_MAX_BUF_LEN = freeswitchPINVOKE.SWITCH_RTCP_MAX_BUF_LEN_get(); public static readonly int SWITCH_RTP_MAX_CRYPTO_LEN = freeswitchPINVOKE.SWITCH_RTP_MAX_CRYPTO_LEN_get(); public static readonly int SWITCH_RTP_KEY_LEN = freeswitchPINVOKE.SWITCH_RTP_KEY_LEN_get(); public static readonly string SWITCH_RTP_CRYPTO_KEY_32 = freeswitchPINVOKE.SWITCH_RTP_CRYPTO_KEY_32_get(); @@ -5866,6 +5877,42 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_rtp_hdr_t")] public static extern void delete_switch_rtp_hdr_t(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_hdr_t_version_set")] + public static extern void switch_rtcp_hdr_t_version_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_hdr_t_version_get")] + public static extern uint switch_rtcp_hdr_t_version_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_hdr_t_p_set")] + public static extern void switch_rtcp_hdr_t_p_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_hdr_t_p_get")] + public static extern uint switch_rtcp_hdr_t_p_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_hdr_t_count_set")] + public static extern void switch_rtcp_hdr_t_count_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_hdr_t_count_get")] + public static extern uint switch_rtcp_hdr_t_count_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_hdr_t_type_set")] + public static extern void switch_rtcp_hdr_t_type_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_hdr_t_type_get")] + public static extern uint switch_rtcp_hdr_t_type_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_hdr_t_length_set")] + public static extern void switch_rtcp_hdr_t_length_set(HandleRef jarg1, uint jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_hdr_t_length_get")] + public static extern uint switch_rtcp_hdr_t_length_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_rtcp_hdr_t")] + public static extern IntPtr new_switch_rtcp_hdr_t(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_rtcp_hdr_t")] + public static extern void delete_switch_rtcp_hdr_t(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_t38_options_t_T38MaxBitRate_set")] public static extern void switch_t38_options_t_T38MaxBitRate_set(HandleRef jarg1, uint jarg2); @@ -11152,6 +11199,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_RTP_MAX_BUF_LEN_get")] public static extern int SWITCH_RTP_MAX_BUF_LEN_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_RTCP_MAX_BUF_LEN_get")] + public static extern int SWITCH_RTCP_MAX_BUF_LEN_get(); + [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_RTP_MAX_CRYPTO_LEN_get")] public static extern int SWITCH_RTP_MAX_CRYPTO_LEN_get(); @@ -11240,7 +11290,7 @@ class freeswitchPINVOKE { public static extern IntPtr switch_rtp_new(string jarg1, ushort jarg2, string jarg3, ushort jarg4, byte jarg5, uint jarg6, uint jarg7, uint jarg8, string jarg9, ref string jarg10, HandleRef jarg11); [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_set_remote_address")] - public static extern int switch_rtp_set_remote_address(HandleRef jarg1, string jarg2, ushort jarg3, int jarg4, ref string jarg5); + public static extern int switch_rtp_set_remote_address(HandleRef jarg1, string jarg2, ushort jarg3, ushort jarg4, int jarg5, ref string jarg6); [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_get_remote_host")] public static extern string switch_rtp_get_remote_host(HandleRef jarg1); @@ -11272,6 +11322,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_activate_ice")] public static extern int switch_rtp_activate_ice(HandleRef jarg1, string jarg2, string jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_activate_rtcp")] + public static extern int switch_rtp_activate_rtcp(HandleRef jarg1, int jarg2, ushort jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_activate_jitter_buffer")] public static extern int switch_rtp_activate_jitter_buffer(HandleRef jarg1, uint jarg2); @@ -11320,6 +11373,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_zerocopy_read_frame")] public static extern int switch_rtp_zerocopy_read_frame(HandleRef jarg1, HandleRef jarg2, uint jarg3); + [DllImport("mod_managed", EntryPoint="CSharp_switch_rtcp_zerocopy_read_frame")] + public static extern int switch_rtcp_zerocopy_read_frame(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_rtp_flush_read_buffer")] public static extern void rtp_flush_read_buffer(HandleRef jarg1, int jarg2); @@ -16855,6 +16911,36 @@ namespace FreeSWITCH.Native { using System; using System.Runtime.InteropServices; +public class SWIGTYPE_p_switch_rtcp_frame { + private HandleRef swigCPtr; + + internal SWIGTYPE_p_switch_rtcp_frame(IntPtr cPtr, bool futureUse) { + swigCPtr = new HandleRef(this, cPtr); + } + + protected SWIGTYPE_p_switch_rtcp_frame() { + swigCPtr = new HandleRef(null, IntPtr.Zero); + } + + internal static HandleRef getCPtr(SWIGTYPE_p_switch_rtcp_frame obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + +using System; +using System.Runtime.InteropServices; + public class SWIGTYPE_p_switch_rtp { private HandleRef swigCPtr; @@ -21473,6 +21559,7 @@ public enum switch_core_session_message_types_t { SWITCH_MESSAGE_INDICATE_PROXY_MEDIA, SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC, SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC_COMPLETE, + SWITCH_MESSAGE_INDICATE_PHONE_EVENT, SWITCH_MESSAGE_INVALID } @@ -22861,6 +22948,7 @@ public enum switch_event_types_t { SWITCH_EVENT_SERVER_DISCONNECTED, SWITCH_EVENT_SEND_INFO, SWITCH_EVENT_RECV_INFO, + SWITCH_EVENT_RECV_RTCP_MESSAGE, SWITCH_EVENT_CALL_SECURE, SWITCH_EVENT_NAT, SWITCH_EVENT_RECORD_START, @@ -25770,6 +25858,103 @@ public enum switch_priority_t { namespace FreeSWITCH.Native { +using System; +using System.Runtime.InteropServices; + +public class switch_rtcp_hdr_t : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_rtcp_hdr_t(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_rtcp_hdr_t obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_rtcp_hdr_t() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_rtcp_hdr_t(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public uint version { + set { + freeswitchPINVOKE.switch_rtcp_hdr_t_version_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_rtcp_hdr_t_version_get(swigCPtr); + return ret; + } + } + + public uint p { + set { + freeswitchPINVOKE.switch_rtcp_hdr_t_p_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_rtcp_hdr_t_p_get(swigCPtr); + return ret; + } + } + + public uint count { + set { + freeswitchPINVOKE.switch_rtcp_hdr_t_count_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_rtcp_hdr_t_count_get(swigCPtr); + return ret; + } + } + + public uint type { + set { + freeswitchPINVOKE.switch_rtcp_hdr_t_type_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_rtcp_hdr_t_type_get(swigCPtr); + return ret; + } + } + + public uint length { + set { + freeswitchPINVOKE.switch_rtcp_hdr_t_length_set(swigCPtr, value); + } + get { + uint ret = freeswitchPINVOKE.switch_rtcp_hdr_t_length_get(swigCPtr); + return ret; + } + } + + public switch_rtcp_hdr_t() : this(freeswitchPINVOKE.new_switch_rtcp_hdr_t(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + public enum switch_rtp_bug_flag_t { RTP_BUG_NONE = 0, RTP_BUG_CISCO_SKIP_MARK_BIT_2833 = (1 << 0), @@ -25953,7 +26138,9 @@ namespace FreeSWITCH.Native { SWITCH_ZRTP_FLAG_SECURE_MITM_RECV = (1 << 26), SWITCH_RTP_FLAG_DEBUG_RTP_READ = (1 << 27), SWITCH_RTP_FLAG_DEBUG_RTP_WRITE = (1 << 28), - SWITCH_RTP_FLAG_VIDEO = (1 << 29) + SWITCH_RTP_FLAG_VIDEO = (1 << 29), + SWITCH_RTP_FLAG_ENABLE_RTCP = (1 << 30), + SWITCH_RTP_FLAG_RTCP_PASSTHRU = (1 << 31) } } From 8a4a09838cd70de1d0738607d18c2a43925e442d Mon Sep 17 00:00:00 2001 From: cseket Date: Fri, 23 Apr 2010 19:16:55 +0200 Subject: [PATCH 61/62] fix windows build (MODEVENT-63) --- .../event_handlers/mod_json_cdr/mod_json_cdr.2008.vcproj | 2 +- src/mod/event_handlers/mod_json_cdr/mod_json_cdr.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.2008.vcproj b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.2008.vcproj index 1af8141191..d330aba5d8 100644 --- a/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.2008.vcproj +++ b/src/mod/event_handlers/mod_json_cdr/mod_json_cdr.2008.vcproj @@ -104,7 +104,7 @@ /> Date: Fri, 23 Apr 2010 12:14:37 -0500 Subject: [PATCH 62/62] add sanity check to launch threads that catch hangup and are not in a thread to make sure they clean up --- src/switch_channel.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/switch_channel.c b/src/switch_channel.c index 345d4e791a..acefec30dc 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2108,6 +2108,11 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_hangup(switch_chan switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_NOTICE, "Hangup %s [%s] [%s]\n", channel->name, state_names[last_state], switch_channel_cause2str(channel->hangup_cause)); + + if (!switch_core_session_running(channel->session)) { + switch_core_session_thread_launch(channel->session); + } + if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_HANGUP) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Hangup-Cause", switch_channel_cause2str(hangup_cause)); switch_channel_event_set_data(channel, event);