Merge branch 'nsg-4.3' of git.sangoma.com:smg_freeswitch into nsg-4.3

Conflicts:
	src/mod/endpoints/mod_media_gateway/mod_media_gateway.h
This commit is contained in:
Mathieu Rene
2012-07-25 15:11:42 -04:00
806 changed files with 63433 additions and 81499 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+9 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -120,6 +120,7 @@ struct switch_core_session {
switch_codec_t *video_write_codec;
switch_codec_implementation_t read_impl;
switch_codec_implementation_t real_read_impl;
switch_codec_implementation_t write_impl;
switch_codec_implementation_t video_read_impl;
switch_codec_implementation_t video_write_impl;
@@ -171,6 +172,8 @@ struct switch_core_session {
uint32_t soft_lock;
switch_ivr_dmachine_t *dmachine[2];
plc_state_t *plc;
uint8_t recur_buffer[SWITCH_RECOMMENDED_BUFFER_SIZE];
switch_size_t recur_buffer_len;
};
struct switch_media_bug {
@@ -199,6 +202,7 @@ struct switch_media_bug {
uint32_t record_pre_buffer_count;
uint32_t record_pre_buffer_max;
switch_frame_t *ping_frame;
switch_frame_t *read_demux_frame;
struct switch_media_bug *next;
};
@@ -261,6 +265,10 @@ struct switch_runtime {
uint32_t db_handle_timeout;
int cpu_count;
uint32_t time_sync;
char *core_db_pre_trans_execute;
char *core_db_post_trans_execute;
char *core_db_inner_pre_trans_execute;
char *core_db_inner_post_trans_execute;
};
extern struct switch_runtime runtime;
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+8 -2
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1605,8 +1605,14 @@ SWITCH_DECLARE(switch_status_t) switch_thread_exit(switch_thread_t *thd, switch_
*/
SWITCH_DECLARE(switch_status_t) switch_thread_join(switch_status_t *retval, switch_thread_t *thd);
/** @} */
/**
* Return a human readable string describing the specified error.
* @param statcode The error code the get a string for.
* @param buf A buffer to hold the error string.
* @bufsize Size of the buffer to hold the string.
*/
SWITCH_DECLARE(char *) switch_strerror(switch_status_t statcode, char *buf, switch_size_t bufsize);
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+5 -3
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -273,6 +273,7 @@ SWITCH_DECLARE(const char *) switch_channel_get_hold_music_partner(switch_channe
SWITCH_DECLARE(uint32_t) switch_channel_del_variable_prefix(switch_channel_t *channel, const char *prefix);
#define switch_channel_set_variable_safe(_channel, _var, _val) switch_channel_set_variable_var_check(_channel, _var, _val, SWITCH_FALSE)
#define switch_channel_set_variable(_channel, _var, _val) switch_channel_set_variable_var_check(_channel, _var, _val, SWITCH_TRUE)
#define switch_channel_set_variable_partner(_channel, _var, _val) switch_channel_set_variable_partner_var_check(_channel, _var, _val, SWITCH_TRUE)
@@ -592,8 +593,8 @@ SWITCH_DECLARE(void) switch_channel_event_set_extended_data(_In_ switch_channel_
\return the original string if no expansion takes place otherwise a new string that must be freed
\note it's necessary to test if the return val is the same as the input and free the string if it is not.
*/
SWITCH_DECLARE(char *) switch_channel_expand_variables_check(switch_channel_t *channel, const char *in, switch_event_t *var_list, switch_event_t *api_list);
#define switch_channel_expand_variables(_channel, _in) switch_channel_expand_variables_check(_channel, _in, NULL, NULL)
SWITCH_DECLARE(char *) switch_channel_expand_variables_check(switch_channel_t *channel, const char *in, switch_event_t *var_list, switch_event_t *api_list, uint32_t recur);
#define switch_channel_expand_variables(_channel, _in) switch_channel_expand_variables_check(_channel, _in, NULL, NULL, 0)
SWITCH_DECLARE(char *) switch_channel_build_param_string(_In_ switch_channel_t *channel, _In_opt_ switch_caller_profile_t *caller_profile,
@@ -640,6 +641,7 @@ SWITCH_DECLARE(switch_status_t) switch_channel_api_on(switch_channel_t *channel,
SWITCH_DECLARE(switch_caller_extension_t *) switch_channel_get_queued_extension(switch_channel_t *channel);
SWITCH_DECLARE(void) switch_channel_transfer_to_extension(switch_channel_t *channel, switch_caller_extension_t *caller_extension);
SWITCH_DECLARE(const char *) switch_channel_get_partner_uuid(switch_channel_t *channel);
SWITCH_END_EXTERN_C
#endif
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+17 -4
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -137,6 +137,11 @@ SWITCH_DECLARE(void) switch_core_session_disable_heartbeat(switch_core_session_t
#define switch_core_session_get_name(_s) switch_channel_get_name(switch_core_session_get_channel(_s))
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_pop(switch_core_session_t *orig_session, const char *function, switch_media_bug_t **pop);
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_exec_all(switch_core_session_t *orig_session,
const char *function, switch_media_bug_exec_cb_t cb, void *user_data);
SWITCH_DECLARE(uint32_t) switch_core_media_bug_count(switch_core_session_t *orig_session, const char *function);
/*!
\brief Add a media bug to the session
\param session the session to add the bug to
@@ -193,7 +198,7 @@ SWITCH_DECLARE(void) switch_core_media_bug_set_write_replace_frame(_In_ switch_m
\param bug the bug to get the data from
*/
SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_read_replace_frame(_In_ switch_media_bug_t *bug);
SWITCH_DECLARE(void) switch_core_media_bug_set_read_demux_frame(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame);
/*!
\brief Obtain the session from a media bug
\param bug the bug to get the data from
@@ -225,6 +230,7 @@ SWITCH_DECLARE(uint32_t) switch_core_cpu_count(void);
\param bug bug to remove
\return SWITCH_STATUS_SUCCESS if the operation was a success
*/
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove(_In_ switch_core_session_t *session, _Inout_ switch_media_bug_t **bug);
SWITCH_DECLARE(uint32_t) switch_core_media_bug_prune(switch_core_session_t *session);
@@ -247,7 +253,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_close(_Inout_ switch_media
\param session the session to remove the bugs from
\return SWITCH_STATUS_SUCCESS if the operation was a success
*/
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove_all(_In_ switch_core_session_t *session);
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_remove_all_function(_In_ switch_core_session_t *session, const char *function);
#define switch_core_media_bug_remove_all(_s) switch_core_media_bug_remove_all_function(_s, NULL)
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_enumerate(switch_core_session_t *session, switch_stream_handle_t *stream);
SWITCH_DECLARE(switch_status_t) switch_core_media_bug_transfer_recordings(switch_core_session_t *orig_session, switch_core_session_t *new_session);
@@ -1492,6 +1500,7 @@ SWITCH_DECLARE(void) switch_core_session_unlock_codec_read(_In_ switch_core_sess
SWITCH_DECLARE(switch_status_t) switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp);
SWITCH_DECLARE(switch_status_t) switch_core_session_get_real_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp);
SWITCH_DECLARE(switch_status_t) switch_core_session_get_write_impl(switch_core_session_t *session, switch_codec_implementation_t *impp);
SWITCH_DECLARE(switch_status_t) switch_core_session_get_video_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp);
SWITCH_DECLARE(switch_status_t) switch_core_session_get_video_write_impl(switch_core_session_t *session, switch_codec_implementation_t *impp);
@@ -2291,10 +2300,12 @@ SWITCH_DECLARE(uint32_t) switch_default_ptime(const char *name, uint32_t number)
\param [in] network_ip
\param [in] network_port
\param [in] network_proto - one of tls, tcp, udp
\param [in] metadata - generic metadata supplied by module
\param [out] err - Error if it exists
*/
SWITCH_DECLARE(switch_status_t) switch_core_add_registration(const char *user, const char *realm, const char *token, const char *url, uint32_t expires,
const char *network_ip, const char *network_port, const char *network_proto);
const char *network_ip, const char *network_port, const char *network_proto,
const char *metadata);
/*!
\brief Delete user registration
\param [in] user
@@ -2319,6 +2330,8 @@ SWITCH_DECLARE(switch_status_t) switch_say_file_handle_create(switch_say_file_ha
SWITCH_DECLARE(void) switch_say_file(switch_say_file_handle_t *sh, const char *fmt, ...);
SWITCH_DECLARE(int) switch_max_file_desc(void);
SWITCH_DECLARE(void) switch_close_extra_files(int *keep, int keep_ttl);
SWITCH_DECLARE(switch_status_t) switch_core_thread_set_cpu_affinity(int cpu);
SWITCH_DECLARE(void) switch_os_yield(void);
SWITCH_END_EXTERN_C
#endif
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+5 -3
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -330,8 +330,8 @@ SWITCH_DECLARE(switch_status_t) switch_event_add_body(switch_event_t *event, con
SWITCH_DECLARE(switch_status_t) switch_event_set_body(switch_event_t *event, const char *body);
SWITCH_DECLARE(char *) switch_event_expand_headers_check(switch_event_t *event, const char *in, switch_event_t *var_list, switch_event_t *api_list);
#define switch_event_expand_headers(_event, _in) switch_event_expand_headers_check(_event, _in, NULL, NULL)
SWITCH_DECLARE(char *) switch_event_expand_headers_check(switch_event_t *event, const char *in, switch_event_t *var_list, switch_event_t *api_list, uint32_t recur);
#define switch_event_expand_headers(_event, _in) switch_event_expand_headers_check(_event, _in, NULL, NULL, 0)
SWITCH_DECLARE(switch_status_t) switch_event_create_pres_in_detailed(_In_z_ char *file, _In_z_ char *func, _In_ int line,
_In_z_ const char *proto, _In_z_ const char *login,
@@ -402,6 +402,8 @@ SWITCH_DECLARE(void) switch_event_deliver(switch_event_t **event);
SWITCH_DECLARE(char *) switch_event_build_param_string(switch_event_t *event, const char *prefix, switch_hash_t *vars_map);
SWITCH_DECLARE(int) switch_event_check_permission_list(switch_event_t *list, const char *name);
SWITCH_DECLARE(void) switch_event_add_presence_data_cols(switch_channel_t *channel, switch_event_t *event, const char *prefix);
///\}
SWITCH_END_EXTERN_C
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+16 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -41,6 +41,7 @@
#define SWITCH_IVR_H
#include <switch.h>
#include "switch_json.h"
SWITCH_BEGIN_EXTERN_C struct switch_unicast_conninfo {
switch_core_session_t *session;
@@ -82,6 +83,14 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_activate_unicast(switch_core_session_
char *local_ip,
switch_port_t local_port,
char *remote_ip, switch_port_t remote_port, char *transport, char *flags);
/*!
\brief Generate an JSON CDR report.
\param session the session to get the data from.
\param json_cdr pointer to the json object
\return SWITCH_STATUS_SUCCESS if successful
\note on success the json object must be freed
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_generate_json_cdr(switch_core_session_t *session, cJSON **json_cdr, switch_bool_t urlencode);
/*!
\brief Generate an XML CDR report.
@@ -269,6 +278,11 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_detect_speech_start_input_timers(swit
*/
SWITCH_DECLARE(switch_status_t) switch_ivr_record_session(switch_core_session_t *session, char *file, uint32_t limit, switch_file_handle_t *fh);
SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_pop_eavesdropper(switch_core_session_t *session, switch_core_session_t **sessionp);
SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_exec_all(switch_core_session_t *session, const char *app, const char *arg);
SWITCH_DECLARE(switch_status_t) switch_ivr_eavesdrop_update_display(switch_core_session_t *session, const char *name, const char *number);
/*!
\brief Eavesdrop on a another session
\param session our session
@@ -956,6 +970,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_insert_file(switch_core_session_t *se
SWITCH_DECLARE(switch_status_t) switch_ivr_create_message_reply(switch_event_t **reply, switch_event_t *message, const char *new_proto);
SWITCH_DECLARE(char *) switch_ivr_check_presence_mapping(const char *exten_name, const char *domain_name);
SWITCH_DECLARE(switch_status_t) switch_ivr_kill_uuid(const char *uuid, switch_call_cause_t cause);
SWITCH_DECLARE(switch_status_t) switch_ivr_blind_transfer_ack(switch_core_session_t *session, switch_bool_t success);
/** @} */
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+3 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -115,6 +115,8 @@ SWITCH_DECLARE(switch_endpoint_interface_t *) switch_loadable_module_get_endpoin
*/
SWITCH_DECLARE(switch_codec_interface_t *) switch_loadable_module_get_codec_interface(const char *name);
SWITCH_DECLARE(char *) switch_parse_codec_buf(char *buf, uint32_t *interval, uint32_t *rate, uint32_t *bit);
/*!
\brief Retrieve the dialplan interface by it's registered name
\param name the name of the dialplan
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+5 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -258,8 +258,12 @@ typedef intptr_t switch_ssize_t;
#endif
#ifndef TIME_T_FMT
#if defined(__FreeBSD__) && SIZEOF_VOIDP == 4
#define TIME_T_FMT "d"
#else
#define TIME_T_FMT "ld"
#endif
#endif
#endif
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -170,7 +170,7 @@ SWITCH_DECLARE(void) switch_change_sln_volume_granular(int16_t *data, uint32_t s
///\}
SWITCH_DECLARE(uint32_t) switch_merge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples);
SWITCH_DECLARE(uint32_t) switch_unmerge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples);
SWITCH_DECLARE(void) switch_mux_channels(int16_t *data, switch_size_t samples, uint32_t channels);
SWITCH_END_EXTERN_C
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+2 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -461,6 +461,7 @@ SWITCH_DECLARE(void) switch_rtp_intentional_bugs(switch_rtp_t *rtp_session, swit
SWITCH_DECLARE(switch_rtp_stats_t *) switch_rtp_get_stats(switch_rtp_t *rtp_session, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_byte_t) switch_rtp_check_auto_adj(switch_rtp_t *rtp_session);
SWITCH_DECLARE(void) switch_rtp_set_interdigit_delay(switch_rtp_t *rtp_session, uint32_t delay);
/*!
\}
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+17 -4
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -129,7 +129,9 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_ENABLE_HEARTBEAT_EVENTS_VARIABLE "enable_heartbeat_events"
#define SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE "bypass_media_after_bridge"
#define SWITCH_READ_RESULT_VARIABLE "read_result"
#define SWITCH_ATT_XFER_RESULT_VARIABLE "att_xfer_result"
#define SWITCH_COPY_XML_CDR_VARIABLE "copy_xml_cdr"
#define SWITCH_COPY_JSON_CDR_VARIABLE "copy_json_cdr"
#define SWITCH_CURRENT_APPLICATION_VARIABLE "current_application"
#define SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE "proto_specific_hangup_cause"
#define SWITCH_TRANSFER_HISTORY_VARIABLE "transfer_history"
@@ -168,6 +170,7 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME "__cache_speech_handles_obj__"
#define SWITCH_BYPASS_MEDIA_VARIABLE "bypass_media"
#define SWITCH_PROXY_MEDIA_VARIABLE "proxy_media"
#define SWITCH_ZRTP_PASSTHRU_VARIABLE "zrtp_passthru"
#define SWITCH_ENDPOINT_DISPOSITION_VARIABLE "endpoint_disposition"
#define SWITCH_HOLD_MUSIC_VARIABLE "hold_music"
#define SWITCH_TEMP_HOLD_MUSIC_VARIABLE "temp_hold_music"
@@ -180,6 +183,7 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_LAST_BRIDGE_VARIABLE "last_bridge_to"
#define SWITCH_SIGNAL_BRIDGE_VARIABLE "signal_bridge_to"
#define SWITCH_SIGNAL_BOND_VARIABLE "signal_bond"
#define SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE "originate_signal_bond"
#define SWITCH_ORIGINATOR_VARIABLE "originator"
#define SWITCH_ORIGINATOR_CODEC_VARIABLE "originator_codec"
#define SWITCH_ORIGINATOR_VIDEO_CODEC_VARIABLE "originator_video_codec"
@@ -287,7 +291,8 @@ typedef enum {
ED_NONE = 0,
ED_MUX_READ = (1 << 0),
ED_MUX_WRITE = (1 << 1),
ED_DTMF = (1 << 2)
ED_DTMF = (1 << 2),
ED_COPY_DISPLAY = (1 << 3)
} switch_eavesdrop_flag_enum_t;
typedef uint32_t switch_eavesdrop_flag_t;
@@ -885,6 +890,7 @@ typedef enum {
SWITCH_MESSAGE_INDICATE_SIGNAL_DATA,
SWITCH_MESSAGE_INDICATE_INFO,
SWITCH_MESSAGE_INDICATE_AUDIO_DATA,
SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE,
SWITCH_MESSAGE_INVALID
} switch_core_session_message_types_t;
@@ -1210,8 +1216,12 @@ typedef enum {
CF_VIDEO_REFRESH_REQ,
CF_SERVICE_AUDIO,
CF_SERVICE_VIDEO,
CF_ZRTP_PASSTHRU_REQ,
CF_ZRTP_PASSTHRU,
CF_ZRTP_HASH,
CF_ZRTP_PASS,
CF_CHANNEL_SWAP,
CF_PICKUP,
CF_CONFIRM_BLIND_TRANSFER,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
/* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
CF_FLAG_MAX
@@ -1432,7 +1442,8 @@ typedef enum {
SMBF_THREAD_LOCK = (1 << 7),
SMBF_PRUNE = (1 << 8),
SMBF_NO_PAUSE = (1 << 9),
SMBF_STEREO_SWAP = (1 << 10)
SMBF_STEREO_SWAP = (1 << 10),
SMBF_LOCK = (1 << 11)
} switch_media_bug_flag_enum_t;
typedef uint32_t switch_media_bug_flag_t;
@@ -1819,6 +1830,8 @@ struct switch_console_callback_match {
};
typedef struct switch_console_callback_match switch_console_callback_match_t;
typedef void (*switch_media_bug_exec_cb_t)(switch_media_bug_t *bug, void *user_data);
typedef void (*switch_cap_callback_t) (const char *var, const char *val, void *user_data);
typedef switch_status_t (*switch_console_complete_callback_t) (const char *, const char *, switch_console_callback_match_t **matches);
typedef switch_bool_t (*switch_media_bug_callback_t) (switch_media_bug_t *, void *, switch_abc_type_t);
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005/2006, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005/2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005/2006, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005/2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -214,7 +214,7 @@ SWITCH_DECLARE(switch_xml_t) switch_xml_get(_In_ switch_xml_t xml,...);
///\param prn_header add <?xml version..> header too
///\return the xml text string
SWITCH_DECLARE(char *) switch_xml_toxml(_In_ switch_xml_t xml, _In_ switch_bool_t prn_header);
SWITCH_DECLARE(char *) switch_xml_toxml_nolock(switch_xml_t xml, _In_ switch_bool_t prn_header);
///\brief Converts an switch_xml structure back to xml using the buffer passed in the parameters.
///\param xml the xml node
///\param buf buffer to use
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+3
View File
@@ -14,6 +14,7 @@
/applications/mod_fax/mod_fax.log
/applications/mod_fifo/Makefile
/applications/mod_fsv/Makefile
/applications/mod_httapi/Makefile
/applications/mod_limit/Makefile
/applications/mod_sms/Makefile
/applications/mod_spandsp/Makefile
@@ -62,5 +63,7 @@
/loggers/mod_logfile/Makefile
/loggers/mod_syslog/Makefile
/say/mod_say_en/Makefile
/say/mod_say_ja/Makefile
/say/mod_say_ru/Makefile
/timers/mod_posix_timer/Makefile
/timers/mod_timerfd/Makefile
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+53 -55
View File
@@ -59,13 +59,17 @@
#define TO_HZ(r, f) (((r) * (f)) / (2.0 * M_PI))
/*! Minimum beep frequency in Hertz */
#define MIN_FREQUENCY (300.0)
#define MIN_FREQUENCY_R(r) ((2.0 * M_PI * MIN_FREQUENCY) / (r))
/*! Maximum beep frequency in Hertz */
#define MAX_FREQUENCY (1500.0)
#define MAX_FREQUENCY (2500.0)
#define MAX_FREQUENCY_R(r) ((2.0 * M_PI * MAX_FREQUENCY) / (r))
/* decrease this value to eliminate false positives */
#define VARIANCE_THRESHOLD (0.001)
#include "amplitude.h"
#include "buffer.h"
#include "desa2.h"
#include "goertzel.h"
//#include "goertzel.h"
#include "psi.h"
#include "sma_buf.h"
#include "options.h"
@@ -111,7 +115,9 @@ typedef struct {
uint32_t rate;
circ_buffer_t b;
sma_buffer_t sma_b;
sma_buffer_t sqa_b;
size_t pos;
double f;
/* freq_table_t ft; */
avmd_state_t state;
} avmd_session_t;
@@ -134,6 +140,7 @@ static void init_avmd_session_data(avmd_session_t *avmd_session, switch_core_se
avmd_session->session = fs_session;
avmd_session->pos = 0;
avmd_session->f = 0.0;
avmd_session->state.last_beep = 0;
avmd_session->state.beep_state = BEEP_NOTDETECTED;
@@ -142,6 +149,12 @@ static void init_avmd_session_data(avmd_session_t *avmd_session, switch_core_se
BEEP_LEN(avmd_session->rate) / SINE_LEN(avmd_session->rate),
fs_session
);
INIT_SMA_BUFFER(
&avmd_session->sqa_b,
BEEP_LEN(avmd_session->rate) / SINE_LEN(avmd_session->rate),
fs_session
);
}
@@ -474,17 +487,18 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
circ_buffer_t *b;
size_t pos;
double f;
double a;
double error = 0.0;
double success = 0.0;
double amp = 0.0;
double s_rate;
double v;
// double error = 0.0;
// double success = 0.0;
// double amp = 0.0;
// double s_rate;
// double e_rate;
double avg_a;
double sine_len;
// double avg_a;
//double sine_len;
uint32_t sine_len_i;
int valid;
//uint32_t beep_len_i;
// int valid;
b = &session->b;
/*! If beep has already been detected skip the CPU heavy stuff */
@@ -494,57 +508,39 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
/*! Precompute values used heavily in the inner loop */
sine_len_i = SINE_LEN(session->rate);
sine_len = (double)sine_len_i;
//sine_len = (double)sine_len_i;
//beep_len_i = BEEP_LEN(session->rate);
channel = switch_core_session_get_channel(session->session);
/*! Insert frame of 16 bit samples into buffer */
INSERT_INT16_FRAME(b, (int16_t *)(frame->data), frame->samples);
//switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_INFO, "<<< AVMD sine_len_i=%d >>>\n", sine_len_i);
/*! INNER LOOP -- OPTIMIZATION TARGET */
for(pos = GET_BACKLOG_POS(b); pos != (GET_CURRENT_POS(b) - P); pos++){
for(pos = session->pos; pos < (GET_CURRENT_POS(b) - P); pos++){
if ((pos % sine_len_i) == 0) {
/*! Get a desa2 frequency estimate every sine len */
f = desa2(b, pos);
/*! Get a desa2 frequency estimate in Hertz */
f = TO_HZ(session->rate, desa2(b, pos));
if(f < MIN_FREQUENCY_R(session->rate) || f > MAX_FREQUENCY_R(session->rate)) {
v = 99999.0;
RESET_SMA_BUFFER(&session->sma_b);
RESET_SMA_BUFFER(&session->sqa_b);
} else {
APPEND_SMA_VAL(&session->sma_b, f);
APPEND_SMA_VAL(&session->sqa_b, f * f);
/* calculate variance */
v = session->sqa_b.sma - (session->sma_b.sma * session->sma_b.sma);
/*! Don't caculate amplitude if frequency is not within range */
if(f < MIN_FREQUENCY || f > MAX_FREQUENCY) {
a = 0.0;
error += 1.0;
} else {
a = amplitude(b, pos, f);
success += 1.0;
if(!ISNAN(a)){
amp += a;
}
}
/*! Every once in a while we evaluate the desa2 and amplitude results */
if(((pos + 1) % sine_len_i) == 0){
s_rate = success / (error + success);
// e_rate = error / (error + success);
avg_a = amp / sine_len;
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_INFO, "<<< AVMD v=%f f=%f %fHz sma=%f sqa=%f >>>\n", v, f, TO_HZ(session->rate, f), session->sma_b.sma, session->sqa_b.sma);
}
/*! Results out of these ranges are considered invalid */
valid = 0;
if( s_rate > 0.60 && avg_a > 0.50) valid = 1;
else if(s_rate > 0.65 && avg_a > 0.45) valid = 1;
else if(s_rate > 0.70 && avg_a > 0.40) valid = 1;
else if(s_rate > 0.80 && avg_a > 0.30) valid = 1;
else if(s_rate > 0.95 && avg_a > 0.05) valid = 1;
else if(s_rate >= 0.99 && avg_a > 0.04) valid = 1;
else if(s_rate == 1.00 && avg_a > 0.02) valid = 1;
/*! If variance is less than threshold then we have detection */
if(v < VARIANCE_THRESHOLD){
if(valid) {
APPEND_SMA_VAL(&session->sma_b, s_rate * avg_a);
}
else {
APPEND_SMA_VAL(&session->sma_b, 0.0 );
}
/*! If sma is higher then 0 we have some kind of detection (increase this value to eliminate false positives ex: 0.01) */
if(session->sma_b.sma > 0.00){
/*! Throw an event to FreeSWITCH */
status = switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, AVMD_EVENT_BEEP);
if(status != SWITCH_STATUS_SUCCESS) {
@@ -565,16 +561,18 @@ static void avmd_process(avmd_session_t *session, switch_frame_t *frame)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session->session), SWITCH_LOG_INFO, "<<< AVMD - Beep Detected >>>\n");
switch_channel_set_variable(channel, "avmd_detect", "TRUE");
RESET_SMA_BUFFER(&session->sma_b);
RESET_SMA_BUFFER(&session->sqa_b);
session->state.beep_state = BEEP_DETECTED;
return;
}
amp = 0.0;
success = 0.0;
error = 0.0;
//amp = 0.0;
//success = 0.0;
//error = 0.0;
}
}
session->pos = pos;
}
/* For Emacs:
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1466,6 +1466,8 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "ignore_early_media", "true");
switch_event_add_header(ovars, SWITCH_STACK_BOTTOM, "origination_uuid", "%s", agent_uuid_str);
switch_channel_process_export(member_channel, NULL, ovars, "cc_export_vars");
t_agent_called = local_epoch_time_now(NULL);
dialstr = switch_mprintf("%s", h->originate_string);
status = switch_ivr_originate(NULL, &agent_session, &cause, dialstr, 60, NULL, cid_name ? cid_name : h->member_cid_name, h->member_cid_number, NULL, ovars, SOF_NONE, NULL);
@@ -1534,7 +1536,7 @@ static void *SWITCH_THREAD_FUNC outbound_agent_thread_run(switch_thread_t *threa
/* Wait for the real channel to be fully bridged */
switch_channel_wait_for_flag(other_loopback_channel, CF_BRIDGED, SWITCH_TRUE, 5000, member_channel);
real_uuid = switch_channel_get_variable(other_loopback_channel, SWITCH_SIGNAL_BOND_VARIABLE);
real_uuid = switch_channel_get_partner_uuid(other_loopback_channel);
switch_channel_set_variable(other_loopback_channel, "cc_member_pre_answer_uuid", NULL);
/* Switch the agent session */
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -188,7 +188,7 @@ static switch_bool_t cidlookup_execute_sql_callback(char *sql, switch_core_db_ca
switch_bool_t retval = SWITCH_FALSE;
switch_cache_db_handle_t *dbh = NULL;
if (globals.odbc_dsn && (dbh = cidlookup_get_db_handle())) {
if (!zstr(globals.odbc_dsn) && (dbh = cidlookup_get_db_handle())) {
if (switch_cache_db_execute_sql_callback(dbh, sql, callback, (void *) cbt, err) != SWITCH_STATUS_SUCCESS) {
retval = SWITCH_FALSE;
} else {
@@ -533,7 +533,7 @@ static char *do_db_lookup(switch_memory_pool_t *pool, switch_event_t *event, con
callback_t cbt = { 0 };
cbt.pool = pool;
if (globals.odbc_dsn) {
if (!zstr(globals.odbc_dsn)) {
newsql = switch_event_expand_headers(event, sql);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG10, "SQL: %s\n", newsql);
if (cidlookup_execute_sql_callback(newsql, cidlookup_callback, &cbt, &err)) {
@@ -655,8 +655,6 @@ static cid_data_t *do_lookup(switch_memory_pool_t *pool, switch_event_t *event,
SWITCH_STANDARD_APP(cidlookup_app_function)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *argv[4] = { 0 };
int argc;
char *mydata = NULL;
@@ -705,7 +703,7 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
if (switch_string_var_check_const(cid->name)) {
switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_CRIT, "Invalid CID data {%s} contains a variable\n", cid->name);
switch_goto_status(SWITCH_STATUS_GENERR, done);
goto done;
}
if (cid && channel) {
@@ -719,7 +717,6 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
profile->caller_id_name = switch_core_strdup(profile->pool, cid->name);;
}
switch_goto_status(SWITCH_STATUS_SUCCESS, done);
done:
if (event) {
@@ -728,9 +725,6 @@ SWITCH_STANDARD_APP(cidlookup_app_function)
if (!session && pool) {
switch_core_destroy_memory_pool(&pool);
}
/* This is so compile doesn't failed because status is never used */
if (status) {
}
}
SWITCH_STANDARD_API(cidlookup_function)
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1559,27 +1559,22 @@ SWITCH_STANDARD_API(regex_function)
goto error;
}
if ((proceed = switch_regex_perform(argv[0], argv[1], &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
if (argc > 2) {
len = (strlen(argv[0]) + strlen(argv[2]) + 10) * proceed;
substituted = malloc(len);
switch_assert(substituted);
memset(substituted, 0, len);
switch_replace_char(argv[2], '%', '$', SWITCH_FALSE);
switch_perform_substitution(re, proceed, argv[2], argv[0], substituted, len, ovector);
proceed = switch_regex_perform(argv[0], argv[1], &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
stream->write_function(stream, "%s", substituted);
free(substituted);
} else {
stream->write_function(stream, "true");
}
if (argc > 2) {
len = (strlen(argv[0]) + strlen(argv[2]) + 10) * proceed;
substituted = malloc(len);
switch_assert(substituted);
memset(substituted, 0, len);
switch_replace_char(argv[2], '%', '$', SWITCH_FALSE);
switch_perform_substitution(re, proceed, argv[2], argv[0], substituted, len, ovector);
stream->write_function(stream, "%s", substituted);
free(substituted);
} else {
if (argc > 2) {
stream->write_function(stream, "%s", argv[0]);
} else {
stream->write_function(stream, "false");
}
stream->write_function(stream, proceed ? "true" : "false");
}
goto ok;
error:
@@ -2649,9 +2644,10 @@ SWITCH_STANDARD_API(sched_hangup_function)
char *cause_str = argv[2];
time_t when;
switch_call_cause_t cause = SWITCH_CAUSE_ALLOTTED_TIMEOUT;
int sec = atol(argv[0] + 1);
if (*argv[0] == '+') {
when = switch_epoch_time_now(NULL) + atol(argv[0] + 1);
when = switch_epoch_time_now(NULL) + sec;
} else {
when = atol(argv[0]);
}
@@ -2661,7 +2657,13 @@ SWITCH_STANDARD_API(sched_hangup_function)
}
if ((hsession = switch_core_session_locate(uuid))) {
switch_ivr_schedule_hangup(when, uuid, cause, SWITCH_FALSE);
if (sec == 0) {
switch_channel_t *hchannel = switch_core_session_get_channel(hsession);
switch_channel_hangup(hchannel, cause);
} else {
switch_ivr_schedule_hangup(when, uuid, cause, SWITCH_FALSE);
}
stream->write_function(stream, "+OK\n");
switch_core_session_rwunlock(hsession);
} else {
@@ -3087,6 +3089,45 @@ SWITCH_STANDARD_API(uuid_send_info_function)
}
#define VIDEO_REFRESH_SYNTAX "<uuid>"
SWITCH_STANDARD_API(uuid_video_refresh_function)
{
switch_status_t status = SWITCH_STATUS_FALSE;
char *mycmd = NULL, *argv[2] = { 0 };
int argc = 0;
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", VIDEO_REFRESH_SYNTAX);
} else {
switch_core_session_message_t msg = { 0 };
switch_core_session_t *lsession = NULL;
msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
msg.string_array_arg[2] = argv[1];
msg.from = __FILE__;
if ((lsession = switch_core_session_locate(argv[0]))) {
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");
}
switch_safe_free(mycmd);
return SWITCH_STATUS_SUCCESS;
}
#define DEBUG_AUDIO_SYNTAX "<uuid> <read|write|both> <on|off>"
SWITCH_STANDARD_API(uuid_debug_audio_function)
{
@@ -3398,7 +3439,7 @@ SWITCH_STANDARD_API(break_function)
channel = switch_core_session_get_channel(psession);
if (both) {
const char *quuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE);
const char *quuid = switch_channel_get_partner_uuid(channel);
if (quuid && (qsession = switch_core_session_locate(quuid))) {
qchannel = switch_core_session_get_channel(qsession);
}
@@ -5434,6 +5475,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
SWITCH_ADD_API(commands_api_interface, "uuid_hold", "hold", uuid_hold_function, HOLD_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_kill", "Kill Channel", kill_function, KILL_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_send_info", "Send info to the endpoint", uuid_send_info_function, INFO_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_video_refresh", "Send video refresh.", uuid_video_refresh_function, VIDEO_REFRESH_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_outgoing_answer", "Answer Outgoing Channel", outgoing_answer_function, OUTGOING_ANSWER_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_limit", "Increase limit resource", uuid_limit_function, LIMIT_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_limit_release", "Release limit resource", uuid_limit_release_function, LIMIT_RELEASE_SYNTAX);
@@ -5598,6 +5640,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
switch_console_set_complete("add uuid_simplify ::console::list_uuid");
switch_console_set_complete("add uuid_transfer ::console::list_uuid");
switch_console_set_complete("add uuid_dual_transfer ::console::list_uuid");
switch_console_set_complete("add uuid_video_refresh ::console::list_uuid");
switch_console_set_complete("add version");
switch_console_set_complete("add uuid_warning ::console::list_uuid");
switch_console_set_complete("add ...");
@@ -120,6 +120,10 @@
<!-- <param name="ivr-input-timeout" value="0" /> -->
<!-- Delay before a conference is asked to be terminated -->
<!-- <param name="endconf-grace-time" value="120" /> -->
<!-- Can be | delim of wait-mod|audio-always|video-bridge|video-floor-only
wait_mod will wait until the moderator in,
audio-always will always mix audio from all members regardless they are talking or not -->
<!-- <param name="conference-flags" value="audio-always"/> -->
</profile>
<profile name="wideband">
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -83,7 +83,7 @@ static int EC = 0;
/* the maximum value for the IIR score [keeps loud & longwinded people from getting overweighted] */
#define SCORE_MAX_IIR 25000
/* the minimum score for which you can be considered to be loud enough to now have the floor */
#define SCORE_IIR_SPEAKING_MAX 3000
#define SCORE_IIR_SPEAKING_MAX 300
/* the threshold below which you cede the floor to someone loud (see above value). */
#define SCORE_IIR_SPEAKING_MIN 100
@@ -174,7 +174,8 @@ typedef enum {
CFLAG_INHASH = (1 << 11),
CFLAG_EXIT_SOUND = (1 << 12),
CFLAG_ENTER_SOUND = (1 << 13),
CFLAG_VIDEO_BRIDGE = (1 << 14)
CFLAG_VIDEO_BRIDGE = (1 << 14),
CFLAG_AUDIO_ALWAYS = (1 << 15)
} conf_flag_t;
typedef enum {
@@ -216,7 +217,8 @@ typedef enum {
EFLAG_FLOOR_CHANGE = (1 << 25),
EFLAG_MUTE_DETECT = (1 << 26),
EFLAG_RECORD = (1 << 27),
EFLAG_HUP_MEMBER = (1 << 28)
EFLAG_HUP_MEMBER = (1 << 28),
EFLAG_PLAY_FILE_DONE = (1 << 29),
} event_type_t;
typedef struct conference_file_node {
@@ -334,6 +336,7 @@ typedef struct conference_obj {
switch_time_t end_time;
char *log_dir;
struct vid_helper vh[2];
struct vid_helper mh;
} conference_obj_t;
/* Relationship with another member */
@@ -476,7 +479,8 @@ static switch_status_t chat_send(switch_event_t *message_event);
static void launch_conference_record_thread(conference_obj_t *conference, char *path);
static void launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b);
static int launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b);
static void launch_conference_video_mirror_thread(conference_member_t *member_a);
typedef switch_status_t (*conf_api_args_cmd_t) (conference_obj_t *, switch_stream_handle_t *, int, char **);
typedef switch_status_t (*conf_api_member_cmd_t) (conference_member_t *, switch_stream_handle_t *, void *);
@@ -657,9 +661,10 @@ static void conference_cdr_render(conference_obj_t *conference)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error writing [%s][%s]\n", path, ebuf);
}
switch_safe_free(path);
switch_safe_free(xml_text);
switch_xml_free(cdr);
}
@@ -1220,6 +1225,62 @@ static void *SWITCH_THREAD_FUNC conference_video_bridge_thread_run(switch_thread
}
static void *SWITCH_THREAD_FUNC conference_video_mirror_thread_run(switch_thread_t *thread, void *obj)
{
struct vid_helper *vh = obj;
switch_core_session_t *session_a = vh->member_a->session;
switch_channel_t *channel_a = switch_core_session_get_channel(session_a);
switch_status_t status;
switch_frame_t *read_frame;
conference_obj_t *conference = vh->member_a->conference;
switch_core_session_message_t msg = { 0 };
switch_thread_rwlock_rdlock(conference->rwlock);
switch_thread_rwlock_rdlock(vh->member_a->rwlock);
/* Acquire locks for both sessions so the helper object and member structures don't get destroyed before we exit */
switch_core_session_read_lock(session_a);
/* Tell the channel to request a fresh vid frame */
msg.from = __FILE__;
msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
switch_core_session_receive_message(session_a, &msg);
vh->up = 1;
while (vh->up > 0 && switch_test_flag(vh->member_a, MFLAG_RUNNING) &&
switch_channel_ready(channel_a)) {
if (vh->up == 1) {
status = switch_core_session_read_video_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0);
if (!SWITCH_READ_ACCEPTABLE(status)) {
break;
}
if (!switch_test_flag(read_frame, SFF_CNG)) {
if (switch_core_session_write_video_frame(session_a, read_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
break;
}
}
} else {
switch_yield(100000);
}
}
switch_thread_rwlock_unlock(vh->member_a->rwlock);
switch_core_session_rwunlock(session_a);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s video mirror thread ended.\n", switch_channel_get_name(channel_a));
switch_thread_rwlock_unlock(conference->rwlock);
vh->up = 0;
return NULL;
}
/* Main video monitor thread (1 per distinct conference room) */
static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thread, void *obj)
{
@@ -1522,8 +1583,22 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
switch_channel_ready(switch_core_session_get_channel(video_bridge_members[0]->session)) &&
switch_channel_ready(switch_core_session_get_channel(video_bridge_members[1]->session))
) {
conference->mh.up = 2;
if (launch_conference_video_bridge_thread(video_bridge_members[0], video_bridge_members[1])) {
conference->mh.up = 1;
} else {
conference->mh.up = -1;
}
} else if (conference->vh[0].up == 0 &&
conference->vh[1].up == 0 &&
conference->mh.up == 0 &&
video_bridge_members[0] &&
!video_bridge_members[1] &&
switch_test_flag(video_bridge_members[0], MFLAG_RUNNING) &&
switch_channel_ready(switch_core_session_get_channel(video_bridge_members[0]->session))
) {
launch_conference_video_bridge_thread(video_bridge_members[0], video_bridge_members[1]);
launch_conference_video_mirror_thread(video_bridge_members[0]);
}
}
@@ -1547,7 +1622,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
}
if (file_sample_len <= 0) {
if (test_eflag(conference, EFLAG_PLAY_FILE) &&
if (test_eflag(conference, EFLAG_PLAY_FILE_DONE) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
conference_add_event_data(conference, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "play-file-done");
@@ -2500,6 +2575,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
switch_clear_flag_locked(member, MFLAG_TALKING);
check_agc_levels(member);
clear_avg(member);
member->score_iir = 0;
if (test_eflag(member->conference, EFLAG_STOP_TALKING) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
@@ -2670,8 +2746,8 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
}
/* skip frames that are not actual media or when we are muted or silent */
if ((switch_test_flag(member, MFLAG_TALKING) || member->energy_level == 0) && switch_test_flag(member, MFLAG_CAN_SPEAK) &&
!switch_test_flag(member->conference, CFLAG_WAIT_MOD)) {
if ((switch_test_flag(member, MFLAG_TALKING) || member->energy_level == 0 || switch_test_flag(member->conference, CFLAG_AUDIO_ALWAYS))
&& switch_test_flag(member, MFLAG_CAN_SPEAK) && !switch_test_flag(member->conference, CFLAG_WAIT_MOD)) {
switch_audio_resampler_t *read_resampler = member->read_resampler;
void *data;
uint32_t datalen;
@@ -4426,6 +4502,10 @@ static void conference_xlist(conference_obj_t *conference, switch_xml_t x_confer
switch_xml_set_attr_d(x_conference, "wait_mod", "true");
}
if (switch_test_flag(conference, CFLAG_AUDIO_ALWAYS)) {
switch_xml_set_attr_d(x_conference, "audio_always", "true");
}
if (switch_test_flag(conference, CFLAG_RUNNING)) {
switch_xml_set_attr_d(x_conference, "running", "true");
}
@@ -5605,6 +5685,7 @@ static switch_status_t conference_outcall(conference_obj_t *conference,
char appdata[512];
int rdlock = 0;
switch_bool_t have_flags = SWITCH_FALSE;
const char *outcall_flags;
*cause = SWITCH_CAUSE_NORMAL_CLEARING;
@@ -5690,6 +5771,12 @@ static switch_status_t conference_outcall(conference_obj_t *conference,
goto done;
}
if ((outcall_flags = switch_channel_get_variable(peer_channel, "outcall_flags"))) {
if (!zstr(outcall_flags)) {
flags = (char *)outcall_flags;
}
}
if (flags && strcasecmp(flags, "none")) {
have_flags = SWITCH_TRUE;
}
@@ -5962,6 +6049,8 @@ static void set_cflags(const char *flags, uint32_t *f)
*f |= CFLAG_VID_FLOOR;
} else if (!strcasecmp(argv[i], "video-bridge")) {
*f |= CFLAG_VIDEO_BRIDGE;
} else if (!strcasecmp(argv[i], "audio-always")) {
*f |= CFLAG_AUDIO_ALWAYS;
}
}
@@ -6019,6 +6108,8 @@ static void clear_eflags(char *events, uint32_t *f)
*f &= ~EFLAG_VOLUME_OUT_MEMBER;
} else if (!strcmp(event, "play-file")) {
*f &= ~EFLAG_PLAY_FILE;
} else if (!strcmp(event, "play-file-done")) {
*f &= ~EFLAG_PLAY_FILE;
} else if (!strcmp(event, "play-file-member")) {
*f &= ~EFLAG_PLAY_FILE_MEMBER;
} else if (!strcmp(event, "speak-text")) {
@@ -6756,11 +6847,11 @@ static void launch_conference_video_thread(conference_obj_t *conference)
}
/* Create a video thread for the conference and launch it */
static void launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b)
static int launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b)
{
conference_obj_t *conference = member_a->conference;
switch_memory_pool_t *pool = conference->pool;
int sanity = 10000;
int sanity = 10000, r = 0;
memset(conference->vh, 0, sizeof(conference->vh));
@@ -6779,14 +6870,33 @@ static void launch_conference_video_bridge_thread(conference_member_t *member_a,
if (conference->vh[0].up == 1 && conference->vh[1].up != 1) {
conference->vh[0].up = -1;
r = -1;
}
if (conference->vh[1].up == 1 && conference->vh[0].up != 1) {
conference->vh[1].up = -1;
r = -1;
}
return r;
}
/* Create a video thread for the conference and launch it */
static void launch_conference_video_mirror_thread(conference_member_t *member_a)
{
conference_obj_t *conference = member_a->conference;
switch_memory_pool_t *pool = conference->pool;
memset(&conference->mh, 0, sizeof(conference->mh));
conference->mh.member_a = member_a;
launch_thread_detached(conference_video_mirror_thread_run, pool, &conference->mh);
}
static void launch_conference_record_thread(conference_obj_t *conference, char *path)
{
switch_thread_t *thread;
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+567 -20
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -24,7 +24,7 @@
* Contributor(s):
*
* Anthony Minessale II <anthm@freeswitch.org>
* Ken Rice, Asteria Solutions Group, Inc <ken@asteriasgi.com>
* Ken Rice <krice@freeswitch.org>
* Michael Murdock <mike at mmurdock dot org>
* Neal Horman <neal at wanlink dot com>
* Bret McDanel <trixter AT 0xdecafbad dot com>
@@ -38,7 +38,8 @@
#include <switch.h>
SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load);
SWITCH_MODULE_DEFINITION(mod_dptools, mod_dptools_load, NULL, NULL);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dptools_shutdown);
SWITCH_MODULE_DEFINITION(mod_dptools, mod_dptools_load, mod_dptools_shutdown, NULL);
SWITCH_STANDARD_DIALPLAN(inline_dialplan_hunt)
{
@@ -464,6 +465,7 @@ SWITCH_STANDARD_APP(play_and_detect_speech_function)
char *lbuf = NULL;
const char *response = "DONE";
char *detect = NULL;
char *s;
switch_channel_set_variable(channel, "detect_speech_result", "");
@@ -474,6 +476,12 @@ SWITCH_STANDARD_APP(play_and_detect_speech_function)
goto done;
}
/* trim any trailing space */
s = detect;
while (--s >= lbuf && switch_isspace(*s)) {
*s = '\0';
}
/* split input at "detect:" */
detect[0] = '\0';
detect += 7;
@@ -966,7 +974,7 @@ SWITCH_STANDARD_APP(transfer_function)
if (bleg || both) {
const char *uuid;
switch_channel_t *channel = switch_core_session_get_channel(session);
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
if ((uuid = switch_channel_get_partner_uuid(channel))) {
switch_core_session_t *b_session;
if ((b_session = switch_core_session_locate(uuid))) {
switch_ivr_session_transfer(b_session, argv[1], argv[2], argv[3]);
@@ -1021,9 +1029,10 @@ SWITCH_STANDARD_APP(sched_hangup_function)
time_t when;
switch_call_cause_t cause = SWITCH_CAUSE_ALLOTTED_TIMEOUT;
switch_bool_t bleg = SWITCH_FALSE;
int sec = atol(argv[0] + 1);
if (*argv[0] == '+') {
when = switch_epoch_time_now(NULL) + atol(argv[0] + 1);
when = switch_epoch_time_now(NULL) + sec;
} else {
when = atol(argv[0]);
}
@@ -1036,7 +1045,11 @@ SWITCH_STANDARD_APP(sched_hangup_function)
bleg = SWITCH_TRUE;
}
switch_ivr_schedule_hangup(when, switch_core_session_get_uuid(session), cause, bleg);
if (sec == 0) {
switch_channel_hangup(switch_core_session_get_channel(session), cause);
} else {
switch_ivr_schedule_hangup(when, switch_core_session_get_uuid(session), cause, bleg);
}
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No time specified.\n");
}
@@ -1172,6 +1185,17 @@ SWITCH_STANDARD_APP(redirect_function)
switch_core_session_receive_message(session, &msg);
}
SWITCH_STANDARD_APP(video_refresh_function)
{
switch_core_session_message_t msg = { 0 };
/* Tell the channel to refresh video */
msg.from = __FILE__;
msg.string_arg = data;
msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
switch_core_session_receive_message(session, &msg);
}
SWITCH_STANDARD_APP(send_info_function)
{
switch_core_session_message_t msg = { 0 };
@@ -1965,7 +1989,7 @@ SWITCH_STANDARD_APP(speak_function)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
char buf[10];
char *argv[4] = { 0 };
char *argv[3] = { 0 };
int argc;
const char *engine = NULL;
const char *voice = NULL;
@@ -1984,14 +2008,14 @@ SWITCH_STANDARD_APP(speak_function)
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Params!\n");
return;
} else if (argc == 1) {
text = argv[0];
text = switch_core_session_strdup(session, data); /* unstripped text */
} else if (argc == 2) {
voice = argv[0];
text = argv[1];
text = switch_core_session_strdup(session, data + (argv[1] - argv[0])); /* unstripped text */
} else {
engine = argv[0];
voice = argv[1];
text = argv[2];
text = switch_core_session_strdup(session, data + (argv[2] - argv[0])); /* unstripped text */
}
if (!engine) {
@@ -2109,6 +2133,12 @@ static switch_status_t hanguphook(switch_core_session_t *session)
return SWITCH_STATUS_SUCCESS;
}
static void att_xfer_set_result(switch_channel_t *channel, switch_status_t status)
{
switch_channel_set_variable(channel, SWITCH_ATT_XFER_RESULT_VARIABLE, status == SWITCH_STATUS_SUCCESS ? "success" : "failure");
}
SWITCH_STANDARD_APP(att_xfer_function)
{
switch_core_session_t *peer_session = NULL;
@@ -2119,7 +2149,7 @@ SWITCH_STANDARD_APP(att_xfer_function)
channel = switch_core_session_get_channel(session);
if ((bond = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
if ((bond = switch_channel_get_partner_uuid(channel))) {
bond = switch_core_session_strdup(session, bond);
}
@@ -2154,7 +2184,8 @@ SWITCH_STANDARD_APP(att_xfer_function)
if (!switch_channel_down(peer_channel)) {
if (!switch_channel_ready(channel)) {
switch_ivr_uuid_bridge(switch_core_session_get_uuid(peer_session), bond);
switch_status_t status = switch_ivr_uuid_bridge(switch_core_session_get_uuid(peer_session), bond);
att_xfer_set_result(peer_channel, status);
br++;
} else if ((b_session = switch_core_session_locate(bond))) {
switch_channel_t *b_channel = switch_core_session_get_channel(b_session);
@@ -2172,7 +2203,8 @@ SWITCH_STANDARD_APP(att_xfer_function)
}
if (!br) {
switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), bond);
switch_status_t status = switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), bond);
att_xfer_set_result(channel, status);
}
}
@@ -2766,7 +2798,7 @@ SWITCH_STANDARD_APP(audio_bridge_function)
switch_thread_t *thread = NULL;
switch_threadattr_t *thd_attr = NULL;
char *camp_data = NULL;
switch_status_t status;
switch_status_t status = SWITCH_STATUS_FALSE;
int camp_loops = 0;
if (zstr(data)) {
@@ -3037,7 +3069,8 @@ SWITCH_STANDARD_APP(audio_bridge_function)
}
}
}
if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && switch_channel_get_state(caller_channel) != CS_ROUTING) {
if (!switch_channel_test_flag(caller_channel, CF_TRANSFER) && !switch_channel_test_flag(caller_channel, CF_CONFIRM_BLIND_TRANSFER) &&
switch_channel_get_state(caller_channel) != CS_ROUTING) {
switch_channel_hangup(caller_channel, cause);
}
return;
@@ -3087,6 +3120,480 @@ SWITCH_STANDARD_APP(audio_bridge_function)
}
}
static struct {
switch_memory_pool_t *pool;
switch_hash_t *pickup_hash;
switch_mutex_t *pickup_mutex;
} globals;
/* pickup channel */
typedef struct pickup_node_s {
char *key;
char *uuid;
struct pickup_node_s *next;
} pickup_node_t;
#define PICKUP_PROTO "pickup"
static int EC = 0;
static int pickup_count(const char *key_name)
{
int count = 0;
pickup_node_t *head, *np;
switch_mutex_lock(globals.pickup_mutex);
if ((head = switch_core_hash_find(globals.pickup_hash, key_name))) {
for (np = head; np; np = np->next) count++;
}
switch_mutex_unlock(globals.pickup_mutex);
return count;
}
static void pickup_send_presence(const char *key_name)
{
char *domain_name, *dup_key_name = NULL, *dup_domain_name = NULL, *dup_id = NULL;
switch_event_t *event;
int count;
dup_key_name = strdup(key_name);
key_name = dup_key_name;
if ((domain_name = strchr(dup_key_name, '@'))) {
*domain_name++ = '\0';
}
if (zstr(domain_name)) {
dup_domain_name = switch_core_get_variable_dup("domain");
domain_name = dup_domain_name;
}
if (zstr(domain_name)) {
domain_name = "cluecon.com";
}
dup_id = switch_mprintf("%s@%s", key_name, domain_name);
count = pickup_count(dup_id);
if (count > 0) {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", PICKUP_PROTO);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", dup_id);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", dup_id);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "force-status", "Active (%d call%s)", count, count == 1 ? "" : "s");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "active");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", key_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_ROUTING");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "confirmed");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", "inbound");
switch_event_fire(&event);
}
} else {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", PICKUP_PROTO);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", dup_id);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "from", dup_id);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "force-status", "Idle");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", dup_id);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_HANGUP");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "terminated");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", "inbound");
switch_event_fire(&event);
}
}
switch_safe_free(dup_domain_name);
switch_safe_free(dup_key_name);
switch_safe_free(dup_id);
}
static void pickup_pres_event_handler(switch_event_t *event)
{
char *to = switch_event_get_header(event, "to");
char *dup_to = NULL, *key_name, *dup_key_name = NULL, *domain_name, *dup_domain_name = NULL;
int count = 0;
if (!to || strncasecmp(to, "pickup+", 7) || !strchr(to, '@')) {
return;
}
if (!(dup_to = strdup(to))) {
return;
}
key_name = dup_to + 7;
if ((domain_name = strchr(key_name, '@'))) {
*domain_name++ = '\0';
} else {
dup_domain_name = switch_core_get_variable_dup("domain");
domain_name = dup_domain_name;
}
if (zstr(domain_name)) {
switch_safe_free(dup_to);
return;
}
dup_key_name = switch_mprintf("%q@%q", key_name, domain_name);
count = pickup_count(dup_key_name);
switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN);
if (count) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", PICKUP_PROTO);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", key_name);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", key_name, domain_name);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "force-status", "Active (%d call%s)", count, count == 1 ? "" : "s");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "active");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", key_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_ROUTING");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "confirmed");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", "inbound");
} else {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", PICKUP_PROTO);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", key_name);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", key_name, domain_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "force-status", "Idle");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_count", "%d", EC++);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "unique-id", key_name);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-state", "CS_HANGUP");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "answer-state", "terminated");
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-direction", "inbound");
}
switch_event_fire(&event);
switch_safe_free(dup_to);
switch_safe_free(dup_key_name);
switch_safe_free(dup_domain_name);
}
static void pickup_add_session(switch_core_session_t *session, const char *key)
{
pickup_node_t *head, *node, *np;
char *dup_key = NULL;
if (!strchr(key, '@')) {
dup_key = switch_mprintf("%s@%s", key, switch_core_get_variable("domain"));
key = dup_key;
}
node = malloc(sizeof(*node));
node->key = strdup(key);
node->uuid = strdup(switch_core_session_get_uuid(session));
node->next = NULL;
switch_mutex_lock(globals.pickup_mutex);
head = switch_core_hash_find(globals.pickup_hash, key);
if (head) {
for (np = head; np && np->next; np = np->next);
np->next = node;
} else {
head = node;
switch_core_hash_insert(globals.pickup_hash, key, head);
}
switch_mutex_unlock(globals.pickup_mutex);
pickup_send_presence(key);
switch_safe_free(dup_key);
}
static char *pickup_pop_uuid(const char *key, const char *uuid)
{
pickup_node_t *node = NULL, *head;
char *r = NULL;
char *dup_key = NULL;
if (!strchr(key, '@')) {
dup_key = switch_mprintf("%s@%s", key, switch_core_get_variable("domain"));
key = dup_key;
}
switch_mutex_lock(globals.pickup_mutex);
if ((head = switch_core_hash_find(globals.pickup_hash, key))) {
switch_core_hash_delete(globals.pickup_hash, key);
if (uuid) {
pickup_node_t *np, *lp = NULL;
for(np = head; np; np = np->next) {
if (!strcmp(np->uuid, uuid)) {
if (lp) {
lp->next = np->next;
} else {
head = np->next;
}
node = np;
break;
}
lp = np;
}
} else {
node = head;
head = head->next;
}
if (head) {
switch_core_hash_insert(globals.pickup_hash, key, head);
}
}
if (node) {
r = node->uuid;
free(node->key);
free(node);
}
switch_mutex_unlock(globals.pickup_mutex);
if (r) pickup_send_presence(key);
switch_safe_free(dup_key);
return r;
}
typedef struct pickup_pvt_s {
char *key;
switch_event_t *vars;
} pickup_pvt_t;
switch_endpoint_interface_t *pickup_endpoint_interface;
static switch_call_cause_t pickup_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause);
switch_io_routines_t pickup_io_routines = {
/*.outgoing_channel */ pickup_outgoing_channel
};
static switch_status_t pickup_event_handler(switch_core_session_t *session)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_channel_state_t state = switch_channel_get_running_state(channel);
pickup_pvt_t *tech_pvt = switch_core_session_get_private(session);
switch(state) {
case CS_DESTROY:
if (tech_pvt->vars) {
switch_event_destroy(&tech_pvt->vars);
}
break;
case CS_REPORTING:
return SWITCH_STATUS_FALSE;
case CS_HANGUP:
{
if (switch_channel_test_flag(channel, CF_CHANNEL_SWAP)) {
const char *key = switch_channel_get_variable(channel, "channel_swap_uuid");
switch_core_session_t *swap_session;
if ((swap_session = switch_core_session_locate(key))) {
switch_channel_t *swap_channel = switch_core_session_get_channel(swap_session);
switch_channel_hangup(swap_channel, SWITCH_CAUSE_PICKED_OFF);
switch_core_session_rwunlock(swap_session);
}
switch_channel_clear_flag(channel, CF_CHANNEL_SWAP);
}
pickup_pop_uuid(tech_pvt->key, switch_core_session_get_uuid(session));
}
break;
default:
break;
}
return SWITCH_STATUS_SUCCESS;
}
switch_state_handler_table_t pickup_event_handlers = {
/*.on_init */ pickup_event_handler,
/*.on_routing */ pickup_event_handler,
/*.on_execute */ pickup_event_handler,
/*.on_hangup */ pickup_event_handler,
/*.on_exchange_media */ pickup_event_handler,
/*.on_soft_execute */ pickup_event_handler,
/*.on_consume_media */ pickup_event_handler,
/*.on_hibernate */ pickup_event_handler,
/*.on_reset */ pickup_event_handler,
/*.on_park */ pickup_event_handler,
/*.on_reporting */ pickup_event_handler,
/*.on_destroy */ pickup_event_handler
};
static switch_call_cause_t pickup_outgoing_channel(switch_core_session_t *session,
switch_event_t *var_event,
switch_caller_profile_t *outbound_profile,
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags,
switch_call_cause_t *cancel_cause)
{
char *pickup;
switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
switch_core_session_t *nsession;
switch_channel_t *nchannel;
char *name;
pickup_pvt_t *tech_pvt;
switch_caller_profile_t *caller_profile;
if (zstr(outbound_profile->destination_number)) {
goto done;
}
pickup = outbound_profile->destination_number;
if (!(nsession = switch_core_session_request(pickup_endpoint_interface, SWITCH_CALL_DIRECTION_OUTBOUND, flags, pool))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n");
goto error;
}
tech_pvt = switch_core_session_alloc(nsession, sizeof(*tech_pvt));
tech_pvt->key = switch_core_session_strdup(nsession, pickup);
switch_event_dup(&tech_pvt->vars, var_event);
switch_core_session_set_private(nsession, tech_pvt);
nchannel = switch_core_session_get_channel(nsession);
caller_profile = switch_caller_profile_clone(nsession, outbound_profile);
switch_channel_set_caller_profile(nchannel, caller_profile);
switch_channel_set_state(nchannel, CS_ROUTING);
*new_session = nsession;
cause = SWITCH_CAUSE_SUCCESS;
name = switch_core_session_sprintf(nsession, "pickup/%s", pickup);
switch_channel_set_name(nchannel, name);
switch_channel_set_variable(nchannel, "process_cdr", "false");
pickup_add_session(nsession, pickup);
switch_channel_set_flag(nchannel, CF_PICKUP);
goto done;
error:
if (nsession) {
switch_core_session_destroy(&nsession);
}
if (pool) {
*pool = NULL;
}
done:
return cause;
}
#define PICKUP_SYNTAX "[<key>]"
SWITCH_STANDARD_APP(pickup_function)
{
char *uuid = NULL;
switch_core_session_t *pickup_session;
switch_channel_t *channel = switch_core_session_get_channel(session);
if (zstr(data)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Missing data. Usage: pickup %s\n", PICKUP_SYNTAX);
return;
}
if ((uuid = pickup_pop_uuid((char *)data, NULL))) {
if ((pickup_session = switch_core_session_locate(uuid))) {
switch_channel_t *pickup_channel = switch_core_session_get_channel(pickup_session);
switch_caller_profile_t *pickup_caller_profile = switch_channel_get_caller_profile(pickup_channel),
*caller_profile = switch_channel_get_caller_profile(channel);
const char *name, *num;
switch_event_t *event;
switch_event_header_t *hp;
pickup_pvt_t *tech_pvt = switch_core_session_get_private(pickup_session);
for(hp = tech_pvt->vars->headers; hp; hp = hp->next) {
switch_channel_set_variable(channel, hp->name, hp->value);
}
switch_channel_set_flag(pickup_channel, CF_CHANNEL_SWAP);
switch_channel_set_variable(pickup_channel, "channel_swap_uuid", switch_core_session_get_uuid(session));
name = caller_profile->caller_id_name;
num = caller_profile->caller_id_number;
caller_profile->caller_id_name = switch_core_strdup(caller_profile->pool, pickup_caller_profile->caller_id_name);
caller_profile->caller_id_number = switch_core_strdup(caller_profile->pool, pickup_caller_profile->caller_id_number);
caller_profile->callee_id_name = name;
caller_profile->callee_id_number = num;
if (switch_event_create(&event, SWITCH_EVENT_CALL_UPDATE) == SWITCH_STATUS_SUCCESS) {
const char *uuid = switch_channel_get_partner_uuid(channel);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Direction", "RECV");
if (uuid) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Bridged-To", uuid);
}
switch_channel_event_set_data(channel, event);
switch_event_fire(&event);
}
switch_channel_set_state(channel, CS_HIBERNATE);
switch_channel_mark_answered(pickup_channel);
switch_core_session_rwunlock(pickup_session);
}
free(uuid);
}
}
/* fake chan_error */
switch_endpoint_interface_t *error_endpoint_interface;
static switch_call_cause_t error_outgoing_channel(switch_core_session_t *session,
@@ -3936,7 +4443,7 @@ static switch_status_t file_string_file_read(switch_file_handle_t *handle, void
*len = context->samples;
}
context->samples -= *len;
context->samples -= (int) *len;
memset(data, 255, *len *2);
status = SWITCH_STATUS_SUCCESS;
} else {
@@ -3962,6 +4469,19 @@ static char *file_string_supported_formats[SWITCH_MAX_CODECS] = { 0 };
/* /FILE STRING INTERFACE */
SWITCH_STANDARD_APP(blind_transfer_ack_function)
{
switch_bool_t val = 0;
if (data) {
val = switch_true((char *) val);
}
switch_ivr_blind_transfer_ack(session, val);
}
#define SPEAK_DESC "Speak text to a channel via the tts interface"
#define DISPLACE_DESC "Displace audio from a file to the channels input"
@@ -3978,6 +4498,14 @@ static char *file_string_supported_formats[SWITCH_MAX_CODECS] = { 0 };
#define LOG_LONG_DESC "Logs a channel variable for the channel calling the application."
#define TRANSFER_LONG_DESC "Immediately transfer the calling channel to a new extension"
#define SLEEP_LONG_DESC "Pause the channel for a given number of milliseconds, consuming the audio for that period of time."
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dptools_shutdown)
{
switch_event_unbind_callback(pickup_pres_event_handler);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
{
switch_api_interface_t *api_interface;
@@ -3986,12 +4514,19 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
switch_chat_interface_t *chat_interface;
switch_file_interface_t *file_interface;
globals.pool = pool;
switch_core_hash_init(&globals.pickup_hash, NULL);
switch_mutex_init(&globals.pickup_mutex, SWITCH_MUTEX_NESTED, globals.pool);
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
switch_event_bind(modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, pickup_pres_event_handler, NULL);
file_string_supported_formats[0] = "file_string";
file_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE);
file_interface = (switch_file_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_FILE_INTERFACE);
file_interface->interface_name = modname;
file_interface->extens = file_string_supported_formats;
file_interface->file_open = file_string_file_open;
@@ -4000,18 +4535,23 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
file_interface->file_seek = file_string_file_seek;
error_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
error_endpoint_interface = (switch_endpoint_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
error_endpoint_interface->interface_name = "error";
error_endpoint_interface->io_routines = &error_io_routines;
group_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
group_endpoint_interface = (switch_endpoint_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
group_endpoint_interface->interface_name = "group";
group_endpoint_interface->io_routines = &group_io_routines;
user_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
user_endpoint_interface = (switch_endpoint_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
user_endpoint_interface->interface_name = "user";
user_endpoint_interface->io_routines = &user_io_routines;
pickup_endpoint_interface = (switch_endpoint_interface_t *) switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
pickup_endpoint_interface->interface_name = "pickup";
pickup_endpoint_interface->io_routines = &pickup_io_routines;
pickup_endpoint_interface->state_handler = &pickup_event_handlers;
SWITCH_ADD_CHAT(chat_interface, "event", event_chat_send);
SWITCH_ADD_CHAT(chat_interface, "api", api_chat_send);
@@ -4021,6 +4561,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_API(api_interface, "strftime", "strftime", strftime_api_function, "<format_string>");
SWITCH_ADD_API(api_interface, "presence", "presence", presence_api_function, PRESENCE_USAGE);
SWITCH_ADD_APP(app_interface, "blind_transfer_ack", "", "", blind_transfer_ack_function, "[true|false]", SAF_NONE);
SWITCH_ADD_APP(app_interface, "bind_digit_action", "bind a key sequence or regex to an action",
"bind a key sequence or regex to an action", bind_digit_action_function, BIND_DIGIT_ACTION_USAGE, SAF_SUPPORT_NOMEDIA);
@@ -4097,6 +4639,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "ivr", "Run an ivr menu", "Run an ivr menu.", ivr_application_function, "<menu_name>", SAF_NONE);
SWITCH_ADD_APP(app_interface, "redirect", "Send session redirect", "Send a redirect message to a session.", redirect_function, "<redirect_data>",
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "video_refresh", "Send video refresh.", "Send video refresh.", video_refresh_function, "",
SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "send_info", "Send info", "Send info", send_info_function, "<info>", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "jitterbuffer", "Send session jitterbuffer", "Send a jitterbuffer message to a session.",
jitterbuffer_function, "<jitterbuffer_data>", SAF_SUPPORT_NOMEDIA);
@@ -4186,6 +4730,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "limit_execute", "Limit", LIMITEXECUTE_DESC, limit_execute_function, LIMITEXECUTE_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "limit_hash_execute", "Limit", LIMITHASHEXECUTE_DESC, limit_hash_execute_function, LIMITHASHEXECUTE_USAGE, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "pickup", "Pickup", "Pickup a call", pickup_function, PICKUP_SYNTAX, SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_DIALPLAN(dp_interface, "inline", inline_dialplan_hunt);
/* indicate that the module should continue to be loaded */
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+2 -2
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -226,7 +226,7 @@ SWITCH_STANDARD_APP(bcast_function)
bytes = 16;
switch_socket_sendto(socket, control_packet_addr, 0, (void *) &control_packet, &bytes);
for (;;) {
while (switch_channel_ready(channel)) {
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
-24
View File
@@ -1,24 +0,0 @@
include $(top_srcdir)/build/modmake.rulesam
MODNAME=mod_fax
TIFF_DIR=$(switch_srcdir)/libs/tiff-3.8.2
TIFF_BUILDDIR=$(switch_builddir)/libs/tiff-3.8.2
TIFF_LA=$(TIFF_BUILDDIR)/libtiff/libtiff.la
SPANDSP_DIR=$(switch_srcdir)/libs/spandsp
SPANDSP_BUILDDIR=$(switch_builddir)/libs/spandsp
SPANDSP_LA=$(SPANDSP_BUILDDIR)/src/libspandsp.la
mod_LTLIBRARIES = mod_fax.la
mod_fax_la_SOURCES = mod_fax.c udptl.c
mod_fax_la_CFLAGS = $(AM_CFLAGS) -I$(SPANDSP_DIR)/src -I$(TIFF_DIR)/libtiff -I$(SPANDSP_BUILDDIR)/src -I$(TIFF_BUILDDIR)/libtiff -I.
mod_fax_la_LIBADD = $(switch_builddir)/libfreeswitch.la $(SPANDSP_LA) $(TIFF_LA)
mod_fax_la_LDFLAGS = -avoid-version -module -no-undefined -shared -ljpeg
$(SPANDSP_LA): $(TIFF_LA) $(SPANDSP_DIR) $(SPANDSP_DIR)/.update
cd $(SPANDSP_BUILDDIR) && $(MAKE) -j1
$(TOUCH_TARGET)
$(TIFF_LA): $(TIFF_DIR) $(TIFF_DIR)/.update
cd $(TIFF_BUILDDIR) && $(MAKE) -j1
$(TOUCH_TARGET)
File diff suppressed because it is too large Load Diff
-563
View File
@@ -1,563 +0,0 @@
//#define UDPTL_DEBUG
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2009, Steve Underwood <steveu@coppice.org>
*
* 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.
*
* Contributor(s):
*
* Steve Underwood <steveu@coppice.org>
*
* udptl.c -- UDPTL handling for T.38
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <inttypes.h>
#include <memory.h>
#include "udptl.h"
#define FALSE 0
#define TRUE (!FALSE)
static int decode_length(const uint8_t *buf, int limit, int *len, int *pvalue)
{
if (*len >= limit)
return -1;
if ((buf[*len] & 0x80) == 0) {
*pvalue = buf[(*len)++];
return 0;
}
if ((buf[*len] & 0x40) == 0) {
if (*len >= limit - 1)
return -1;
*pvalue = (buf[(*len)++] & 0x3F) << 8;
*pvalue |= buf[(*len)++];
return 0;
}
*pvalue = (buf[(*len)++] & 0x3F) << 14;
/* Indicate we have a fragment */
return 1;
}
/*- End of function --------------------------------------------------------*/
static int decode_open_type(const uint8_t *buf, int limit, int *len, const uint8_t ** p_object, int *p_num_octets)
{
int octet_cnt;
int octet_idx;
int stat;
int i;
const uint8_t **pbuf;
for (octet_idx = 0, *p_num_octets = 0;; octet_idx += octet_cnt) {
if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0)
return -1;
if (octet_cnt > 0) {
*p_num_octets += octet_cnt;
pbuf = &p_object[octet_idx];
i = 0;
/* Make sure the buffer contains at least the number of bits requested */
if ((*len + octet_cnt) > limit)
return -1;
*pbuf = &buf[*len];
*len += octet_cnt;
}
if (stat == 0)
break;
}
return 0;
}
/*- End of function --------------------------------------------------------*/
static int encode_length(uint8_t *buf, int *len, int value)
{
int multiplier;
if (value < 0x80) {
/* 1 octet */
buf[(*len)++] = value;
return value;
}
if (value < 0x4000) {
/* 2 octets */
/* Set the first bit of the first octet */
buf[(*len)++] = ((0x8000 | value) >> 8) & 0xFF;
buf[(*len)++] = value & 0xFF;
return value;
}
/* Fragmentation */
multiplier = (value < 0x10000) ? (value >> 14) : 4;
/* Set the first 2 bits of the octet */
buf[(*len)++] = 0xC0 | multiplier;
return multiplier << 14;
}
/*- End of function --------------------------------------------------------*/
static int encode_open_type(uint8_t *buf, int *len, const uint8_t *data, int num_octets)
{
int enclen;
int octet_idx;
uint8_t zero_byte;
/* If open type is of zero length, add a single zero byte (10.1) */
if (num_octets == 0) {
zero_byte = 0;
data = &zero_byte;
num_octets = 1;
}
/* Encode the open type */
for (octet_idx = 0;; num_octets -= enclen, octet_idx += enclen) {
if ((enclen = encode_length(buf, len, num_octets)) < 0)
return -1;
if (enclen > 0) {
memcpy(&buf[*len], &data[octet_idx], enclen);
*len += enclen;
}
if (enclen >= num_octets)
break;
}
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len)
{
int stat;
int stat2;
int i;
int j;
int k;
int l;
int m;
int x;
int limit;
int which;
int ptr;
int count;
int total_count;
int seq_no;
const uint8_t *msg;
const uint8_t *data;
int msg_len;
int repaired[16];
const uint8_t *bufs[16];
int lengths[16];
int span;
int entries;
ptr = 0;
/* Decode seq_number */
if (ptr + 2 > len)
return -1;
seq_no = (buf[0] << 8) | buf[1];
ptr += 2;
/* Break out the primary packet */
if ((stat = decode_open_type(buf, len, &ptr, &msg, &msg_len)) != 0)
return -1;
/* Decode error_recovery */
if (ptr + 1 > len)
return -1;
/* Our buffers cannot tolerate overlength packets */
if (msg_len > LOCAL_FAX_MAX_DATAGRAM)
return -1;
/* Update any missed slots in the buffer */
for (i = s->rx_seq_no; seq_no > i; i++) {
x = i & UDPTL_BUF_MASK;
s->rx[x].buf_len = -1;
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
}
/* Save the new packet. Pure redundancy mode won't use this, but some systems will switch
into FEC mode after sending some redundant packets. */
x = seq_no & UDPTL_BUF_MASK;
memcpy(s->rx[x].buf, msg, msg_len);
s->rx[x].buf_len = msg_len;
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
if ((buf[ptr++] & 0x80) == 0) {
/* Secondary packet mode for error recovery */
/* We might have the packet we want, but we need to check through
the redundant stuff, and verify the integrity of the UDPTL.
This greatly reduces our chances of accepting garbage. */
total_count = 0;
do {
if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
return -1;
for (i = 0; i < count; i++) {
if ((stat = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0)
return -1;
}
total_count += count;
}
while (stat2 > 0);
/* We should now be exactly at the end of the packet. If not, this is a fault. */
if (ptr != len)
return -1;
if (seq_no > s->rx_seq_no) {
/* We received a later packet than we expected, so we need to check if we can fill in the gap from the
secondary packets. */
/* Step through in reverse order, so we go oldest to newest */
for (i = total_count; i > 0; i--) {
if (seq_no - i >= s->rx_seq_no) {
/* This one wasn't seen before */
/* Decode the secondary packet */
#if defined(UDPTL_DEBUG)
fprintf(stderr, "Secondary %d, len %d\n", seq_no - i, lengths[i - 1]);
#endif
/* Save the new packet. Redundancy mode won't use this, but some systems will switch into
FEC mode after sending some redundant packets, and this may then be important. */
x = (seq_no - i) & UDPTL_BUF_MASK;
memcpy(s->rx[x].buf, bufs[i - 1], lengths[i - 1]);
s->rx[x].buf_len = lengths[i - 1];
s->rx[x].fec_len[0] = 0;
s->rx[x].fec_span = 0;
s->rx[x].fec_entries = 0;
if (s->rx_packet_handler(s->user_data, bufs[i - 1], lengths[i - 1], seq_no - i) < 0)
fprintf(stderr, "Bad IFP\n");
}
}
}
} else {
/* FEC mode for error recovery */
/* Decode the FEC packets */
/* The span is defined as an unconstrained integer, but will never be more
than a small value. */
if (ptr + 2 > len)
return -1;
if (buf[ptr++] != 1)
return -1;
span = buf[ptr++];
x = seq_no & UDPTL_BUF_MASK;
s->rx[x].fec_span = span;
memset(repaired, 0, sizeof(repaired));
repaired[x] = TRUE;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
if (ptr + 1 > len)
return -1;
entries = buf[ptr++];
s->rx[x].fec_entries = entries;
/* Decode the elements */
for (i = 0; i < entries; i++) {
if ((stat = decode_open_type(buf, len, &ptr, &data, &s->rx[x].fec_len[i])) != 0)
return -1;
if (s->rx[x].fec_len[i] > LOCAL_FAX_MAX_DATAGRAM)
return -1;
/* Save the new FEC data */
memcpy(s->rx[x].fec[i], data, s->rx[x].fec_len[i]);
#if 0
fprintf(stderr, "FEC: ");
for (j = 0; j < s->rx[x].fec_len[i]; j++)
fprintf(stderr, "%02X ", data[j]);
fprintf(stderr, "\n");
#endif
}
/* We should now be exactly at the end of the packet. If not, this is a fault. */
if (ptr != len)
return -1;
/* See if we can reconstruct anything which is missing */
/* TODO: this does not comprehensively hunt back and repair everything that is possible */
for (l = x; l != ((x - (16 - span * entries)) & UDPTL_BUF_MASK); l = (l - 1) & UDPTL_BUF_MASK) {
if (s->rx[l].fec_len[0] <= 0)
continue;
for (m = 0; m < s->rx[l].fec_entries; m++) {
limit = (l + m) & UDPTL_BUF_MASK;
for (which = -1, k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit;
k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK) {
if (s->rx[k].buf_len <= 0)
which = (which == -1) ? k : -2;
}
if (which >= 0) {
/* Repairable */
for (j = 0; j < s->rx[l].fec_len[m]; j++) {
s->rx[which].buf[j] = s->rx[l].fec[m][j];
for (k = (limit - s->rx[l].fec_span * s->rx[l].fec_entries) & UDPTL_BUF_MASK; k != limit;
k = (k + s->rx[l].fec_entries) & UDPTL_BUF_MASK)
s->rx[which].buf[j] ^= (s->rx[k].buf_len > j) ? s->rx[k].buf[j] : 0;
}
s->rx[which].buf_len = s->rx[l].fec_len[m];
repaired[which] = TRUE;
}
}
}
/* Now play any new packets forwards in time */
for (l = (x + 1) & UDPTL_BUF_MASK, j = seq_no - UDPTL_BUF_MASK; l != x; l = (l + 1) & UDPTL_BUF_MASK, j++) {
if (repaired[l]) {
#if defined(UDPTL_DEBUG)
fprintf(stderr, "Fixed packet %d, len %d\n", j, l);
#endif
if (s->rx_packet_handler(s->user_data, s->rx[l].buf, s->rx[l].buf_len, j) < 0)
fprintf(stderr, "Bad IFP\n");
}
}
}
/* If packets are received out of sequence, we may have already processed this packet from the error
recovery information in a packet already received. */
if (seq_no >= s->rx_seq_no) {
/* Decode the primary packet */
#if defined(UDPTL_DEBUG)
fprintf(stderr, "Primary packet %d, len %d\n", seq_no, msg_len);
#endif
if (s->rx_packet_handler(s->user_data, msg, msg_len, seq_no) < 0)
fprintf(stderr, "Bad IFP\n");
}
s->rx_seq_no = (seq_no + 1) & 0xFFFF;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int msg_len)
{
uint8_t fec[LOCAL_FAX_MAX_DATAGRAM];
int i;
int j;
int seq;
int entry;
int entries;
int span;
int m;
int len;
int limit;
int high_tide;
/* UDPTL cannot cope with zero length messages, and our buffering for redundancy limits their
maximum length. */
if (msg_len < 1 || msg_len > LOCAL_FAX_MAX_DATAGRAM)
return -1;
seq = s->tx_seq_no & 0xFFFF;
/* Map the sequence number to an entry in the circular buffer */
entry = seq & UDPTL_BUF_MASK;
/* We save the message in a circular buffer, for generating FEC or
redundancy sets later on. */
s->tx[entry].buf_len = msg_len;
memcpy(s->tx[entry].buf, msg, msg_len);
/* Build the UDPTL packet */
len = 0;
/* Encode the sequence number */
buf[len++] = (seq >> 8) & 0xFF;
buf[len++] = seq & 0xFF;
/* Encode the primary packet */
if (encode_open_type(buf, &len, msg, msg_len) < 0)
return -1;
/* Encode the appropriate type of error recovery information */
switch (s->error_correction_scheme) {
case UDPTL_ERROR_CORRECTION_NONE:
/* Encode the error recovery type */
buf[len++] = 0x00;
/* The number of entries will always be zero, so it is pointless allowing
for the fragmented case here. */
if (encode_length(buf, &len, 0) < 0)
return -1;
break;
case UDPTL_ERROR_CORRECTION_REDUNDANCY:
/* Encode the error recovery type */
buf[len++] = 0x00;
if (s->tx_seq_no > s->error_correction_entries)
entries = s->error_correction_entries;
else
entries = s->tx_seq_no;
/* The number of entries will always be small, so it is pointless allowing
for the fragmented case here. */
if (encode_length(buf, &len, entries) < 0)
return -1;
/* Encode the elements */
for (i = 0; i < entries; i++) {
j = (entry - i - 1) & UDPTL_BUF_MASK;
if (encode_open_type(buf, &len, s->tx[j].buf, s->tx[j].buf_len) < 0)
return -1;
}
break;
case UDPTL_ERROR_CORRECTION_FEC:
span = s->error_correction_span;
entries = s->error_correction_entries;
if (seq < s->error_correction_span * s->error_correction_entries) {
/* In the initial stages, wind up the FEC smoothly */
entries = seq / s->error_correction_span;
if (seq < s->error_correction_span)
span = 0;
}
/* Encode the error recovery type */
buf[len++] = 0x80;
/* Span is defined as an inconstrained integer, which it dumb. It will only
ever be a small value. Treat it as such. */
buf[len++] = 1;
buf[len++] = span;
/* The number of entries is defined as a length, but will only ever be a small
value. Treat it as such. */
buf[len++] = entries;
for (m = 0; m < entries; m++) {
/* Make an XOR'ed entry the maximum length */
limit = (entry + m) & UDPTL_BUF_MASK;
high_tide = 0;
for (i = (limit - span * entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK) {
if (high_tide < s->tx[i].buf_len) {
for (j = 0; j < high_tide; j++)
fec[j] ^= s->tx[i].buf[j];
for (; j < s->tx[i].buf_len; j++)
fec[j] = s->tx[i].buf[j];
high_tide = s->tx[i].buf_len;
} else {
for (j = 0; j < s->tx[i].buf_len; j++)
fec[j] ^= s->tx[i].buf[j];
}
}
if (encode_open_type(buf, &len, fec, high_tide) < 0)
return -1;
}
break;
}
if (s->verbose)
fprintf(stderr, "\n");
s->tx_seq_no++;
return len;
}
/*- End of function --------------------------------------------------------*/
int udptl_set_error_correction(udptl_state_t *s, int ec_scheme, int span, int entries)
{
switch (ec_scheme) {
case UDPTL_ERROR_CORRECTION_FEC:
case UDPTL_ERROR_CORRECTION_REDUNDANCY:
case UDPTL_ERROR_CORRECTION_NONE:
s->error_correction_scheme = ec_scheme;
break;
case -1:
/* Just don't change the scheme */
break;
default:
return -1;
}
if (span >= 0)
s->error_correction_span = span;
if (entries >= 0)
s->error_correction_entries = entries;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_get_error_correction(udptl_state_t *s, int *ec_scheme, int *span, int *entries)
{
if (ec_scheme)
*ec_scheme = s->error_correction_scheme;
if (span)
*span = s->error_correction_span;
if (entries)
*entries = s->error_correction_entries;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_set_local_max_datagram(udptl_state_t *s, int max_datagram)
{
s->local_max_datagram_size = max_datagram;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_get_local_max_datagram(udptl_state_t *s)
{
return s->local_max_datagram_size;
}
/*- End of function --------------------------------------------------------*/
int udptl_set_far_max_datagram(udptl_state_t *s, int max_datagram)
{
s->far_max_datagram_size = max_datagram;
return 0;
}
/*- End of function --------------------------------------------------------*/
int udptl_get_far_max_datagram(udptl_state_t *s)
{
return s->far_max_datagram_size;
}
/*- End of function --------------------------------------------------------*/
udptl_state_t *udptl_init(udptl_state_t *s, int ec_scheme, int span, int entries, udptl_rx_packet_handler_t rx_packet_handler, void *user_data)
{
int i;
if (rx_packet_handler == NULL)
return NULL;
if (s == NULL) {
if ((s = (udptl_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
memset(s, 0, sizeof(*s));
s->error_correction_scheme = ec_scheme;
s->error_correction_span = span;
s->error_correction_entries = entries;
s->far_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
s->local_max_datagram_size = LOCAL_FAX_MAX_DATAGRAM;
memset(&s->rx, 0, sizeof(s->rx));
memset(&s->tx, 0, sizeof(s->tx));
for (i = 0; i <= UDPTL_BUF_MASK; i++) {
s->rx[i].buf_len = -1;
s->tx[i].buf_len = -1;
}
s->rx_packet_handler = rx_packet_handler;
s->user_data = user_data;
return s;
}
/*- End of function --------------------------------------------------------*/
int udptl_release(udptl_state_t *s)
{
return 0;
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/
-153
View File
@@ -1,153 +0,0 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2009, Steve Underwood <steveu@coppice.org>
*
* 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.
*
* Contributor(s):
*
* Steve Underwood <steveu@coppice.org>
*
* udptl.h -- UDPTL handling for T.38
*
*/
#if !defined(FREESWITCH_UDPTL_H)
#define FREESWITCH_UDPTL_H
#define LOCAL_FAX_MAX_DATAGRAM 400
#define LOCAL_FAX_MAX_FEC_PACKETS 5
#define UDPTL_BUF_MASK 15
typedef int (udptl_rx_packet_handler_t) (void *user_data, const uint8_t msg[], int len, int seq_no);
typedef struct {
int buf_len;
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
} udptl_fec_tx_buffer_t;
typedef struct {
int buf_len;
uint8_t buf[LOCAL_FAX_MAX_DATAGRAM];
int fec_len[LOCAL_FAX_MAX_FEC_PACKETS];
uint8_t fec[LOCAL_FAX_MAX_FEC_PACKETS][LOCAL_FAX_MAX_DATAGRAM];
int fec_span;
int fec_entries;
} udptl_fec_rx_buffer_t;
struct udptl_state_s {
udptl_rx_packet_handler_t *rx_packet_handler;
void *user_data;
/*! This option indicates the error correction scheme used in transmitted UDPTL
packets. */
int error_correction_scheme;
/*! This option indicates the number of error correction entries transmitted in
UDPTL packets. */
int error_correction_entries;
/*! This option indicates the span of the error correction entries in transmitted
UDPTL packets (FEC only). */
int error_correction_span;
/*! This option indicates the maximum size of a datagram that can be accepted by
the remote device. */
int far_max_datagram_size;
/*! This option indicates the maximum size of a datagram that we are prepared to
accept. */
int local_max_datagram_size;
int verbose;
int tx_seq_no;
int rx_seq_no;
int rx_expected_seq_no;
udptl_fec_tx_buffer_t tx[UDPTL_BUF_MASK + 1];
udptl_fec_rx_buffer_t rx[UDPTL_BUF_MASK + 1];
};
enum {
UDPTL_ERROR_CORRECTION_NONE,
UDPTL_ERROR_CORRECTION_FEC,
UDPTL_ERROR_CORRECTION_REDUNDANCY
};
typedef struct udptl_state_s udptl_state_t;
#if defined(__cplusplus)
extern "C" {
#endif
/*! \brief Process an arriving UDPTL packet.
\param s The UDPTL context.
\param buf The UDPTL packet buffer.
\param len The length of the packet.
\return 0 for OK. */
int udptl_rx_packet(udptl_state_t *s, const uint8_t buf[], int len);
/*! \brief Construct a UDPTL packet, ready for transmission.
\param s The UDPTL context.
\param buf The UDPTL packet buffer.
\param msg The primary packet.
\param len The length of the primary packet.
\return The length of the constructed UDPTL packet. */
int udptl_build_packet(udptl_state_t *s, uint8_t buf[], const uint8_t msg[], int msg_len);
/*! \brief Change the error correction settings of a UDPTL context.
\param s The UDPTL context.
\param ec_scheme One of the optional error correction schemes.
\param span The packet span over which error correction should be applied.
\param entries The number of error correction entries to include in packets.
\return 0 for OK. */
int udptl_set_error_correction(udptl_state_t *s, int ec_scheme, int span, int entries);
/*! \brief Check the error correction settings of a UDPTL context.
\param s The UDPTL context.
\param ec_scheme One of the optional error correction schemes.
\param span The packet span over which error correction is being applied.
\param entries The number of error correction being included in packets.
\return 0 for OK. */
int udptl_get_error_correction(udptl_state_t *s, int *ec_scheme, int *span, int *entries);
int udptl_set_local_max_datagram(udptl_state_t *s, int max_datagram);
int udptl_get_local_max_datagram(udptl_state_t *s);
int udptl_set_far_max_datagram(udptl_state_t *s, int max_datagram);
int udptl_get_far_max_datagram(udptl_state_t *s);
/*! \brief Initialise a UDPTL context.
\param s The UDPTL context.
\param ec_scheme One of the optional error correction schemes.
\param span The packet span over which error correction should be applied.
\param entries The number of error correction entries to include in packets.
\param rx_packet_handler The callback function, used to report arriving IFP packets.
\param user_data An opaque pointer supplied to rx_packet_handler.
\return A pointer to the UDPTL context, or NULL if there was a problem. */
udptl_state_t *udptl_init(udptl_state_t *s, int ec_scheme, int span, int entries, udptl_rx_packet_handler_t rx_packet_handler, void *user_data);
/*! \brief Release a UDPTL context.
\param s The UDPTL context.
\return 0 for OK. */
int udptl_release(udptl_state_t *s);
#if defined(__cplusplus)
}
#endif
#endif
/*- End of file ------------------------------------------------------------*/
+22 -6
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1121,7 +1121,7 @@ static switch_status_t messagehook (switch_core_session_t *session, switch_core_
"(fifo_name,caller_uuid,caller_caller_id_name,caller_caller_id_number,consumer_uuid,consumer_outgoing_uuid,bridge_start) "
"values ('%q','%q','%q','%q','%q','%q',%ld)",
MANUAL_QUEUE_NAME,
"N/A",
(msg->string_arg && strchr(msg->string_arg, '-')) ? msg->string_arg : "00000000-0000-0000-0000-000000000000",
ced_name,
ced_number,
switch_core_session_get_uuid(session),
@@ -2926,12 +2926,27 @@ SWITCH_STANDARD_APP(fifo_function)
if (!(switch_channel_ready(channel))) {
const char *app = switch_channel_get_variable(other_channel, "current_application");
const char *arg = switch_channel_get_variable(other_channel, "current_application_data");
switch_caller_extension_t *extension = NULL;
switch_caller_extension_t *extension = NULL;
switch_channel_set_variable_printf(channel, "last_sent_callee_id_name", "%s (AGENT FAIL)",
switch_channel_get_variable(other_channel, "caller_id_name"));
switch_channel_set_variable(channel, "last_sent_callee_id_number", switch_channel_get_variable(other_channel, "caller_id_number"));
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
"Customer %s %s [%s] appears to be abandoned by agent %s [%s] "
"but is still on the line, redirecting them back to the queue with VIP status.\n",
switch_channel_get_name(other_channel),
switch_channel_get_variable(other_channel, "caller_id_name"),
switch_channel_get_variable(other_channel, "caller_id_number"),
switch_channel_get_variable(channel, "caller_id_name"),
switch_channel_get_variable(channel, "caller_id_number"));
switch_channel_wait_for_state_timeout(other_channel, CS_HIBERNATE, 5000);
send_presence(node);
check_cancel(node);
if (app) {
extension = switch_caller_extension_new(other_session, app, arg);
switch_caller_extension_add_application(other_session, extension, app, arg);
@@ -2940,6 +2955,7 @@ SWITCH_STANDARD_APP(fifo_function)
} else {
switch_channel_hangup(other_channel, SWITCH_CAUSE_NORMAL_CLEARING);
}
switch_channel_set_variable(other_channel, "fifo_vip", "true");
switch_core_session_rwunlock(other_session);
break;
@@ -3098,6 +3114,7 @@ SWITCH_STANDARD_APP(fifo_function)
send_presence(node);
check_cancel(node);
switch_core_session_rwunlock(other_session);
@@ -3230,7 +3247,6 @@ SWITCH_STANDARD_APP(fifo_function)
switch_channel_clear_app_flag_key(FIFO_APP_KEY, channel, FIFO_APP_BRIDGE_TAG);
switch_core_media_bug_resume(session);
}
struct xml_helper {
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+3 -6
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -451,8 +451,6 @@ SWITCH_STANDARD_APP(hash_function)
value = strdup(argv[3]);
switch_assert(value);
switch_core_hash_insert(globals.db_hash, hash_key, value);
} else {
switch_safe_free(value);
}
} else if (!strcasecmp(argv[0], "delete")) {
@@ -466,9 +464,9 @@ SWITCH_STANDARD_APP(hash_function)
}
if ((value = switch_core_hash_find(globals.db_hash, hash_key))) {
if(!strcmp(argv[3], value)) {
switch_safe_free(value);
switch_core_hash_delete(globals.db_hash, hash_key);
}
switch_safe_free(value);
}
} else {
goto usage;
@@ -527,7 +525,6 @@ SWITCH_STANDARD_API(hash_api_function)
switch_thread_rwlock_wrlock(globals.db_hash_rwlock);
if ((value = switch_core_hash_find(globals.db_hash, hash_key))) {
stream->write_function(stream, "-ERR key already exists\n");
switch_safe_free(value);
} else {
value = strdup(argv[3]);
switch_assert(value);
@@ -552,12 +549,12 @@ SWITCH_STANDARD_API(hash_api_function)
switch_thread_rwlock_wrlock(globals.db_hash_rwlock);
if ((value = switch_core_hash_find(globals.db_hash, hash_key))) {
if(!strcmp(argv[3],value)) {
switch_safe_free(value);
switch_core_hash_delete(globals.db_hash, hash_key);
stream->write_function(stream, "+OK\n");
} else {
stream->write_function(stream, "-ERR Doesn't match\n");
}
switch_safe_free(value);
} else {
stream->write_function(stream, "-ERR Not found\n");
}
@@ -319,7 +319,7 @@ user-agent : <string> mod_httapi/1.0 User Agent header value.
<permissions>: * = default
<permission name="" value="">
<permission name="" value="true">
*set-params : <params> tag can be parsed for session params.
set-vars : <variables> tag can be parsed to set channel vars.
+6 -4
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1142,7 +1142,8 @@ static switch_status_t parse_xml(client_t *client)
switch_channel_get_variables(client->channel, &templ_data);
switch_event_merge(templ_data, client->params);
expanded = switch_event_expand_headers_check(templ_data, tag->txt,
client->profile->var_params.expand_var_list, client->profile->var_params.api_list);
client->profile->var_params.expand_var_list,
client->profile->var_params.api_list, 0);
switch_event_destroy(&templ_data);
}
@@ -1324,7 +1325,7 @@ static void cleanup_attachments(client_t *client)
for (hp = client->params->headers; hp; hp = hp->next) {
if (!strncasecmp(hp->name, "attach_file:", 12)) {
if (switch_file_exists(hp->value, client->pool)) {
if (switch_file_exists(hp->value, client->pool) == SWITCH_STATUS_SUCCESS) {
printf("DELETE %s\n", hp->value);
unlink(hp->value);
}
@@ -1498,7 +1499,7 @@ static switch_status_t httapi_sync(client_t *client)
switch_curl_easy_setopt(curl_handle, CURLOPT_HTTPHEADER, headers);
if (method != NULL && strcasecmp(method, "get") && strcasecmp(method, "post")) {
if (!zstr(method)) {
switch_curl_easy_setopt(curl_handle, CURLOPT_CUSTOMREQUEST, method);
}
@@ -2160,6 +2161,7 @@ SWITCH_STANDARD_APP(httapi_function)
if (!zstr(url) && switch_stristr("://", url)) {
if (!params) {
switch_event_create(&params, SWITCH_EVENT_CLONE);
params->flags |= EF_UNIQ_HEADERS;
}
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "url", url);
}
@@ -3,6 +3,9 @@
<param name="max-urls" value="10000"/>
<param name="location" value="$${base_dir}/http_cache"/>
<param name="default-max-age" value="86400"/>
<param name="ssl-cacert" value="$${base_dir}/conf/cacert.pem"/>
<param name="ssl-verifyhost" value="true"/>
<param name="ssl-verifypeer" value="true"/>
</settings>
</configuration>
File diff suppressed because it is too large Load Diff
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -23,7 +23,9 @@
*
* Contributor(s):
*
* Chris Rienzo <chris@rienzo.net>
* Christopher M. Rienzo <chris@rienzo.net>
*
* Maintainer: Christopher M. Rienzo <chris@rienzo.net>
*
* mod_http_cache.c -- HTTP GET with caching
* -- designed for downloading audio files from a webserver for playback
@@ -96,12 +98,12 @@ struct http_get_data {
};
typedef struct http_get_data http_get_data_t;
static switch_status_t http_get(cached_url_t *url, switch_core_session_t *session);
static switch_status_t http_get(url_cache_t *cache, cached_url_t *url, switch_core_session_t *session);
static size_t get_file_callback(void *ptr, size_t size, size_t nmemb, void *get);
static size_t get_header_callback(void *ptr, size_t size, size_t nmemb, void *url);
static void process_cache_control_header(cached_url_t *url, char *data);
static switch_status_t http_put(switch_core_session_t *session, const char *url, const char *filename);
static switch_status_t http_put(url_cache_t *cache, switch_core_session_t *session, const char *url, const char *filename);
/**
* Queue used for clock cache replacement algorithm. This
@@ -159,6 +161,12 @@ struct url_cache {
int shutdown;
/** Synchronizes shutdown of cache */
switch_thread_rwlock_t *shutdown_lock;
/** SSL cert filename */
char *ssl_cacert;
/** Verify certificate */
int ssl_verifypeer;
/** Verify that hostname matches certificate */
int ssl_verifyhost;
};
static url_cache_t gcache;
@@ -173,12 +181,13 @@ static void url_cache_clear(url_cache_t *cache, switch_core_session_t *session);
/**
* Put a file to the URL
* @param cache the cache
* @param session the (optional) session uploading the file
* @param url The URL
* @param filename The file to upload
* @return SWITCH_STATUS_SUCCESS if successful
*/
static switch_status_t http_put(switch_core_session_t *session, const char *url, const char *filename)
static switch_status_t http_put(url_cache_t *cache, switch_core_session_t *session, const char *url, const char *filename)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
CURL *curl_handle = NULL;
@@ -223,6 +232,18 @@ static switch_status_t http_put(switch_core_session_t *session, const char *url,
switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-http-cache/1.0");
if (!cache->ssl_verifypeer) {
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
} else {
/* this is the file with all the trusted certificate authorities */
if (!zstr(cache->ssl_cacert)) {
switch_curl_easy_setopt(curl_handle, CURLOPT_CAINFO, cache->ssl_cacert);
}
/* verify that the host name matches the cert */
if (!cache->ssl_verifyhost) {
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
}
}
switch_curl_easy_perform(curl_handle);
switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
switch_curl_easy_cleanup(curl_handle);
@@ -346,7 +367,7 @@ static void process_cache_control_header(cached_url_t *url, char *data)
return;
}
url->max_age = switch_time_now() + (max_age * 1000 * 1000);
url->max_age = max_age * 1000 * 1000;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "setting max age to %u seconds from now\n", (int)max_age);
}
@@ -485,7 +506,7 @@ static char *url_cache_get(url_cache_t *cache, switch_core_session_t *session, c
/* download the file */
url_cache_unlock(cache, session);
if (http_get(u, session) == SWITCH_STATUS_SUCCESS) {
if (http_get(cache, u, session) == SWITCH_STATUS_SUCCESS) {
/* Got the file, let the waiters know it is available */
url_cache_lock(cache, session);
u->status = CACHED_URL_AVAILABLE;
@@ -708,11 +729,12 @@ static void cached_url_destroy(cached_url_t *url, switch_memory_pool_t *pool)
/**
* Fetch a file via HTTP
* @param cache the cache
* @param url The cached URL entry
* @param session the (optional) session
* @return SWITCH_STATUS_SUCCESS if successful
*/
static switch_status_t http_get(cached_url_t *url, switch_core_session_t *session)
static switch_status_t http_get(url_cache_t *cache, cached_url_t *url, switch_core_session_t *session)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_CURL *curl_handle = NULL;
@@ -734,7 +756,19 @@ static switch_status_t http_get(cached_url_t *url, switch_core_session_t *sessio
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &get_data);
switch_curl_easy_setopt(curl_handle, CURLOPT_HEADERFUNCTION, get_header_callback);
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEHEADER, (void *) url);
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-http-cache/1.0");
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-http-cache/1.0");
if (!cache->ssl_verifypeer) {
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0L);
} else {
/* this is the file with all the trusted certificate authorities */
if (!zstr(cache->ssl_cacert)) {
switch_curl_easy_setopt(curl_handle, CURLOPT_CAINFO, cache->ssl_cacert);
}
/* verify that the host name matches the cert */
if (!cache->ssl_verifyhost) {
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0L);
}
}
switch_curl_easy_perform(curl_handle);
switch_curl_easy_getinfo(curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
switch_curl_easy_cleanup(curl_handle);
@@ -791,7 +825,7 @@ static void setup_dir(url_cache_t *cache)
static int isUrl(const char *filename)
{
return !zstr(filename) && !strncmp("http://", filename, strlen("http://"));
return !zstr(filename) && (!strncmp("http://", filename, strlen("http://")) || !strncmp("https://", filename, strlen("https://")));
}
#define HTTP_PREFETCH_SYNTAX "<url>"
@@ -910,7 +944,7 @@ SWITCH_STANDARD_API(http_cache_put)
char *argv[10] = { 0 };
int argc = 0;
if (zstr(cmd) || strncmp("http://", cmd, strlen("http://"))) {
if (zstr(cmd) || (strncmp("http://", cmd, strlen("http://")) && strncmp("https://", cmd, strlen("https://")))) {
stream->write_function(stream, "USAGE: %s\n", HTTP_PUT_SYNTAX);
status = SWITCH_STATUS_SUCCESS;
goto done;
@@ -924,7 +958,7 @@ SWITCH_STANDARD_API(http_cache_put)
goto done;
}
status = http_put(session, argv[0], argv[1]);
status = http_put(&gcache, session, argv[0], argv[1]);
if (status == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "+OK\n");
} else {
@@ -1013,6 +1047,9 @@ static switch_status_t do_config(url_cache_t *cache)
cache->location = SWITCH_PREFIX_DIR "/http_cache";
cache->prefetch_queue_size = 100;
cache->prefetch_thread_count = 8;
cache->ssl_cacert = SWITCH_PREFIX_DIR "/conf/cacert.pem";
cache->ssl_verifyhost = 1;
cache->ssl_verifypeer = 1;
/* get params */
settings = switch_xml_child(cfg, "settings");
@@ -1035,6 +1072,15 @@ static switch_status_t do_config(url_cache_t *cache)
} else if (!strcasecmp(var, "prefetch-thread-count")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting prefetch-thread-count to %s\n", val);
cache->prefetch_thread_count = atoi(val);
} else if (!strcasecmp(var, "ssl-cacert")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting ssl-cacert to %s\n", val);
cache->ssl_cacert = switch_core_strdup(cache->pool, val);
} else if (!strcasecmp(var, "ssl-verifyhost")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting ssl-verifyhost to %s\n", val);
cache->ssl_verifyhost = !switch_false(val); /* only disable if explicitly set to false */
} else if (!strcasecmp(var, "ssl-verifypeer")) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Setting ssl-verifypeer to %s\n", val);
cache->ssl_verifypeer = !switch_false(val); /* only disable if explicitly set to false */
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unsupported param: %s\n", var);
}
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+4 -1
View File
@@ -24,6 +24,9 @@ $(MONGO_CXX_DRIVER_SRC):
$(LIBMONGOCLIENT_A): $(MONGO_CXX_DRIVER_SRC)
cd $(MONGO_CXX_DRIVER_SRC) && scons
(cd $(MONGO_CXX_DRIVER_SRC) && \
sed -i SConstruct -e "s/Environment()/Environment(ENV = {'PATH' : os.environ['PATH'],'CFLAGS' : os.environ['CFLAGS'],'CXXFLAGS' : os.environ['CXXFLAGS']})/" && \
echo "env.Append(PATH=os.environ['PATH'])" >> SConstruct && \
scons)
$(TOUCH_TARGET)
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -287,7 +287,7 @@ static void transfer_call(switch_core_session_t *session, char *destination)
switch_separate_string(mydup, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
/* Find the uuid of our B leg. If it exists, transfer it first */
if ((uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
if ((uuid = switch_channel_get_partner_uuid(channel))) {
switch_core_session_t *b_session;
/* Get info on the B leg */
@@ -0,0 +1,84 @@
FreeSWITCH Open Settlement Protocol (OSP) module
This module provides OSP based call authentication, authorization, routing lookup and call detail record (CDR) collection services using standard FreeSWITCH application and dailplan interfaces.
The OSP module can be configured by the following parameters in osp.conf.xml:
Global parameters:
<settings>
<param name="*NAME*" value="*VALUE*"/>
</settings>
Global parameter names and values can be:
debug-info: Flag to show OSP module debug information. The default is "disabled".
log-level: At which log level to show OSP module debug information. The default is "info".
crypto-hardware: If to use hardware for OpenSSL. The default is "disabled".
sip: Used SIP module and profile. The default is "sofia" and "external".
h323: Used H.323 module and profile. The default is "h323" and "external". This option has not been implemented.
iax: Used IAX2 module and profile. The default is "iax" and "external". This option has not been implemented.
skype: Used Skype module and profile. The default is "skypopen" and "external". This option has not been implemented.
default-protocol: The VoIP protocol for destinations with unknown/undefined protocol. The default is "sip".
OSP provider parameters:
<profiles>
<profile name="default">
<param name="*NAME*" value="*VALUE*"/>
</profile>
</profiles>
OSP provider parameter names ane values cab be:
profile: OSP provider profile name.
service-point-url: OSP service point URL. This parameter must be defined. Up to 8 URLs are allowed.
device-ip: FreeSWITCH IP for OSP module. This parameter must be defined.
ssl-lifetime: SSL lifetime. The default is 300 in seconds.
http-max-connections: HTTP max connections. The default is 20.
http-persistence: HTTP persistence. The default is 60 in seconds.
http-retry-delay: HTTP retry delay. The default is 0 in seconds.
http-retry-limit: HTTP retry times. The default is 2.
http-timeout: HTTP timeout. The default is 10000 in ms.
work-mode: OSP module work mode (direct and indirect). The default is "direct".
service-type: OSP service type (voice and npquery). The default is "voice".
max-destinations: Max destinations OSP server will return. It is up to 12. The default is 12.
The OSP application is called in dial plan like this:
<action application="osp" data="<profilename>"/>
The OSP dialplan is called in dial plan like this:
<param name="dialplan" value="osp:<profilename>"/>
For both OSP application and dialplan, the <profilename> is an OSP service provider name configured in osp.conf.xml. If it is empty, profile "default" is used.
Both OSP application and dialplan accept a set of inbound channel variables that are used to pass additional call information to OSP module. These channel variables include:
osp_source_device: Actual source device IP address channel variable. It is only for FreeSWITH OSP module running in indirect mode.
osp_source_nid: Source device network ID channel variable.
osp_custom_info_N: Up to 8 custom info channel variables. N is the index starting from 1.
osp_networkid_userparam: The URI user parameter name that is used to present destination network ID.
osp_networkid_uriparam: The URI parameter name that is used to present destination network ID.
osp_user_phone: Flag to add "user=phone" URI parameter. The default is "disabled".
osp_outbound_proxy: Outbound proxy IP address channel variable.
Both OSP application and dialplan also export a set of channel variables for outbound channels and FreeSWITCH dial plan logic (for OSP dialplan, some exported channel variables are not visible for dial plan). These channel variables include:
osp_profile: Used OSP profile name. Used by outbound channels.
osp_transaction_id: OSP transaction ID. Used by outbound channels.
osp_calling: Original inbound calling number. Used by outbound channels.
osp_called: Original inbound called number. Used by outbound channels.
osp_start_time: Inbound call start time. Used by outbound channels.
osp_source_device: Actual source device. Used by outbound channels. It is only for FreeSWITH OSP module running in indirect mode.
osp_source_nid: Source network ID. Used by outbound channels.
osp_destination_total: Total number of destinations from OSP servers. Used by outbound channels.
osp_destination_count: Destination index. Used by outbound channels.
osp_destination_ip: Destination IP. Used by outbound channels.
osp_destination_nid: Destination network ID. Used by outbound channels.
osp_authreq_status: Authorization request result status.
osp_route_count: Number of supported destinations.
osp_route_N: Destination route string. N is the index starting from 1.
osp_auto_route: Bridge route string.
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2009, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -0,0 +1,234 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* 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 <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Anthony Minessale II <anthm@freeswitch.org>
* Neal Horman <neal at wanlink dot com>
*
*
* mod_random.c -- entropy source module
*
*/
#include <switch.h>
/* Prototypes */
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_random_shutdown);
SWITCH_MODULE_RUNTIME_FUNCTION(mod_random_runtime);
SWITCH_MODULE_LOAD_FUNCTION(mod_random_load);
SWITCH_MODULE_DEFINITION(mod_random, mod_random_load, mod_random_shutdown, mod_random_runtime);
static int RUNNING = 0;
static const char *random_device_files[] = { "/dev/hwrandom", "/dev/random", NULL };
const char *random_device_file = NULL;
static void event_handler(switch_event_t *event);
SWITCH_MODULE_LOAD_FUNCTION(mod_random_load)
{
#ifdef WIN32
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s missing window support\n", modname);
return SWITCH_STATUS_NOTIMPL;
#endif
int i = 0;
for(i = 0 ;random_device_files[i]; i++) {
if (switch_file_exists(random_device_files[i], pool) == SWITCH_STATUS_SUCCESS) {
random_device_file = random_device_files[i];
break;
}
}
if (!random_device_file) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s can't locate a random device file\n", modname);
return SWITCH_STATUS_FALSE;
}
if ((switch_event_bind(modname, SWITCH_EVENT_ALL, NULL, event_handler, NULL) != SWITCH_STATUS_SUCCESS)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
return SWITCH_STATUS_TERM;
}
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
RUNNING = 1;
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_random_shutdown)
{
switch_event_unbind_callback(event_handler);
RUNNING = 0;
return SWITCH_STATUS_SUCCESS;
}
#if WIN32
SWITCH_MODULE_RUNTIME_FUNCTION(mod_random_runtime)
{
RUNNING = 0;
return SWITCH_STATUS_TERM;
}
#else
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <syslog.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/time.h>
#include <time.h>
#include <linux/types.h>
#include <linux/random.h>
#include <string.h>
typedef struct {
int count;
int size;
unsigned char *data;
} entropy_t;
static int random_add_entropy(int fd, void *buf, size_t size)
{
entropy_t e = { 0 };
int r = 0;
e.count = size * 8;
e.size = size;
e.data = (unsigned char *) buf;
if (ioctl(fd, RNDADDENTROPY, &e) != 0) {
r = 1;
}
return r;
}
static int rng_read(int fd, void *buf, size_t size)
{
size_t off = 0;
ssize_t r;
unsigned char *bp = (unsigned char *) buf;
while (size > 0) {
do {
r = read(fd, bp + off, size);
} while ((r == -1) && (errno == EINTR));
if (r <= 0) {
break;
}
off += r;
size -= r;
}
return size;
}
static int rfd = 0;
static void event_handler(switch_event_t *event)
{
char *buf;
if (switch_event_serialize(event, &buf, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
random_add_entropy(rfd, buf, strlen(buf));
free(buf);
}
}
SWITCH_MODULE_RUNTIME_FUNCTION(mod_random_runtime)
{
unsigned char data[1024] = {0};
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s Thread starting using random_device_file %s\n", modname, random_device_file);
if ((rfd = open(random_device_file, O_RDWR)) < 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Error opening random_device_file %s\n", modname, random_device_file);
RUNNING = 0;
}
rng_read(rfd, data, 4);
while(RUNNING) {
int16_t data[64];
int i = 0;
int len = sizeof(data) / 2;
switch_generate_sln_silence(data, len, 1);
random_add_entropy(rfd, data, len);
while(i < len && !data[i]) i++;
if (i < len) {
switch_yield(abs(data[i]) * 1000);
}
}
if (rfd > -1) {
close(rfd);
}
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s Thread ending\n", modname);
return SWITCH_STATUS_TERM;
}
#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
*/
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
+1 -1
View File
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*
@@ -43,12 +43,17 @@ typedef struct {
uint32_t last_digit_end;
uint32_t digit_begin;
uint32_t min_dup_digit_spacing;
int twist;
int reverse_twist;
int filter_dialtone;
int threshold;
} switch_inband_dtmf_t;
static void spandsp_dtmf_rx_realtime_callback(void *user_data, int code, int level, int delay)
static void spandsp_dtmf_rx_realtime_callback(void *user_data, int code, int level, int duration)
{
switch_inband_dtmf_t *pvt = (switch_inband_dtmf_t *)user_data;
char digit = (char)code;
pvt->samples += duration;
if (digit) {
/* prevent duplicate DTMF */
if (digit != pvt->last_digit || (pvt->samples - pvt->last_digit_end) > pvt->min_dup_digit_spacing) {
@@ -74,16 +79,12 @@ static switch_bool_t inband_dtmf_callback(switch_media_bug_t *bug, void *user_da
{
switch_inband_dtmf_t *pvt = (switch_inband_dtmf_t *) user_data;
switch_frame_t *frame = NULL;
switch_channel_t *channel = switch_core_session_get_channel(pvt->session);
switch (type) {
case SWITCH_ABC_TYPE_INIT: {
const char *min_dup_digit_spacing_str = switch_channel_get_variable(channel, "min_dup_digit_spacing_ms");
pvt->dtmf_detect = dtmf_rx_init(NULL, NULL, NULL);
dtmf_rx_parms(pvt->dtmf_detect, pvt->filter_dialtone, pvt->twist, pvt->reverse_twist, pvt->threshold);
dtmf_rx_set_realtime_callback(pvt->dtmf_detect, spandsp_dtmf_rx_realtime_callback, pvt);
if (!zstr(min_dup_digit_spacing_str)) {
pvt->min_dup_digit_spacing = atoi(min_dup_digit_spacing_str) * 8;
}
break;
}
case SWITCH_ABC_TYPE_CLOSE:
@@ -93,7 +94,6 @@ static switch_bool_t inband_dtmf_callback(switch_media_bug_t *bug, void *user_da
break;
case SWITCH_ABC_TYPE_READ_REPLACE:
if ((frame = switch_core_media_bug_get_read_replace_frame(bug))) {
pvt->samples += frame->samples;
dtmf_rx(pvt->dtmf_detect, frame->data, frame->samples);
switch_core_media_bug_set_read_replace_frame(bug, frame);
}
@@ -126,6 +126,7 @@ switch_status_t spandsp_inband_dtmf_session(switch_core_session_t *session)
switch_status_t status;
switch_inband_dtmf_t *pvt;
switch_codec_implementation_t read_impl = { 0 };
const char *value;
switch_core_session_get_read_impl(session, &read_impl);
@@ -133,8 +134,60 @@ switch_status_t spandsp_inband_dtmf_session(switch_core_session_t *session)
return SWITCH_STATUS_MEMERR;
}
pvt->session = session;
pvt->session = session;
/* get detector params */
pvt->min_dup_digit_spacing = 0;
value = switch_channel_get_variable(channel, "min_dup_digit_spacing_ms");
if (!zstr(value) && switch_is_number(value)) {
int val = atoi(value) * 8; /* convert from ms to samples */
if (val < 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "min_dup_digit_spacing_ms must be >= 0\n");
} else {
pvt->min_dup_digit_spacing = val;
}
}
pvt->threshold = -100;
value = switch_channel_get_variable(channel, "spandsp_dtmf_rx_threshold");
if (!zstr(value) && switch_is_number(value)) {
int val = atoi(value);
if (val < -99) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "spandsp_dtmf_rx_threshold must be >= -99 dBm0\n");
} else {
pvt->threshold = val;
}
}
pvt->twist = -1;
value = switch_channel_get_variable(channel, "spandsp_dtmf_rx_twist");
if (!zstr(value) && switch_is_number(value)) {
int val = atoi(value);
if (val < 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "spandsp_dtmf_rx_twist must be >= 0 dB\n");
} else {
pvt->twist = val;
}
}
pvt->reverse_twist = -1;
value = switch_channel_get_variable(channel, "spandsp_dtmf_rx_reverse_twist");
if (!zstr(value) && switch_is_number(value)) {
int val = atoi(value);
if (val < 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "spandsp_dtmf_rx_reverse_twist must be >= 0 dB\n");
} else {
pvt->reverse_twist = val;
}
}
pvt->filter_dialtone = -1;
value = switch_channel_get_variable(channel, "spandsp_dtmf_rx_filter_dialtone");
if (switch_true(value)) {
pvt->filter_dialtone = 1;
} else if (switch_false(value)) {
pvt->filter_dialtone = 0;
}
if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_FALSE;
@@ -1,6 +1,6 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
* Copyright (C) 2005-2012, Anthony Minessale II <anthm@freeswitch.org>
*
* Version: MPL 1.1
*

Some files were not shown because too many files have changed in this diff Show More