mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-07-24 21:22:09 +00:00
Merge branch 'staging-1.9'
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user