Merge branch 'staging-1.9'

This commit is contained in:
Anthony Minessale
2016-09-27 17:32:53 -05:00
71 changed files with 9336 additions and 529 deletions
+11
View File
@@ -189,7 +189,13 @@ struct switch_core_session {
uint32_t decoder_errors;
switch_core_video_thread_callback_func_t video_read_callback;
void *video_read_user_data;
switch_core_video_thread_callback_func_t text_read_callback;
void *text_read_user_data;
switch_io_routines_t *io_override;
switch_slin_data_t *sdata;
switch_buffer_t *text_buffer;
switch_mutex_t *text_mutex;
};
struct switch_media_bug {
@@ -228,6 +234,11 @@ struct switch_media_bug {
switch_image_t *spy_img[2];
switch_vid_spy_fmt_t spy_fmt;
switch_thread_t *video_bug_thread;
switch_buffer_t *text_buffer;
char *text_framedata;
uint32_t text_framesize;
struct switch_media_bug *next;
};
+2
View File
@@ -162,6 +162,8 @@ SWITCH_DECLARE(void) switch_buffer_destroy(switch_buffer_t **buffer);
SWITCH_DECLARE(switch_size_t) switch_buffer_zwrite(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen)
const void *data, _In_ switch_size_t datalen);
SWITCH_DECLARE(void *) switch_buffer_get_head_pointer(switch_buffer_t *buffer);
/** @} */
SWITCH_END_EXTERN_C
+5
View File
@@ -317,6 +317,11 @@ SWITCH_DECLARE(switch_status_t) switch_channel_get_variables(switch_channel_t *c
SWITCH_DECLARE(switch_status_t) switch_channel_pass_callee_id(switch_channel_t *channel, switch_channel_t *other_channel);
static inline int switch_channel_var_true(switch_channel_t *channel, const char *variable) {
return switch_true(switch_channel_get_variable_dup(channel, variable, SWITCH_FALSE, -1));
}
/*!
* \brief Start iterating over the entries in the channel variable list.
* \param channel the channel to iterate the variables for
+9
View File
@@ -351,6 +351,8 @@ SWITCH_DECLARE(void) switch_core_media_bug_set_read_demux_frame(_In_ switch_medi
*/
SWITCH_DECLARE(switch_core_session_t *) switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug);
SWITCH_DECLARE(const char *) switch_core_media_bug_get_text(switch_media_bug_t *bug);
/*!
\brief Test for the existance of a flag on an media bug
\param bug the object to test
@@ -1163,6 +1165,8 @@ SWITCH_DECLARE(void *) switch_core_session_get_stream(_In_ switch_core_session_t
*/
SWITCH_DECLARE(int) switch_core_session_get_stream_count(_In_ switch_core_session_t *session);
SWITCH_DECLARE(const char *) switch_core_session_get_text_buffer(switch_core_session_t *session);
/*!
\brief Launch a thread designed to exist within the scope of a given session
\param session a session to allocate the thread from
@@ -2741,6 +2745,8 @@ SWITCH_DECLARE(int) switch_stream_system(const char *cmd, switch_stream_handle_t
SWITCH_DECLARE(switch_call_direction_t) switch_ice_direction(switch_core_session_t *session);
SWITCH_DECLARE(void) switch_core_session_debug_pool(switch_stream_handle_t *stream);
SWITCH_DECLARE(switch_status_t) switch_core_session_override_io_routines(switch_core_session_t *session, switch_io_routines_t *ior);
SWITCH_DECLARE(const char *)switch_version_major(void);
SWITCH_DECLARE(const char *)switch_version_minor(void);
SWITCH_DECLARE(const char *)switch_version_micro(void);
@@ -2752,6 +2758,9 @@ SWITCH_DECLARE(const char *)switch_version_full_human(void);
SWITCH_DECLARE(void) switch_core_autobind_cpu(void);
SWITCH_DECLARE(switch_status_t) switch_core_session_start_text_thread(switch_core_session_t *session);
SWITCH_END_EXTERN_C
#endif
/* For Emacs:
+27 -1
View File
@@ -41,6 +41,8 @@ typedef struct switch_io_event_hook_read_frame switch_io_event_hook_read_frame_t
typedef struct switch_io_event_hook_video_read_frame switch_io_event_hook_video_read_frame_t;
typedef struct switch_io_event_hook_write_frame switch_io_event_hook_write_frame_t;
typedef struct switch_io_event_hook_video_write_frame switch_io_event_hook_video_write_frame_t;
typedef struct switch_io_event_hook_text_read_frame switch_io_event_hook_text_read_frame_t;
typedef struct switch_io_event_hook_text_write_frame switch_io_event_hook_text_write_frame_t;
typedef struct switch_io_event_hook_kill_channel switch_io_event_hook_kill_channel_t;
typedef struct switch_io_event_hook_send_dtmf switch_io_event_hook_send_dtmf_t;
typedef struct switch_io_event_hook_recv_dtmf switch_io_event_hook_recv_dtmf_t;
@@ -54,6 +56,8 @@ typedef switch_status_t (*switch_read_frame_hook_t) (switch_core_session_t *, sw
typedef switch_status_t (*switch_video_read_frame_hook_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);
typedef switch_status_t (*switch_write_frame_hook_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
typedef switch_status_t (*switch_video_write_frame_hook_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
typedef switch_status_t (*switch_text_read_frame_hook_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);
typedef switch_status_t (*switch_text_write_frame_hook_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
typedef switch_status_t (*switch_kill_channel_hook_t) (switch_core_session_t *, int);
typedef switch_status_t (*switch_send_dtmf_hook_t) (switch_core_session_t *, const switch_dtmf_t *, switch_dtmf_direction_t direction);
typedef switch_status_t (*switch_recv_dtmf_hook_t) (switch_core_session_t *, const switch_dtmf_t *, switch_dtmf_direction_t direction);
@@ -108,6 +112,20 @@ struct switch_io_event_hook_video_write_frame {
struct switch_io_event_hook_video_write_frame *next;
};
/*! \brief Node in which to store custom read frame channel callback hooks */
struct switch_io_event_hook_text_read_frame {
/*! the read frame channel callback hook */
switch_read_frame_hook_t text_read_frame;
struct switch_io_event_hook_text_read_frame *next;
};
/*! \brief Node in which to store custom video_write_frame channel callback hooks */
struct switch_io_event_hook_text_write_frame {
/*! the video_write_frame channel callback hook */
switch_video_write_frame_hook_t text_write_frame;
struct switch_io_event_hook_text_write_frame *next;
};
/*! \brief Node in which to store custom kill channel callback hooks */
struct switch_io_event_hook_kill_channel {
/*! the kill channel callback hook */
@@ -158,8 +176,12 @@ struct switch_io_event_hooks {
switch_io_event_hook_video_read_frame_t *video_read_frame;
/*! a list of write frame hooks */
switch_io_event_hook_write_frame_t *write_frame;
/*! a list of video write frame hooks */
/*! a list of text write frame hooks */
switch_io_event_hook_video_write_frame_t *video_write_frame;
/*! a list of text write frame hooks */
switch_io_event_hook_text_write_frame_t *text_write_frame;
/*! a list of text read frame hooks */
switch_io_event_hook_text_read_frame_t *text_read_frame;
/*! a list of kill channel hooks */
switch_io_event_hook_kill_channel_t *kill_channel;
/*! a list of send dtmf hooks */
@@ -225,6 +247,8 @@ NEW_HOOK_DECL_ADD_P(read_frame);
NEW_HOOK_DECL_ADD_P(write_frame);
NEW_HOOK_DECL_ADD_P(video_read_frame);
NEW_HOOK_DECL_ADD_P(video_write_frame);
NEW_HOOK_DECL_ADD_P(text_read_frame);
NEW_HOOK_DECL_ADD_P(text_write_frame);
NEW_HOOK_DECL_ADD_P(kill_channel);
NEW_HOOK_DECL_ADD_P(send_dtmf);
NEW_HOOK_DECL_ADD_P(recv_dtmf);
@@ -238,6 +262,8 @@ NEW_HOOK_DECL_REM_P(read_frame);
NEW_HOOK_DECL_REM_P(write_frame);
NEW_HOOK_DECL_REM_P(video_read_frame);
NEW_HOOK_DECL_REM_P(video_write_frame);
NEW_HOOK_DECL_REM_P(text_read_frame);
NEW_HOOK_DECL_REM_P(text_write_frame);
NEW_HOOK_DECL_REM_P(kill_channel);
NEW_HOOK_DECL_REM_P(send_dtmf);
NEW_HOOK_DECL_REM_P(recv_dtmf);
+25 -4
View File
@@ -35,6 +35,7 @@
#include <switch.h>
#include <switch_msrp.h>
SWITCH_BEGIN_EXTERN_C
@@ -122,9 +123,11 @@ typedef struct switch_core_media_params_s {
switch_rtp_bug_flag_t manual_rtp_bugs;
switch_rtp_bug_flag_t manual_video_rtp_bugs;
switch_rtp_bug_flag_t manual_text_rtp_bugs;
char *rtcp_audio_interval_msec;
char *rtcp_video_interval_msec;
char *rtcp_text_interval_msec;
char *extrtpip;
@@ -335,10 +338,10 @@ SWITCH_DECLARE(switch_bool_t) switch_core_media_codec_get_cap(switch_core_sessio
SWITCH_DECLARE(switch_timer_t *) switch_core_media_get_timer(switch_core_session_t *session, switch_media_type_t mtype);
SWITCH_DECLARE(void) switch_core_media_start_video_function(switch_core_session_t *session, switch_video_function_t video_function, void *user_data);
SWITCH_DECLARE(void) switch_core_media_end_video_function(switch_core_session_t *session);
SWITCH_DECLARE(void) switch_core_media_start_engine_function(switch_core_session_t *session, switch_media_type_t type, switch_engine_function_t engine_function, void *user_data);
SWITCH_DECLARE(void) switch_core_media_end_engine_function(switch_core_session_t *session, switch_media_type_t type);
SWITCH_DECLARE(switch_status_t) switch_core_session_start_video_thread(switch_core_session_t *session);
SWITCH_DECLARE(int) switch_core_media_check_video_function(switch_core_session_t *session);
SWITCH_DECLARE(int) switch_core_media_check_engine_function(switch_core_session_t *session, switch_media_type_t type);
SWITCH_DECLARE(void) switch_core_session_video_reinit(switch_core_session_t *session);
SWITCH_DECLARE(switch_status_t) switch_core_media_read_lock_unlock(switch_core_session_t *session, switch_media_type_t type, switch_bool_t lock);
@@ -357,7 +360,25 @@ SWITCH_DECLARE(switch_bool_t) switch_core_media_check_dtls(switch_core_session_t
SWITCH_DECLARE(switch_status_t) switch_core_media_set_outgoing_bitrate(switch_core_session_t *session, switch_media_type_t type, uint32_t bitrate);
SWITCH_DECLARE(switch_status_t) switch_core_media_reset_jb(switch_core_session_t *session, switch_media_type_t type);
SWITCH_DECLARE(switch_status_t) switch_core_session_wait_for_video_input_params(switch_core_session_t *session, uint32_t timeout_ms);
SWITCH_DECLARE(switch_status_t) switch_core_session_set_text_read_callback(switch_core_session_t *session,
switch_core_text_thread_callback_func_t func, void *user_data);
SWITCH_DECLARE(switch_status_t) switch_core_session_text_read_callback(switch_core_session_t *session, switch_frame_t *frame);
SWITCH_DECLARE(switch_status_t) switch_core_session_read_text_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags,
int stream_id);
SWITCH_DECLARE(switch_status_t) switch_core_session_write_text_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags,
int stream_id);
SWITCH_DECLARE(switch_status_t) switch_rtp_text_factory_create(switch_rtp_text_factory_t **tfP, switch_memory_pool_t *pool);
SWITCH_DECLARE(switch_status_t) switch_rtp_text_factory_destroy(switch_rtp_text_factory_t **tfP);
SWITCH_DECLARE(switch_status_t) switch_core_session_print(switch_core_session_t *session, const char *data);
SWITCH_DECLARE(switch_status_t) switch_core_session_printf(switch_core_session_t *session, const char *fmt, ...);
SWITCH_DECLARE(switch_msrp_session_t *) switch_core_media_get_msrp_session(switch_core_session_t *session);
SWITCH_END_EXTERN_C
#endif
/* For Emacs:
+1
View File
@@ -1020,6 +1020,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_stop_video_write_overlay_session(swit
SWITCH_DECLARE(switch_status_t) switch_ivr_video_write_overlay_session(switch_core_session_t *session, const char *img_path,
switch_img_position_t pos, uint8_t alpha);
SWITCH_DECLARE(switch_status_t) switch_ivr_capture_text(switch_core_session_t *session, switch_bool_t on);
/** @} */
+2 -1
View File
@@ -39,7 +39,8 @@ typedef enum {
typedef enum {
SJB_VIDEO = 0,
SJB_AUDIO
SJB_AUDIO,
SJB_TEXT
} switch_jb_type_t;
+8
View File
@@ -119,6 +119,8 @@ typedef switch_status_t (*switch_io_state_change_t) (switch_core_session_t *);
typedef switch_status_t (*switch_io_state_run_t) (switch_core_session_t *);
typedef switch_status_t (*switch_io_read_video_frame_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);
typedef switch_status_t (*switch_io_write_video_frame_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
typedef switch_status_t (*switch_io_read_text_frame_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);
typedef switch_status_t (*switch_io_write_text_frame_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
typedef switch_jb_t *(*switch_io_get_jb_t) (switch_core_session_t *, switch_media_type_t);
typedef enum {
@@ -132,6 +134,8 @@ typedef enum {
SWITCH_IO_STATE_CHANGE,
SWITCH_IO_READ_VIDEO_FRAME,
SWITCH_IO_WRITE_VIDEO_FRAME,
SWITCH_IO_READ_TEXT_FRAME,
SWITCH_IO_WRITE_TEXT_FRAME,
SWITCH_IO_GET_JB,
} switch_io_routine_name_t;
@@ -157,6 +161,10 @@ struct switch_io_routines {
switch_io_read_video_frame_t read_video_frame;
/*! write a video frame to a session */
switch_io_write_video_frame_t write_video_frame;
/*! read a video frame from a session */
switch_io_read_text_frame_t read_text_frame;
/*! write a video frame to a session */
switch_io_write_text_frame_t write_text_frame;
/*! change a sessions channel run state */
switch_io_state_run_t state_run;
/*! get sessions jitterbuffer */
+146
View File
@@ -0,0 +1,146 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2011-2016, Seven Du <dujinfang@gmail.com>
*
* 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
* Seven Du <dujinfang@gmail.com>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
*
* msrp.h -- MSRP lib
*
*/
#ifndef _MSRP_H
#define _MSRP_H
#include <switch.h>
#include <openssl/ssl.h>
#define MSRP_LISTEN_PORT 2855
#define MSRP_SSL_LISTEN_PORT 2856
enum {
MSRP_ST_WAIT_HEADER,
MSRP_ST_PARSE_HEADER,
MSRP_ST_WAIT_BODY,
MSRP_ST_DONE,
MSRP_ST_ERROR,
MSRP_METHOD_REPLY,
MSRP_METHOD_SEND,
MSRP_METHOD_AUTH,
MSRP_METHOD_REPORT,
};
enum {
MSRP_H_FROM_PATH,
MSRP_H_TO_PATH,
MSRP_H_MESSAGE_ID,
MSRP_H_CONTENT_TYPE,
MSRP_H_SUCCESS_REPORT,
MSRP_H_FAILURE_REPORT,
MSRP_H_STATUS,
MSRP_H_KEEPALIVE,
MSRP_H_UNKNOWN
};
typedef struct msrp_msg_s {
int state;
int method;
char *headers[12];
int last_header;
char *transaction_id;
char *delimiter;
int code_number;
char *code_description;
switch_size_t byte_start;
switch_size_t byte_end;
switch_size_t bytes;
switch_size_t payload_bytes;
int range_star; /* range-end is '*' */
char *last_p;
char *payload;
struct msrp_msg_s *next;
} msrp_msg_t;
typedef struct msrp_msg_s switch_msrp_msg_t;
typedef struct msrp_socket_s {
switch_port_t port;
switch_socket_t *sock;
switch_thread_t *thread;
int secure;
} msrp_socket_t;
typedef struct msrp_client_socket_s {
switch_socket_t *sock;
int secure;
} msrp_client_socket_t;
typedef struct {
switch_memory_pool_t *pool;
int secure;
char *remote_path;
char *remote_accept_types;
char *remote_accept_wrapped_types;
char *remote_setup;
char *remote_file_selector;
char *local_path;
char *local_accept_types;
char *local_accept_wrapped_types;
char *local_setup;
char *local_file_selector;
int local_port;
char *call_id;
msrp_msg_t *msrp_msg;
msrp_msg_t *last_msg;
switch_mutex_t *mutex;
switch_size_t msrp_msg_buffer_size;
switch_size_t msrp_msg_count;
msrp_socket_t *msock;
msrp_client_socket_t *csock;
switch_frame_t frame;
uint8_t frame_data[SWITCH_RTP_MAX_BUF_LEN];
} switch_msrp_session_t;
SWITCH_DECLARE(switch_status_t) switch_msrp_init();
SWITCH_DECLARE(switch_status_t) switch_msrp_destroy();
SWITCH_DECLARE(switch_msrp_session_t *)switch_msrp_session_new(switch_memory_pool_t *pool, switch_bool_t secure);
SWITCH_DECLARE(switch_status_t) switch_msrp_session_destroy(switch_msrp_session_t **ms);
// switch_status_t switch_msrp_session_push_msg(switch_msrp_session_t *ms, msrp_msg_t *msg);
SWITCH_DECLARE(switch_msrp_msg_t *)switch_msrp_session_pop_msg(switch_msrp_session_t *ms);
SWITCH_DECLARE(switch_status_t) switch_msrp_send(switch_msrp_session_t *ms, msrp_msg_t *msg);
SWITCH_DECLARE(void) switch_msrp_load_apis_and_applications(switch_loadable_module_interface_t **moudle_interface);
#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 noet:
*/
+32 -6
View File
@@ -213,6 +213,8 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_REMOTE_VIDEO_PORT_VARIABLE "remote_video_port"
#define SWITCH_LOCAL_VIDEO_IP_VARIABLE "local_video_ip"
#define SWITCH_LOCAL_VIDEO_PORT_VARIABLE "local_video_port"
#define SWITCH_LOCAL_TEXT_IP_VARIABLE "local_text_ip"
#define SWITCH_LOCAL_TEXT_PORT_VARIABLE "local_text_port"
#define SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE "hangup_after_bridge"
#define SWITCH_PARK_AFTER_BRIDGE_VARIABLE "park_after_bridge"
#define SWITCH_PARK_AFTER_EARLY_BRIDGE_VARIABLE "park_after_early_bridge"
@@ -234,6 +236,7 @@ SWITCH_BEGIN_EXTERN_C
#define SWITCH_RTCP_AUDIO_INTERVAL_MSEC "5000"
#define SWITCH_RTCP_VIDEO_INTERVAL_MSEC "2000"
#define TEXT_UNICODE_LINEFEED {0xe2, 0x80, 0xa8}
#define MAX_FMTP_LEN 256
/* Jitter */
@@ -496,7 +499,8 @@ typedef enum {
SWITCH_ABC_TYPE_READ_VIDEO_PING,
SWITCH_ABC_TYPE_WRITE_VIDEO_PING,
SWITCH_ABC_TYPE_STREAM_VIDEO_PING,
SWITCH_ABC_TYPE_VIDEO_PATCH
SWITCH_ABC_TYPE_VIDEO_PATCH,
SWITCH_ABC_TYPE_READ_TEXT
} switch_abc_type_t;
typedef struct {
@@ -771,6 +775,7 @@ typedef enum {
SWITCH_RTP_FLAG_TMMBR,
SWITCH_RTP_FLAG_GEN_TS_DELTA,
SWITCH_RTP_FLAG_DETECT_SSRC,
SWITCH_RTP_FLAG_TEXT,
SWITCH_RTP_FLAG_INVALID
} switch_rtp_flag_t;
@@ -1371,6 +1376,9 @@ typedef enum {
CC_JITTERBUFFER,
CC_FS_RTP,
CC_QUEUEABLE_DTMF_DELAY,
CC_IO_OVERRIDE,
CC_RTP_RTT,
CC_MSRP,
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
CC_FLAG_MAX
} switch_channel_cap_t;
@@ -1516,6 +1524,14 @@ typedef enum {
CF_3P_NOMEDIA_REQUESTED_BLEG,
CF_IMAGE_SDP,
CF_VIDEO_SDP_RECVD,
CF_TEXT_SDP_RECVD,
CF_TEXT,
CF_TEXT_POSSIBLE,
CF_TEXT_PASSIVE,
CF_TEXT_ECHO,
CF_TEXT_ACTIVE,
CF_TEXT_IDLE,
CF_MSRP,
/* 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
@@ -1572,7 +1588,8 @@ typedef enum {
SFF_PICTURE_RESET = (1 << 14),
SFF_SAME_IMAGE = (1 << 15),
SFF_USE_VIDEO_TIMESTAMP = (1 << 16),
SFF_ENCODED = (1 << 17)
SFF_ENCODED = (1 << 17),
SFF_TEXT_LINE_BREAK = (1 << 18)
} switch_frame_flag_enum_t;
typedef uint32_t switch_frame_flag_t;
@@ -1717,9 +1734,10 @@ typedef enum {
typedef enum {
SWITCH_MEDIA_TYPE_AUDIO,
SWITCH_MEDIA_TYPE_VIDEO
SWITCH_MEDIA_TYPE_VIDEO,
SWITCH_MEDIA_TYPE_TEXT
} switch_media_type_t;
#define SWITCH_MEDIA_TYPE_TOTAL 2
#define SWITCH_MEDIA_TYPE_TOTAL 3
/*!
@@ -1778,7 +1796,8 @@ typedef enum {
SMBF_VIDEO_PATCH = (1 << 21),
SMBF_SPY_VIDEO_STREAM = (1 << 22),
SMBF_SPY_VIDEO_STREAM_BLEG = (1 << 23),
SMBF_READ_VIDEO_PATCH = (1 << 24)
SMBF_READ_VIDEO_PATCH = (1 << 24),
SMBF_READ_TEXT_STREAM = (1 << 25)
} switch_media_bug_flag_enum_t;
typedef uint32_t switch_media_bug_flag_t;
@@ -2024,6 +2043,7 @@ typedef enum {
SWITCH_EVENT_CALL_SETUP_RESULT,
SWITCH_EVENT_CALL_DETAIL,
SWITCH_EVENT_DEVICE_STATE,
SWITCH_EVENT_REAL_TIME_TEXT,
SWITCH_EVENT_ALL
} switch_event_types_t;
@@ -2239,13 +2259,15 @@ 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 switch_status_t (*switch_core_video_thread_callback_func_t) (switch_core_session_t *session, switch_frame_t *frame, void *user_data);
typedef switch_status_t (*switch_core_text_thread_callback_func_t) (switch_core_session_t *session, switch_frame_t *frame, 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);
typedef switch_bool_t (*switch_tone_detect_callback_t) (switch_core_session_t *, const char *, const char *);
typedef struct switch_xml_binding switch_xml_binding_t;
typedef void (*switch_video_function_t) (switch_core_session_t *session, void *user_data);
typedef void (*switch_engine_function_t) (switch_core_session_t *session, void *user_data);
typedef switch_status_t (*switch_core_codec_encode_func_t) (switch_codec_t *codec,
switch_codec_t *other_codec,
@@ -2619,6 +2641,10 @@ typedef enum {
SCFC_PAUSE_READ
} switch_file_command_t;
struct switch_rtp_text_factory_s;
typedef struct switch_rtp_text_factory_s switch_rtp_text_factory_t;
SWITCH_END_EXTERN_C
#endif
/* For Emacs:
+27
View File
@@ -373,6 +373,33 @@ SWITCH_DECLARE(switch_status_t) switch_b64_encode(unsigned char *in, switch_size
SWITCH_DECLARE(switch_size_t) switch_b64_decode(char *in, char *out, switch_size_t olen);
SWITCH_DECLARE(char *) switch_amp_encode(char *s, char *buf, switch_size_t len);
static inline char *switch_print_bits(const unsigned char *byte, char *buf, switch_size_t buflen)
{
int i, j = 0, k = 0, l = 0;
while(k < buflen) {
l = 0;
for (i = 7; i >= 0; i--) {
buf[j++] = (*byte & (1 << i)) ? '1' : '0';
if (++l % 4 == 0) {
buf[j++] = ' ';
}
}
k++;
byte++;
}
if (buf[j-1] == ' ') j--;
buf[j++] = '\0';
return buf;
}
static inline switch_bool_t switch_is_digit_string(const char *s)
{
+1 -1
View File
@@ -1140,7 +1140,7 @@ SWITCH_STANDARD_APP(record_av_function)
switch_core_timer_destroy(&timer);
}
switch_core_media_end_video_function(session);
switch_core_media_end_engine_function(session, SWITCH_MEDIA_TYPE_VIDEO);
switch_core_session_set_read_codec(session, NULL);
switch_core_codec_destroy(&codec);
@@ -3066,6 +3066,61 @@ SWITCH_STANDARD_API(uuid_chat)
return SWITCH_STATUS_SUCCESS;
}
#define UUID_CAPTURE_TEXT_SYNTAX "<uuid> <on|off>"
SWITCH_STANDARD_API(uuid_capture_text)
{
switch_core_session_t *tsession = NULL;
char *uuid = NULL, *onoff = NULL;
if (!zstr(cmd) && (uuid = strdup(cmd))) {
if ((onoff = strchr(uuid, ' '))) {
*onoff++ = '\0';
}
}
if (zstr(uuid) || zstr(onoff)) {
stream->write_function(stream, "-USAGE: %s\n", UUID_CAPTURE_TEXT_SYNTAX);
} else {
if ((tsession = switch_core_session_locate(uuid))) {
switch_ivr_capture_text(tsession, switch_true(onoff));
} else {
stream->write_function(stream, "-ERR No such channel %s!\n", uuid);
}
}
switch_safe_free(uuid);
return SWITCH_STATUS_SUCCESS;
}
#define UUID_SEND_TEXT_SYNTAX "<uuid> <text>"
SWITCH_STANDARD_API(uuid_send_text)
{
switch_core_session_t *tsession = NULL;
char *uuid = NULL, *text = NULL;
if (!zstr(cmd) && (uuid = strdup(cmd))) {
if ((text = strchr(uuid, ' '))) {
*text++ = '\0';
}
}
if (zstr(uuid) || zstr(text)) {
stream->write_function(stream, "-USAGE: %s\n", UUID_SEND_TEXT_SYNTAX);
} else {
if ((tsession = switch_core_session_locate(uuid))) {
switch_core_session_print(tsession, text);
switch_core_session_print(tsession, "\r\n");
switch_core_session_rwunlock(tsession);
} else {
stream->write_function(stream, "-ERR No such channel %s!\n", uuid);
}
}
switch_safe_free(uuid);
return SWITCH_STATUS_SUCCESS;
}
#define UUID_DROP_DTMF_SYNTAX "<uuid> [on | off ] [ mask_digits <digits> | mask_file <file>]"
SWITCH_STANDARD_API(uuid_drop_dtmf)
{
@@ -7197,6 +7252,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
SWITCH_ADD_API(commands_api_interface, "uuid_broadcast", "Execute dialplan application", uuid_broadcast_function, BROADCAST_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_buglist", "List media bugs on a session", uuid_buglist_function, BUGLIST_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_chat", "Send a chat message", uuid_chat, UUID_CHAT_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_send_text", "Send text in real-time", uuid_send_text, UUID_SEND_TEXT_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_capture_text", "start/stop capture_text", uuid_capture_text, UUID_CAPTURE_TEXT_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_codec_debug", "Send codec a debug message", uuid_codec_debug_function, CODEC_DEBUG_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_codec_param", "Send codec a param", uuid_codec_param_function, CODEC_PARAM_SYNTAX);
SWITCH_ADD_API(commands_api_interface, "uuid_debug_media", "Debug media", uuid_debug_media_function, DEBUG_MEDIA_SYNTAX);
@@ -7376,6 +7433,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
switch_console_set_complete("add uuid_broadcast ::console::list_uuid");
switch_console_set_complete("add uuid_buglist ::console::list_uuid");
switch_console_set_complete("add uuid_chat ::console::list_uuid");
switch_console_set_complete("add uuid_send_text ::console::list_uuid");
switch_console_set_complete("add uuid_capture_text ::console::list_uuid");
switch_console_set_complete("add uuid_codec_debug ::console::list_uuid audio");
switch_console_set_complete("add uuid_codec_debug ::console::list_uuid video");
switch_console_set_complete("add uuid_codec_param ::console::list_uuid audio read");
@@ -7439,6 +7498,8 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load)
switch_console_set_complete("add file_exists");
switch_console_set_complete("add getcputime");
switch_msrp_load_apis_and_applications(module_interface);
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_NOUNLOAD;
}
@@ -1148,6 +1148,13 @@ switch_status_t conference_member_del(conference_obj_t *conference, conference_m
lock_member(member);
conference_utils_member_clear_flag(member, MFLAG_INTREE);
switch_safe_free(member->text_framedata);
member->text_framesize = 0;
if (member->text_buffer) {
switch_buffer_destroy(&member->text_buffer);
}
if (member->rec) {
conference->recording_members--;
}
@@ -249,6 +249,42 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob
floor_holder = conference->floor_holder;
for (imember = conference->members; imember; imember = imember->next) {
if (!zstr(imember->text_framedata)) {
switch_frame_t frame = { 0 };
char *framedata;
uint32_t framedatalen;
const char *caller_id_name = switch_channel_get_variable(imember->channel, "caller_id_name");
unsigned char CR[3] = TEXT_UNICODE_LINEFEED;
switch_mutex_lock(imember->text_mutex);
framedatalen = strlen(imember->text_framedata) + strlen(caller_id_name) + 6;
switch_zmalloc(framedata, framedatalen);
switch_snprintf(framedata, framedatalen, "%s::\n%s", caller_id_name, imember->text_framedata);
memcpy(framedata + strlen(framedata), CR, sizeof(CR));
frame.data = framedata;
frame.datalen = framedatalen;
for (omember = conference->members; omember; omember = omember->next) {
if (omember != imember) {
switch_core_session_write_text_frame(omember->session, &frame, 0, 0);
}
}
free(framedata);
imember->text_framedata[0] = '\0';
switch_mutex_unlock(imember->text_mutex);
}
}
/* Read one frame of audio from each member channel and save it for redistribution */
for (imember = conference->members; imember; imember = imember->next) {
uint32_t buf_read = 0;
@@ -1610,6 +1646,65 @@ SWITCH_STANDARD_APP(conference_auto_function)
}
switch_status_t conference_text_thread_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data)
{
conference_member_t *member = (conference_member_t *)user_data;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_size_t inuse = 0;
if (!member) return SWITCH_STATUS_FALSE;
switch_mutex_lock(member->text_mutex);
if (!member->text_buffer) {
switch_buffer_create_dynamic(&member->text_buffer, 512, 1024, 0);
switch_zmalloc(member->text_framedata, 1024);
member->text_framesize = 1024;
}
if (frame->data && frame->datalen && !(frame->flags & SFF_CNG)) {
switch_buffer_write(member->text_buffer, frame->data, frame->datalen);
}
inuse = switch_buffer_inuse(member->text_buffer);
if (zstr(member->text_framedata) && inuse && (switch_channel_test_flag(channel, CF_TEXT_IDLE) || switch_test_flag(frame, SFF_TEXT_LINE_BREAK))) {
int bytes = 0, ok = 0;
char *p;
if (inuse + 1 > member->text_framesize) {
void *tmp = malloc(inuse + 1024);
memcpy(tmp, member->text_framedata, member->text_framesize);
switch_assert(tmp);
member->text_framesize = inuse + 1024;
free(member->text_framedata);
member->text_framedata = tmp;
}
bytes = switch_buffer_read(member->text_buffer, member->text_framedata, inuse);
*(member->text_framedata + bytes) = '\0';
for(p = member->text_framedata; p && *p; p++) {
if (*p > 32 && *p < 127) {
ok++;
}
}
if (!ok) {
member->text_framedata[0] = '\0';
}
}
switch_mutex_unlock(member->text_mutex);
return SWITCH_STATUS_SUCCESS;
}
/* Application interface function that is called from the dialplan to join the channel to a conference */
SWITCH_STANDARD_APP(conference_function)
{
@@ -2123,6 +2218,7 @@ SWITCH_STANDARD_APP(conference_function)
switch_mutex_init(&member.fnode_mutex, SWITCH_MUTEX_NESTED, member.pool);
switch_mutex_init(&member.audio_in_mutex, SWITCH_MUTEX_NESTED, member.pool);
switch_mutex_init(&member.audio_out_mutex, SWITCH_MUTEX_NESTED, member.pool);
switch_mutex_init(&member.text_mutex, SWITCH_MUTEX_NESTED, member.pool);
switch_thread_rwlock_create(&member.rwlock, member.pool);
if (conference_member_setup_media(&member, conference)) {
@@ -2197,6 +2293,7 @@ SWITCH_STANDARD_APP(conference_function)
/* Chime in the core video thread */
switch_core_session_set_video_read_callback(session, conference_video_thread_callback, (void *)&member);
switch_core_session_set_text_read_callback(session, conference_text_thread_callback, (void *)&member);
if (switch_channel_test_flag(channel, CF_VIDEO_ONLY)) {
while(conference_utils_member_test_flag((&member), MFLAG_RUNNING) && switch_channel_ready(channel)) {
@@ -2211,6 +2308,7 @@ SWITCH_STANDARD_APP(conference_function)
}
switch_core_session_set_video_read_callback(session, NULL, NULL);
switch_core_session_set_text_read_callback(session, NULL, NULL);
switch_channel_set_private(channel, "_conference_autocall_list_", NULL);
@@ -790,6 +790,13 @@ struct conference_member {
int reset_media;
int flip;
int flip_count;
switch_mutex_t *text_mutex;
switch_buffer_t *text_buffer;
char *text_framedata;
uint32_t text_framesize;
};
typedef enum {
@@ -971,6 +978,7 @@ void conference_video_fnode_check(conference_file_node_t *fnode, int canvas_id);
switch_status_t conference_video_set_canvas_bgimg(mcu_canvas_t *canvas, const char *img_path);
switch_status_t conference_al_parse_position(al_handle_t *al, const char *data);
switch_status_t conference_video_thread_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data);
switch_status_t conference_text_thread_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data);
void *SWITCH_THREAD_FUNC conference_video_muxing_write_thread_run(switch_thread_t *thread, void *obj);
void conference_member_check_agc_levels(conference_member_t *member);
void conference_member_clear_avg(conference_member_t *member);
@@ -1012,6 +1012,10 @@ SWITCH_STANDARD_APP(set_mute_function)
}
SWITCH_STANDARD_APP(capture_text_function)
{
switch_ivr_capture_text(session, switch_true((char *)data));
}
SWITCH_STANDARD_APP(ring_ready_function)
{
@@ -6127,6 +6131,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_CHAT(chat_interface, "event", event_chat_send);
SWITCH_ADD_CHAT(chat_interface, "api", api_chat_send);
SWITCH_ADD_API(api_interface, "strepoch", "Convert a date string into epoch time", strepoch_api_function, "<string>");
SWITCH_ADD_API(api_interface, "page", "Send a file as a page", page_api_function, "(var1=val1,var2=val2)<var1=val1,var2=val2><chan1>[:_:<chanN>]");
SWITCH_ADD_API(api_interface, "strmicroepoch", "Convert a date string into micoepoch time", strmicroepoch_api_function, "<string>");
@@ -6216,6 +6221,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
SWITCH_ADD_APP(app_interface, "multiunset", "Unset many channel variables", SET_LONG_DESC, multiunset_function, "[^^<delim>]<varname> <var2> <var3>",
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
SWITCH_ADD_APP(app_interface, "capture_text", "capture text", "capture text", capture_text_function, "", SAF_NONE);
SWITCH_ADD_APP(app_interface, "ring_ready", "Indicate Ring_Ready", "Indicate Ring_Ready on a channel.", ring_ready_function, "", SAF_SUPPORT_NOMEDIA);
SWITCH_ADD_APP(app_interface, "remove_bugs", "Remove media bugs", "Remove all media bugs from a channel.", remove_bugs_function, "[<function>]", SAF_NONE);
SWITCH_ADD_APP(app_interface, "break", "Break", "Set the break flag.", break_function, "", SAF_SUPPORT_NOMEDIA);
+4 -4
View File
@@ -183,7 +183,7 @@ SWITCH_STANDARD_APP(record_fsv_function)
switch_mutex_init(&mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
eh.mutex = mutex;
eh.fd = fd;
switch_core_media_start_video_function(session, record_video_thread, &eh);
switch_core_media_start_engine_function(session, SWITCH_MEDIA_TYPE_VIDEO, record_video_thread, &eh);
}
@@ -257,7 +257,7 @@ SWITCH_STANDARD_APP(record_fsv_function)
close(fd);
}
switch_core_media_end_video_function(session);
switch_core_media_end_engine_function(session, SWITCH_MEDIA_TYPE_VIDEO);
switch_core_session_set_read_codec(session, NULL);
switch_core_codec_destroy(&codec);
@@ -751,7 +751,7 @@ SWITCH_STANDARD_APP(decode_video_function)
switch_channel_set_flag(channel, CF_VIDEO_DECODED_READ);
switch_core_media_start_video_function(session, decode_video_thread, &max_pictures);
switch_core_media_start_engine_function(session, SWITCH_MEDIA_TYPE_VIDEO, decode_video_thread, &max_pictures);
switch_ivr_play_file(session, NULL, moh, NULL);
@@ -762,7 +762,7 @@ SWITCH_STANDARD_APP(decode_video_function)
switch_channel_set_variable(channel, SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE, "OK");
switch_core_media_end_video_function(session);
switch_core_media_end_engine_function(session, SWITCH_MEDIA_TYPE_VIDEO);
switch_core_session_video_reset(session);
}
+3
View File
@@ -287,6 +287,8 @@ switch_io_routines_t rtc_io_routines = {
/*.state_change */ NULL,
/*.read_video_frame */ rtc_read_video_frame,
/*.write_video_frame */ rtc_write_video_frame,
/*.read_text_frame */ NULL,
/*.write_text_frame */ NULL,
/*.state_run*/ NULL,
/*.get_jb*/ rtc_get_jb
};
@@ -330,6 +332,7 @@ void rtc_attach_private(switch_core_session_t *session, private_object_t *tech_p
switch_core_media_check_dtmf_type(session);
switch_channel_set_cap(tech_pvt->channel, CC_JITTERBUFFER);
switch_channel_set_cap(tech_pvt->channel, CC_FS_RTP);
switch_channel_set_cap(tech_pvt->channel, CC_IO_OVERRIDE);
switch_media_handle_create(&tech_pvt->media_handle, session, &tech_pvt->mparams);
switch_core_session_set_private(session, tech_pvt);
+31
View File
@@ -62,6 +62,8 @@ static switch_status_t sofia_read_frame(switch_core_session_t *session, switch_f
static switch_status_t sofia_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t sofia_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t sofia_write_video_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t sofia_read_text_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t sofia_write_text_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t sofia_kill_channel(switch_core_session_t *session, int sig);
/* BODY OF THE MODULE */
@@ -918,6 +920,33 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
return SWITCH_STATUS_SUCCESS;
}
static switch_status_t sofia_read_text_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
{
return switch_core_media_read_frame(session, frame, flags, stream_id, SWITCH_MEDIA_TYPE_TEXT);
}
static switch_status_t sofia_write_text_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
{
if (switch_channel_test_flag(switch_core_session_get_channel(session), CF_MSRP)) {
switch_msrp_session_t *msrp_session = switch_core_media_get_msrp_session(session);
if (frame && msrp_session) {
switch_msrp_msg_t msrp_msg = { 0 };
msrp_msg.headers[MSRP_H_CONTENT_TYPE] = "message/cpim";
// msrp_msg.headers[MSRP_H_CONTENT_TYPE] = "text/plain";
msrp_msg.payload = frame->data;
msrp_msg.payload_bytes = frame->datalen;
return switch_msrp_send(msrp_session, &msrp_msg);
}
return SWITCH_STATUS_FALSE;
}
return switch_core_media_write_frame(session, frame, flags, stream_id, SWITCH_MEDIA_TYPE_TEXT);
}
static switch_status_t sofia_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
{
private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
@@ -4279,6 +4308,8 @@ switch_io_routines_t sofia_io_routines = {
/*.state_change */ NULL,
/*.read_video_frame */ sofia_read_video_frame,
/*.write_video_frame */ sofia_write_video_frame,
/*.read_text_frame */ sofia_read_text_frame,
/*.write_text_frame */ sofia_write_text_frame,
/*.state_run*/ NULL,
/*.get_jb*/ sofia_get_jb
};
+2
View File
@@ -122,6 +122,8 @@ switch_io_routines_t crtp_io_routines = {
/*state_change*/ NULL,
/*read_video_frame*/ NULL,
/*write_video_frame*/ NULL,
/*read_text_frame*/ NULL,
/*write_text_frame*/ NULL,
/*state_run*/ NULL
+2
View File
@@ -159,6 +159,8 @@ void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *
switch_channel_set_cap(tech_pvt->channel, CC_PROXY_MEDIA);
switch_channel_set_cap(tech_pvt->channel, CC_JITTERBUFFER);
switch_channel_set_cap(tech_pvt->channel, CC_FS_RTP);
switch_channel_set_cap(tech_pvt->channel, CC_RTP_RTT);
switch_channel_set_cap(tech_pvt->channel, CC_MSRP);
switch_channel_set_cap(tech_pvt->channel, CC_QUEUEABLE_DTMF_DELAY);
+1 -1
View File
@@ -53,7 +53,7 @@
#include <poll.h>
#define closesocket(x) close(x)
#endif
#include <switch_utils.h>
#include <switch.h>
#include "mcast.h"
+165 -3
View File
@@ -130,6 +130,10 @@ static switch_bool_t check_name(const char *name)
}
static switch_status_t verto_read_text_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t verto_write_text_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static void set_text_funcs(switch_core_session_t *session);
static verto_profile_t *find_profile(const char *name);
static jsock_t *get_jsock(const char *uuid);
@@ -2116,6 +2120,11 @@ switch_endpoint_interface_t *verto_endpoint_interface = NULL;
static switch_status_t verto_on_destroy(switch_core_session_t *session)
{
verto_pvt_t *tech_pvt = switch_core_session_get_private_class(session, SWITCH_PVT_SECONDARY);
switch_buffer_destroy(&tech_pvt->text_read_buffer);
switch_buffer_destroy(&tech_pvt->text_write_buffer);
UNPROTECT_INTERFACE(verto_endpoint_interface);
return SWITCH_STATUS_SUCCESS;
}
@@ -2576,6 +2585,7 @@ static int verto_recover_callback(switch_core_session_t *session)
}
tech_pvt = switch_core_session_alloc(session, sizeof(*tech_pvt));
tech_pvt->pool = switch_core_session_get_pool(session);
tech_pvt->session = session;
tech_pvt->channel = channel;
tech_pvt->jsock_uuid = (char *) jsock_uuid_str;
@@ -3261,7 +3271,7 @@ static void parse_user_vars(cJSON *obj, switch_core_session_t *session)
static switch_bool_t verto__info_func(const char *method, cJSON *params, jsock_t *jsock, cJSON **response)
{
cJSON *msg = NULL, *dialog = NULL;
cJSON *msg = NULL, *dialog = NULL, *txt = NULL;
const char *call_id = NULL, *dtmf = NULL;
switch_bool_t r = SWITCH_TRUE;
char *proto = VERTO_CHAT_PROTO;
@@ -3298,6 +3308,43 @@ static switch_bool_t verto__info_func(const char *method, cJSON *params, jsock_t
}
}
if ((txt = cJSON_GetObjectItem(params, "txt"))) {
switch_core_session_t *session;
if ((session = switch_core_session_locate(call_id))) {
verto_pvt_t *tech_pvt = switch_core_session_get_private_class(session, SWITCH_PVT_SECONDARY);
char charbuf[2] = "";
char *chardata = NULL;
cJSON *data;
if ((data = cJSON_GetObjectItem(txt, "code"))) {
charbuf[0] = data->valueint;
chardata = charbuf;
} else if ((data = cJSON_GetObjectItem(txt, "chars"))) {
if (data->valuestring) {
chardata = data->valuestring;
} else if (data->valueint) {
charbuf[0] = data->valueint;
chardata = charbuf;
}
}
if (chardata) {
switch_mutex_lock(tech_pvt->text_read_mutex);
switch_buffer_write(tech_pvt->text_read_buffer, chardata, strlen(chardata));
switch_mutex_unlock(tech_pvt->text_read_mutex);
if ((switch_mutex_trylock(tech_pvt->text_cond_mutex) == SWITCH_STATUS_SUCCESS)) {
switch_thread_cond_signal(tech_pvt->text_cond);
switch_mutex_unlock(tech_pvt->text_cond_mutex);
}
}
switch_core_session_rwunlock(session);
}
}
if ((msg = cJSON_GetObjectItem(params, "msg"))) {
switch_event_t *event;
char *to = (char *) cJSON_GetObjectCstr(msg, "to");
@@ -3380,6 +3427,8 @@ static switch_bool_t verto__info_func(const char *method, cJSON *params, jsock_t
return r;
}
static switch_bool_t verto__invite_func(const char *method, cJSON *params, jsock_t *jsock, cJSON **response)
{
cJSON *obj = cJSON_CreateObject(), *screenShare = NULL, *dedEnc = NULL, *mirrorInput, *bandwidth = NULL, *canvas = NULL;
@@ -3431,12 +3480,13 @@ static switch_bool_t verto__invite_func(const char *method, cJSON *params, jsock
tech_pvt = switch_core_session_alloc(session, sizeof(*tech_pvt));
tech_pvt->session = session;
tech_pvt->pool = switch_core_session_get_pool(session);
tech_pvt->channel = channel;
tech_pvt->jsock_uuid = switch_core_session_strdup(session, jsock->uuid_str);
tech_pvt->r_sdp = switch_core_session_strdup(session, sdp);
switch_core_media_set_sdp_codec_string(session, sdp, SDP_TYPE_REQUEST);
switch_core_session_set_private_class(session, tech_pvt, SWITCH_PVT_SECONDARY);
set_text_funcs(session);
tech_pvt->call_id = switch_core_session_strdup(session, call_id);
if ((tech_pvt->smh = switch_core_session_get_media_handle(session))) {
@@ -5042,6 +5092,115 @@ switch_io_routines_t verto_io_routines = {
/*.outgoing_channel */ verto_outgoing_channel
};
switch_io_routines_t verto_io_override = {
/*.outgoing_channel */ NULL,
/*.read_frame */ NULL,
/*.write_frame */ NULL,
/*.kill_channel */ NULL,
/*.send_dtmf */ NULL,
/*.receive_message */ NULL,
/*.receive_event */ NULL,
/*.state_change */ NULL,
/*.read_video_frame */ NULL,
/*.write_video_frame */ NULL,
/*.read_text_frame */ verto_read_text_frame,
/*.write_text_frame */ verto_write_text_frame,
/*.state_run*/ NULL,
/*.get_jb*/ NULL
};
static switch_status_t verto_read_text_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
{
verto_pvt_t *tech_pvt = switch_core_session_get_private_class(session, SWITCH_PVT_SECONDARY);
switch_status_t status;
switch_mutex_lock(tech_pvt->text_cond_mutex);
status = switch_thread_cond_timedwait(tech_pvt->text_cond, tech_pvt->text_cond_mutex, 100000);
switch_mutex_unlock(tech_pvt->text_cond_mutex);
*frame = &tech_pvt->text_read_frame;
(*frame)->flags = 0;
switch_mutex_lock(tech_pvt->text_read_mutex);
if (switch_buffer_inuse(tech_pvt->text_read_buffer)) {
status = SWITCH_STATUS_SUCCESS;
tech_pvt->text_read_frame.datalen = switch_buffer_read(tech_pvt->text_read_buffer, tech_pvt->text_read_frame.data, 100);
} else {
(*frame)->flags |= SFF_CNG;
tech_pvt->text_read_frame.datalen = 2;
status = SWITCH_STATUS_BREAK;
}
switch_mutex_unlock(tech_pvt->text_read_mutex);
return status;
}
static switch_status_t verto_write_text_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
{
verto_pvt_t *tech_pvt = switch_core_session_get_private_class(session, SWITCH_PVT_SECONDARY);
switch_mutex_lock(tech_pvt->text_write_mutex);
if (frame) {
switch_buffer_write(tech_pvt->text_write_buffer, frame->data, frame->datalen);
}
if (switch_buffer_inuse(tech_pvt->text_write_buffer)) {
uint32_t datalen;
switch_byte_t data[SWITCH_RTP_MAX_BUF_LEN] = "";
if ((datalen = switch_buffer_read(tech_pvt->text_write_buffer, data, 100))) {
cJSON *obj = NULL, *txt = NULL, *params = NULL;
jsock_t *jsock;
obj = jrpc_new_req("verto.info", tech_pvt->call_id, &params);
txt = json_add_child_obj(params, "txt", NULL);
cJSON_AddItemToObject(txt, "chars", cJSON_CreateString((char *)data));
if ((jsock = get_jsock(tech_pvt->jsock_uuid))) {
jsock_queue_event(jsock, &obj, SWITCH_TRUE);
switch_thread_rwlock_unlock(jsock->rwlock);
} else {
cJSON_Delete(obj);
}
}
}
switch_mutex_unlock(tech_pvt->text_write_mutex);
return SWITCH_STATUS_SUCCESS;
}
static void set_text_funcs(switch_core_session_t *session)
{
if ((switch_core_session_override_io_routines(session, &verto_io_override) == SWITCH_STATUS_SUCCESS)) {
verto_pvt_t *tech_pvt = switch_core_session_get_private_class(session, SWITCH_PVT_SECONDARY);
tech_pvt->text_read_frame.data = tech_pvt->text_read_frame_data;
switch_mutex_init(&tech_pvt->text_read_mutex, SWITCH_MUTEX_NESTED, tech_pvt->pool);
switch_mutex_init(&tech_pvt->text_write_mutex, SWITCH_MUTEX_NESTED, tech_pvt->pool);
switch_mutex_init(&tech_pvt->text_cond_mutex, SWITCH_MUTEX_NESTED, tech_pvt->pool);
switch_thread_cond_create(&tech_pvt->text_cond, tech_pvt->pool);
switch_buffer_create_dynamic(&tech_pvt->text_read_buffer, 512, 1024, 0);
switch_buffer_create_dynamic(&tech_pvt->text_write_buffer, 512, 1024, 0);
switch_channel_set_flag(switch_core_session_get_channel(session), CF_TEXT);
switch_core_session_start_text_thread(session);
}
}
static char *verto_get_dial_string(const char *uid, switch_stream_handle_t *rstream)
{
jsock_t *jsock;
@@ -5187,11 +5346,14 @@ static switch_call_cause_t verto_outgoing_channel(switch_core_session_t *session
char name[512];
tech_pvt = switch_core_session_alloc(*new_session, sizeof(*tech_pvt));
tech_pvt->pool = switch_core_session_get_pool(*new_session);
tech_pvt->session = *new_session;
tech_pvt->channel = channel;
tech_pvt->jsock_uuid = switch_core_session_strdup(*new_session, jsock_uuid_str);
switch_core_session_set_private_class(*new_session, tech_pvt, SWITCH_PVT_SECONDARY);
set_text_funcs(*new_session);
if (session) {
switch_channel_t *ochannel = switch_core_session_get_channel(session);
+12
View File
@@ -173,6 +173,7 @@ typedef enum {
} tflag_t;
typedef struct verto_pvt_s {
switch_memory_pool_t *pool;
char *jsock_uuid;
char *call_id;
char *r_sdp;
@@ -184,6 +185,17 @@ typedef struct verto_pvt_s {
switch_call_cause_t remote_hangup_cause;
time_t detach_time;
struct verto_pvt_s *next;
switch_byte_t text_read_frame_data[SWITCH_RTP_MAX_BUF_LEN];
switch_frame_t text_read_frame;
switch_thread_cond_t *text_cond;
switch_mutex_t *text_cond_mutex;
switch_mutex_t *text_read_mutex;
switch_mutex_t *text_write_mutex;
switch_buffer_t *text_read_buffer;
switch_buffer_t *text_write_buffer;
} verto_pvt_t;
typedef struct verto_vhost_s {
+6
View File
@@ -53,6 +53,12 @@ struct switch_buffer {
int32_t loops;
};
SWITCH_DECLARE(void *) switch_buffer_get_head_pointer(switch_buffer_t *buffer)
{
return buffer->head;
}
SWITCH_DECLARE(switch_status_t) switch_buffer_reset_partition_data(switch_buffer_t *buffer)
{
if (!switch_test_flag(buffer, SWITCH_BUFFER_FLAG_PARTITION)) {
+4
View File
@@ -42,6 +42,7 @@
#include <switch_nat.h>
#include "private/switch_core_pvt.h"
#include <switch_curl.h>
#include <switch_msrp.h>
#ifndef WIN32
#include <switch_private.h>
#ifdef HAVE_SETRLIMIT
@@ -2391,6 +2392,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init_and_modload(switch_core_flag_t
switch_core_set_signal_handlers();
switch_load_network_lists(SWITCH_FALSE);
switch_msrp_init();
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Bringing up environment.\n");
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Loading Modules.\n");
if (switch_loadable_module_init(SWITCH_TRUE) != SWITCH_STATUS_SUCCESS) {
@@ -2905,6 +2908,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_destroy(void)
switch_scheduler_task_thread_stop();
switch_rtp_shutdown();
switch_msrp_destroy();
if (switch_test_flag((&runtime), SCF_USE_AUTO_NAT)) {
switch_nat_shutdown();
+2140 -92
View File
File diff suppressed because it is too large Load Diff
+18
View File
@@ -88,6 +88,11 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_media_bug_get_session(switch
return bug->session;
}
SWITCH_DECLARE(const char *) switch_core_media_bug_get_text(switch_media_bug_t *bug)
{
return bug->text_framedata;
}
SWITCH_DECLARE(switch_frame_t *) switch_core_media_bug_get_video_ping_frame(switch_media_bug_t *bug)
{
return bug->video_ping_frame;
@@ -791,6 +796,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_add(switch_core_session_t
switch_queue_create(&bug->spy_video_queue[1], SWITCH_CORE_QUEUE_LEN, switch_core_session_get_pool(session));
}
if ((switch_test_flag(bug, SMBF_READ_TEXT_STREAM))) {
switch_buffer_create_dynamic(&bug->text_buffer, 512, 1024, 0);
switch_zmalloc(bug->text_framedata, 1024);
bug->text_framesize = 1024;
}
if ((switch_test_flag(bug, SMBF_READ_VIDEO_STREAM) || switch_test_flag(bug, SMBF_WRITE_VIDEO_STREAM))) {
switch_memory_pool_t *pool = switch_core_session_get_pool(session);
@@ -1150,6 +1163,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_bug_close(switch_media_bug_t *
bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_CLOSE);
}
if (bp->text_buffer) {
switch_buffer_destroy(&bp->text_buffer);
switch_safe_free(bp->text_framedata);
}
if (switch_test_flag(bp, SMBF_READ_VIDEO_STREAM) || switch_test_flag(bp, SMBF_WRITE_VIDEO_STREAM) || switch_test_flag(bp, SMBF_READ_VIDEO_PING) || switch_test_flag(bp, SMBF_WRITE_VIDEO_PING)) {
switch_channel_clear_flag_recursive(bp->session->channel, CF_VIDEO_DECODED_READ);
}
+28
View File
@@ -1469,6 +1469,10 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t *
switch_channel_get_name((*session)->channel), switch_channel_state_name(switch_channel_get_state((*session)->channel)));
if ((*session)->text_buffer) {
switch_buffer_destroy(&(*session)->text_buffer);
}
switch_core_session_reset(*session, SWITCH_TRUE, SWITCH_TRUE);
switch_core_media_bug_remove_all(*session);
@@ -1880,6 +1884,19 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_thread_launch(switch_core_se
return status;
}
SWITCH_DECLARE(const char *) switch_core_session_get_text_buffer(switch_core_session_t *session)
{
const char *buf = NULL;
if (session->text_buffer) {
switch_mutex_lock(session->text_mutex);
buf = (const char *)switch_core_session_strdup(session, (const char *) switch_buffer_get_head_pointer(session->text_buffer));
switch_mutex_unlock(session->text_mutex);
}
return buf;
}
SWITCH_DECLARE(void) switch_core_session_launch_thread(switch_core_session_t *session, switch_thread_start_t func, void *obj)
{
switch_thread_t *thread;
@@ -2945,6 +2962,17 @@ SWITCH_DECLARE(void) switch_core_session_raw_read(switch_core_session_t *session
switch_core_session_set_codec_slin(session, session->sdata);
}
SWITCH_DECLARE(switch_status_t) switch_core_session_override_io_routines(switch_core_session_t *session, switch_io_routines_t *ior)
{
if (session->endpoint_interface && switch_channel_test_cap(session->channel, CC_IO_OVERRIDE)) {
session->io_override = ior;
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
/* For Emacs:
* Local Variables:
* mode:c
+1
View File
@@ -219,6 +219,7 @@ static char *EVENT_NAMES[] = {
"CALL_SETUP_RESULT",
"CALL_DETAIL",
"DEVICE_STATE",
"REAL_TIME_TEXT",
"ALL"
};
+8 -1
View File
@@ -2728,7 +2728,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_
char tmp[512], *f;
int cdr_off = 0, v_off = 0, cd_off = 0;
switch_hold_record_t *hold_record = switch_channel_get_hold_record(channel), *hr;
const char *text_buffer = NULL;
if (*xml_cdr) {
cdr = *xml_cdr;
} else {
@@ -2750,6 +2751,12 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_
x_field = switch_xml_add_child_d(x_channel_data, "direction", cd_off++);
switch_xml_set_txt_d(x_field, switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound");
if ((text_buffer = switch_core_session_get_text_buffer(session))) {
x_field = switch_xml_add_child_d(x_channel_data, "textlog", cd_off++);
switch_xml_set_txt_d(x_field, text_buffer);
}
x_field = switch_xml_add_child_d(x_channel_data, "state_number", cd_off++);
switch_snprintf(tmp, sizeof(tmp), "%d", switch_channel_get_state(channel));
switch_xml_set_txt_d(x_field, tmp);
+80
View File
@@ -663,6 +663,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_echo(switch_core_session_t *s
}
switch_channel_set_flag(channel, CF_VIDEO_ECHO);
switch_channel_set_flag(channel, CF_TEXT_ECHO);
while (switch_channel_ready(channel)) {
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
@@ -717,6 +718,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_session_echo(switch_core_session_t *s
switch_core_session_video_reset(session);
switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
switch_channel_clear_flag(channel, CF_TEXT_ECHO);
return SWITCH_STATUS_SUCCESS;
}
@@ -1525,6 +1527,84 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s
return SWITCH_TRUE;
}
static switch_bool_t text_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
{
switch (type) {
case SWITCH_ABC_TYPE_READ_TEXT:
{
const char *text = switch_core_media_bug_get_text(bug);
if (!zstr(text)) {
switch_event_t *event = NULL;
switch_core_session_t *session = switch_core_media_bug_get_session(bug);
//switch_channel_t *channel = switch_core_session_get_channel(session);
if (switch_event_create(&event, SWITCH_EVENT_REAL_TIME_TEXT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_body(event, text, SWITCH_VA_NONE);
if (switch_true(switch_core_get_variable("fire_text_events"))) {
switch_event_t *clone = NULL;
switch_event_dup(&clone, event);
switch_event_fire(&clone);
}
switch_core_session_queue_event(session, &event);
}
}
}
break;
default:
break;
}
return SWITCH_TRUE;
}
SWITCH_DECLARE(switch_status_t) switch_ivr_capture_text(switch_core_session_t *session, switch_bool_t on)
{
switch_media_bug_t *bug;
switch_channel_t *channel = switch_core_session_get_channel(session);
bug = (switch_media_bug_t *) switch_channel_get_private(channel, "capture_text");
if (on) {
if (bug) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "text bug already attached\n");
return SWITCH_STATUS_FALSE;
}
if (switch_core_media_bug_add(session, "capture_text", switch_core_session_get_uuid(session),
text_callback, NULL, 0,
SMBF_READ_TEXT_STREAM,
&bug) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot attach bug\n");
return SWITCH_STATUS_FALSE;
}
switch_channel_set_private(channel, "capture_text", bug);
return SWITCH_STATUS_SUCCESS;
} else {
if (bug) {
switch_channel_set_private(channel, "capture_text", NULL);
switch_core_media_bug_remove(session, &bug);
return SWITCH_STATUS_SUCCESS;
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "text bug not attached\n");
return SWITCH_STATUS_FALSE;
}
}
}
SWITCH_DECLARE(switch_status_t) switch_ivr_record_session_mask(switch_core_session_t *session, const char *file, switch_bool_t on)
{
switch_media_bug_t *bug;
+54 -4
View File
@@ -39,13 +39,39 @@ static void cleanup_proxy_mode_b(switch_core_session_t *session);
/* Bridge Related Stuff*/
/*********************************************************************************/
#ifdef SWITCH_VIDEO_IN_THREADS
struct vid_helper {
switch_core_session_t *session_a;
switch_core_session_t *session_b;
int up;
};
static void text_bridge_thread(switch_core_session_t *session, void *obj)
{
struct vid_helper *vh = obj;
switch_status_t status;
switch_frame_t *read_frame = 0;
switch_channel_t *channel = switch_core_session_get_channel(vh->session_a);
switch_channel_t *b_channel = switch_core_session_get_channel(vh->session_b);
vh->up = 1;
while (switch_channel_up_nosig(channel) && switch_channel_up_nosig(b_channel) && vh->up == 1) {
status = switch_core_session_read_text_frame(vh->session_a, &read_frame, SWITCH_IO_FLAG_NONE, 0);
if (SWITCH_READ_ACCEPTABLE(status) && !switch_test_flag(read_frame, SFF_CNG)) {
switch_core_session_write_text_frame(vh->session_b, read_frame, 0, 0);
}
switch_core_session_write_text_frame(vh->session_a, NULL, 0, 0);
}
vh->up = 0;
}
#ifdef SWITCH_VIDEO_IN_THREADS
static void video_bridge_thread(switch_core_session_t *session, void *obj)
{
struct vid_helper *vh = obj;
@@ -156,7 +182,7 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj)
static void launch_video(struct vid_helper *vh)
{
switch_core_media_start_video_function(vh->session_a, video_bridge_thread, vh);
switch_core_media_start_engine_function(vh->session_a, SWITCH_MEDIA_TYPE_VIDEO, video_bridge_thread, vh);
}
#endif
@@ -267,6 +293,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
const char *exec_app = NULL;
const char *exec_data = NULL;
switch_codec_implementation_t read_impl = { 0 };
uint32_t txt_launch = 0;
struct vid_helper th = { 0 };
#ifdef SWITCH_VIDEO_IN_THREADS
struct vid_helper vh = { 0 };
@@ -382,6 +410,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
bridge_filter_dtmf = switch_true(switch_channel_get_variable(chan_a, "bridge_filter_dtmf"));
for (;;) {
switch_channel_state_t b_state;
switch_status_t status;
@@ -445,6 +474,16 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
}
continue;
}
if (switch_channel_test_flag(chan_a, CF_TEXT) && switch_channel_test_flag(chan_b, CF_TEXT) && !txt_launch) {
txt_launch++;
th.session_a = session_a;
th.session_b = session_b;
switch_core_media_start_engine_function(th.session_a, SWITCH_MEDIA_TYPE_TEXT, text_bridge_thread, &th);
}
#ifdef SWITCH_VIDEO_IN_THREADS
if (switch_channel_test_flag(chan_a, CF_VIDEO) && switch_channel_test_flag(chan_b, CF_VIDEO) && !vid_launch) {
vid_launch++;
@@ -649,6 +688,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
end_of_bridge_loop:
#ifdef SWITCH_VIDEO_IN_THREADS
if (vh.up > 0) {
vh.up = -1;
@@ -693,8 +733,18 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
end:
if (switch_core_media_check_engine_function(session_a, SWITCH_MEDIA_TYPE_TEXT)) {
if (th.up == 1) {
th.up = -1;
}
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Ending text thread.\n");
switch_core_media_end_engine_function(session_a, SWITCH_MEDIA_TYPE_TEXT);
}
#ifdef SWITCH_VIDEO_IN_THREADS
if (switch_core_media_check_video_function(session_a)) {
if (switch_core_media_check_engine_function(session_a, SWITCH_MEDIA_TYPE_VIDEO)) {
if (vh.up == 1) {
vh.up = -1;
}
@@ -705,7 +755,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session_a), SWITCH_LOG_DEBUG, "Ending video thread.\n");
switch_core_media_end_video_function(session_a);
switch_core_media_end_engine_function(session_a, SWITCH_MEDIA_TYPE_VIDEO);
switch_channel_clear_flag(chan_a, CF_NOT_READY);
switch_channel_clear_flag(chan_b, CF_NOT_READY);
}
+23 -7
View File
@@ -37,7 +37,7 @@
#define PERIOD_LEN 250
#define MAX_FRAME_PADDING 2
#define MAX_MISSING_SEQ 20
#define jb_debug(_jb, _level, _format, ...) if (_jb->debug_level >= _level) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(_jb->session), SWITCH_LOG_ALERT, "JB:%p:%s lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->" _format, (void *) _jb, (jb->type == SJB_AUDIO ? "aud" : "vid"), _level, __LINE__, _jb->min_frame_len, _jb->max_frame_len, _jb->frame_len, _jb->complete_frames, _jb->period_count, _jb->consec_good_count, _jb->period_good_count, _jb->consec_miss_count, _jb->period_miss_count, _jb->period_miss_pct, __VA_ARGS__)
#define jb_debug(_jb, _level, _format, ...) if (_jb->debug_level >= _level) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(_jb->session), SWITCH_LOG_ALERT, "JB:%p:%s lv:%d ln:%.4d sz:%.3u/%.3u/%.3u/%.3u c:%.3u %.3u/%.3u/%.3u/%.3u %.2f%% ->" _format, (void *) _jb, (jb->type == SJB_TEXT ? "txt" : (jb->type == SJB_AUDIO ? "aud" : "vid")), _level, __LINE__, _jb->min_frame_len, _jb->max_frame_len, _jb->frame_len, _jb->complete_frames, _jb->period_count, _jb->consec_good_count, _jb->period_good_count, _jb->consec_miss_count, _jb->period_miss_count, _jb->period_miss_pct, __VA_ARGS__)
//const char *TOKEN_1 = "ONE";
//const char *TOKEN_2 = "TWO";
@@ -101,6 +101,8 @@ struct switch_jb_s {
switch_jb_type_t type;
switch_core_session_t *session;
switch_channel_t *channel;
uint32_t buffer_lag;
uint32_t flush;
};
@@ -1117,7 +1119,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp
if (!want) want = got;
if (switch_test_flag(jb, SJB_QUEUE_ONLY) || jb->type == SJB_AUDIO) {
if (switch_test_flag(jb, SJB_QUEUE_ONLY) || jb->type == SJB_AUDIO || jb->type == SJB_TEXT) {
jb->next_seq = htons(got + 1);
} else {
@@ -1203,12 +1205,26 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
switch_mutex_lock(jb->mutex);
if (jb->complete_frames == 0) {
jb->flush = 0;
switch_goto_status(SWITCH_STATUS_BREAK, end);
}
if (jb->complete_frames < jb->frame_len) {
jb_debug(jb, 2, "BUFFERING %u/%u\n", jb->complete_frames , jb->frame_len);
switch_goto_status(SWITCH_STATUS_MORE_DATA, end);
if (jb->type == SJB_TEXT) {
if (jb->complete_frames && !jb->buffer_lag) {
jb->buffer_lag = 10;
}
if (jb->buffer_lag && --jb->buffer_lag == 0) {
jb->flush = 1;
}
}
if (!jb->flush) {
jb_debug(jb, 2, "BUFFERING %u/%u\n", jb->complete_frames , jb->frame_len);
switch_goto_status(SWITCH_STATUS_MORE_DATA, end);
}
}
jb_debug(jb, 2, "GET PACKET %u/%u n:%d\n", jb->complete_frames , jb->frame_len, jb->visible_nodes);
@@ -1254,8 +1270,8 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
}
}
}
}
jb->period_miss_pct = ((double)jb->period_miss_count / jb->period_count) * 100;
@@ -1263,7 +1279,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
jb_debug(jb, 2, "Miss percent %02f too high, resetting buffer.\n", jb->period_miss_pct);
switch_jb_reset(jb);
}
if ((status = jb_next_packet(jb, &node)) == SWITCH_STATUS_SUCCESS) {
jb_debug(jb, 2, "Found next frame cur ts: %u seq: %u\n", htonl(node->packet.header.ts), htons(node->packet.header.seq));
@@ -1272,7 +1288,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
jb->highest_read_seq = node->packet.header.seq;
}
if (jb->read_init && htons(node->packet.header.seq) >= htons(jb->highest_read_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_read_ts))) {
if (jb->type == SJB_TEXT || (jb->read_init && htons(node->packet.header.seq) >= htons(jb->highest_read_seq) && (ntohl(node->packet.header.ts) > ntohl(jb->highest_read_ts)))) {
jb->complete_frames--;
jb_debug(jb, 2, "READ frame ts: %u complete=%u/%u n:%u\n", ntohl(node->packet.header.ts), jb->complete_frames , jb->frame_len, jb->visible_nodes);
jb->highest_read_ts = node->packet.header.ts;
+1569
View File
File diff suppressed because it is too large Load Diff
+62 -30
View File
@@ -520,7 +520,7 @@ typedef enum {
static void do_2833(switch_rtp_t *rtp_session);
#define rtp_type(rtp_session) rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "video" : "audio"
#define rtp_type(rtp_session) rtp_session->flags[SWITCH_RTP_FLAG_TEXT] ? "text" : (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "video" : "audio")
static void switch_rtp_change_ice_dest(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, const char *host, switch_port_t port)
@@ -1287,7 +1287,7 @@ static void handle_ice(switch_rtp_t *rtp_session, switch_rtp_ice_t *ice, void *d
msg.message_id = SWITCH_MESSAGE_INDICATE_STUN_ERROR;
switch_core_session_receive_message(rtp_session->session, &msg);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG,
"STUN/ICE binding error received on %s channel\n", rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "video" : "audio");
"STUN/ICE binding error received on %s channel\n", rtp_type(rtp_session));
}
}
@@ -3192,7 +3192,7 @@ static int do_dtls(switch_rtp_t *rtp_session, switch_dtls_t *dtls)
ret = SSL_get_error(dtls->ssl, ret);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "%s DTLS packet read err %d\n", rtp_type(rtp_session), ret);
}
if (dtls_states[dtls->state]) {
r = dtls_states[dtls->state](rtp_session, dtls);
}
@@ -3396,8 +3396,11 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d
//SSL_CTX_set_verify(dtls->ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
SSL_CTX_set_verify(dtls->ssl_ctx, SSL_VERIFY_NONE, NULL);
SSL_CTX_set_cipher_list(dtls->ssl_ctx, "ALL");
SSL_CTX_set_cipher_list(dtls->ssl_ctx, "ECDH:!RC4:!SSLv3:RSA_WITH_AES_128_CBC_SHA");
//SSL_CTX_set_cipher_list(dtls->ssl_ctx, "ECDHE-RSA-AES256-GCM-SHA384");
//SSL_CTX_set_cipher_list(dtls->ssl_ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
//SSL_CTX_set_cipher_list(dtls->ssl_ctx, "SUITEB128");
SSL_CTX_set_read_ahead(dtls->ssl_ctx, 1);
#ifdef HAVE_OPENSSL_DTLS_SRTP
//SSL_CTX_set_tlsext_use_srtp(dtls->ssl_ctx, "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32");
SSL_CTX_set_tlsext_use_srtp(dtls->ssl_ctx, "SRTP_AES128_CM_SHA1_80");
@@ -3456,11 +3459,11 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_dtls(switch_rtp_t *rtp_session, d
SSL_set_verify(dtls->ssl, SSL_VERIFY_NONE, NULL);
SSL_set_app_data(dtls->ssl, dtls);
BIO_ctrl(dtls->read_bio, BIO_CTRL_DGRAM_SET_MTU, 1400, NULL);
BIO_ctrl(dtls->write_bio, BIO_CTRL_DGRAM_SET_MTU, 1400, NULL);
SSL_set_mtu(dtls->ssl, 1400);
BIO_ctrl(dtls->write_bio, BIO_C_SET_BUFF_SIZE, 1400, NULL);
BIO_ctrl(dtls->read_bio, BIO_C_SET_BUFF_SIZE, 1400, NULL);
//BIO_ctrl(dtls->read_bio, BIO_CTRL_DGRAM_SET_MTU, 1400, NULL);
//BIO_ctrl(dtls->write_bio, BIO_CTRL_DGRAM_SET_MTU, 1400, NULL);
//SSL_set_mtu(dtls->ssl, 1400);
//BIO_ctrl(dtls->write_bio, BIO_C_SET_BUFF_SIZE, 1400, NULL);
//BIO_ctrl(dtls->read_bio, BIO_C_SET_BUFF_SIZE, 1400, NULL);
@@ -3654,7 +3657,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
if (status == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Activating %s Secure %s RECV\n",
rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "Video" : "Audio", idx ? "RTCP" : "RTP");
rtp_type(rtp_session), idx ? "RTCP" : "RTP");
rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] = 1;
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error allocating srtp [%d]\n", stat);
@@ -3676,7 +3679,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_add_crypto_key(switch_rtp_t *rtp_sess
if (status == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Activating %s Secure %s SEND\n",
rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "Video" : "Audio", idx ? "RTCP" : "RTP");
rtp_type(rtp_session), idx ? "RTCP" : "RTP");
rtp_session->flags[SWITCH_RTP_FLAG_SECURE_SEND] = 1;
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "Error allocating SRTP [%d]\n", stat);
@@ -4085,11 +4088,11 @@ SWITCH_DECLARE(switch_timer_t *) switch_rtp_get_media_timer(switch_rtp_t *rtp_se
SWITCH_DECLARE(switch_jb_t *) switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_session)
{
if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) {
if (!switch_rtp_ready(rtp_session)) {
return NULL;
}
return rtp_session->jb;
return rtp_session->jb ? rtp_session->jb : rtp_session->vb;
}
SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause)
@@ -4145,13 +4148,13 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_video_buffer_size(switch_rtp_t *r
}
if (!max_frames || frames >= max_frames) {
max_frames = frames + 8;
max_frames = frames * 10;
}
rtp_session->last_max_vb_frames = max_frames;
if (!rtp_session->vb) {
switch_jb_create(&rtp_session->vb, SJB_VIDEO, frames, max_frames, rtp_session->pool);
switch_jb_create(&rtp_session->vb, rtp_session->flags[SWITCH_RTP_FLAG_TEXT] ? SJB_TEXT : SJB_VIDEO, frames, max_frames, rtp_session->pool);
switch_jb_set_session(rtp_session->vb, rtp_session->session);
} else {
switch_jb_set_frames(rtp_session->vb, frames, max_frames);
@@ -4202,7 +4205,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *
}
if (max_queue_frames < queue_frames) {
max_queue_frames = queue_frames * 6;
max_queue_frames = queue_frames * 3;
}
@@ -5687,7 +5690,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
switch_jb_destroy(&rtp_session->vb);
}
}
if (rtp_session->has_rtp && *bytes) {
uint32_t read_ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc);
@@ -5746,7 +5749,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
}
if (!*bytes || rtp_session->has_rtp) {
if (rtp_session->jb && !rtp_session->pause_jb && jb_valid(rtp_session)) {
switch_status_t jstatus = switch_jb_get_packet(rtp_session->jb, (switch_rtp_packet_t *) &rtp_session->recv_msg, bytes);
@@ -5806,9 +5809,21 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
default:
break;
}
if (vstatus == SWITCH_STATUS_NOTFOUND && rtp_session->flags[SWITCH_RTP_FLAG_TEXT]) {
int pt = get_recv_payload(rtp_session);
(*flags) |= SFF_PLC;
status = SWITCH_STATUS_SUCCESS;
*bytes = switch_jb_get_last_read_len(rtp_session->vb);
rtp_session->last_rtp_hdr = rtp_session->recv_msg.header;
if (pt > -1) {
rtp_session->last_rtp_hdr.pt = pt;
}
}
if (vstatus == SWITCH_STATUS_SUCCESS) {
rtp_session->last_rtp_hdr = rtp_session->recv_msg.header;
if (!xcheck_jitter) {
check_jitter(rtp_session);
xcheck_jitter = *bytes;
@@ -5882,6 +5897,7 @@ static void handle_nack(switch_rtp_t *rtp_session, uint32_t nack)
}
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RE----SEND %u\n", ntohs(send_msg->header.seq));
switch_rtp_write_raw(rtp_session, (void *) &send_msg, &bytes, SWITCH_FALSE);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG1, "Cannot send NACK for seq %u\n", ntohs(seq) + i);
@@ -6423,7 +6439,9 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
}
}
if (hot_socket && (rtp_session->hot_hits % 10) != 0) {
if (rtp_session->flags[SWITCH_RTP_FLAG_TEXT]) {
///NOOP
} else if (hot_socket && (rtp_session->hot_hits % 10) != 0) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG10, "%s timer while HOT\n", rtp_session_name(rtp_session));
switch_core_timer_next(&rtp_session->timer);
} else if (hot_socket) {
@@ -6510,10 +6528,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
poll_status = switch_poll(rtp_session->read_pollfd, 1, &fdr, pt);
//if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
// switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "WTF Poll %d\n", poll_status);
//}
if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && rtp_session->dtmf_data.out_digit_dur > 0) {
return_cng_frame();
}
@@ -6535,7 +6549,7 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
if (read_pretriggered) {
read_pretriggered = 0;
} else {
status = read_rtp_packet(rtp_session, &bytes, flags, poll_status, SWITCH_TRUE);
if (status == SWITCH_STATUS_GENERR) {
@@ -6807,11 +6821,11 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
if (bytes && rtp_session->last_rtp_hdr.m && rtp_session->last_rtp_hdr.pt != rtp_session->recv_te &&
!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] &&
!rtp_session->flags[SWITCH_RTP_FLAG_TEXT] &&
!(rtp_session->rtp_bugs & RTP_BUG_IGNORE_MARK_BIT)) {
rtp_flush_read_buffer(rtp_session, SWITCH_RTP_FLUSH_ONCE);
}
if (rtp_session->last_rtp_hdr.pt == rtp_session->cng_pt || rtp_session->last_rtp_hdr.pt == 13) {
*flags |= SFF_NOT_AUDIO;
} else {
@@ -6894,6 +6908,19 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_
}
}
if (rtp_session->flags[SWITCH_RTP_FLAG_TEXT]) {
if (!bytes) {
if (rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER]) {
switch_core_timer_next(&rtp_session->timer);
}
return_cng_frame();
} else {
*payload_type = rtp_session->last_rtp_hdr.pt;
ret = (int) bytes;
goto end;
}
}
if (bytes && (rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] || rtp_session->flags[SWITCH_RTP_FLAG_UDPTL])) {
/* Fast PASS! */
*flags |= SFF_PROXY_PACKET;
@@ -8065,14 +8092,19 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra
#endif
}
if (switch_test_flag(frame, SFF_RTP_HEADER)) {
switch_size_t wrote = switch_rtp_write_manual(rtp_session, frame->data, frame->datalen,
frame->m, frame->payload, (uint32_t) (frame->timestamp), &frame->flags);
if (switch_test_flag(frame, SFF_RTP_HEADER) || rtp_session->flags[SWITCH_RTP_FLAG_TEXT]) {
switch_size_t wrote;
wrote = switch_rtp_write_manual(rtp_session, frame->data, frame->datalen,
frame->m, frame->payload, (uint32_t) (frame->timestamp), &frame->flags);
rtp_session->stats.outbound.raw_bytes += wrote;
rtp_session->stats.outbound.media_bytes += wrote;
rtp_session->stats.outbound.media_packet_count++;
rtp_session->stats.outbound.packet_count++;
return wrote;
}
if (frame->pmap && rtp_session->pmaps && *rtp_session->pmaps) {