mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-23 04:31:50 +00:00
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:
+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
|
||||
*
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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,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-2010, 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
|
||||
*
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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,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-2010, 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
|
||||
*
|
||||
@@ -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,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/2006, 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/2006, 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
|
||||
*
|
||||
@@ -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,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
|
||||
*
|
||||
|
||||
@@ -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
|
||||
*
|
||||
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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,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,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
@@ -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 ------------------------------------------------------------*/
|
||||
@@ -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 ------------------------------------------------------------*/
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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.
|
||||
|
||||
@@ -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(¶ms, 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,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
|
||||
*
|
||||
|
||||
@@ -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,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
|
||||
*
|
||||
@@ -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,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,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
|
||||
*
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user