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
+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 {