mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-13 07:45:26 +00:00
FS-9576 #resolve [Add Realtime Text]
This commit is contained in:
parent
25732c82d2
commit
c409499cd9
@ -3,9 +3,9 @@
|
||||
|
||||
# Must change all of the below together
|
||||
# For a release, set revision for that tagged release as well and uncomment
|
||||
AC_INIT([freeswitch], [1.7.0], bugs@freeswitch.org)
|
||||
AC_INIT([freeswitch], [1.9.0], bugs@freeswitch.org)
|
||||
AC_SUBST(SWITCH_VERSION_MAJOR, [1])
|
||||
AC_SUBST(SWITCH_VERSION_MINOR, [7])
|
||||
AC_SUBST(SWITCH_VERSION_MINOR, [9])
|
||||
AC_SUBST(SWITCH_VERSION_MICRO, [0])
|
||||
AC_SUBST(SWITCH_VERSION_REVISION, [])
|
||||
AC_SUBST(SWITCH_VERSION_REVISION_HUMAN, [])
|
||||
|
@ -2062,12 +2062,18 @@
|
||||
obj.dialogParams = {};
|
||||
|
||||
for (var i in dialog.params) {
|
||||
if (i == "sdp" && method != "verto.invite" && method != "verto.attach") {
|
||||
if (i == "sdp" && method != "verto.invite" && method != "verto.attach") {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ((obj.noDialogParams && i != "callID")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
obj.dialogParams[i] = dialog.params[i];
|
||||
obj.dialogParams[i] = dialog.params[i];
|
||||
}
|
||||
|
||||
delete obj.noDialogParams;
|
||||
|
||||
dialog.verto.rpcClient.call(method, obj,
|
||||
|
||||
@ -2371,6 +2377,26 @@
|
||||
}
|
||||
};
|
||||
|
||||
$.verto.dialog.prototype.rtt = function(obj) {
|
||||
var dialog = this;
|
||||
var pobj = {};
|
||||
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pobj.code = obj.code;
|
||||
pobj.chars = obj.chars;
|
||||
|
||||
|
||||
if (pobj.chars || pobj.code) {
|
||||
dialog.sendMethod("verto.info", {
|
||||
txt: obj,
|
||||
noDialogParams: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
$.verto.dialog.prototype.transfer = function(dest, params) {
|
||||
var dialog = this;
|
||||
if (dest) {
|
||||
@ -2517,7 +2543,8 @@
|
||||
$.verto.dialog.prototype.handleInfo = function(params) {
|
||||
var dialog = this;
|
||||
|
||||
dialog.sendMessage($.verto.enum.message.info, params.msg);
|
||||
dialog.sendMessage($.verto.enum.message.info, params);
|
||||
|
||||
};
|
||||
|
||||
$.verto.dialog.prototype.handleDisplay = function(params) {
|
||||
|
@ -244,6 +244,14 @@ div#preload { display: none; }
|
||||
|
||||
|
||||
<video id="webcam" autoplay="autoplay" style="width:100%;height:100%;object-fit:inherit;"></video>
|
||||
<br><br>
|
||||
<table><tr><td>
|
||||
<div style="width:500px;max-height:300px;overflow-y:scroll;display:block;unicode-bidi:embed;font-family:tahoma;white-space:pre;size:14pt;text-align:left" id="rtt_in"></div>
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
<textarea style="width:500px;height:200px" id="rtt"></textarea>
|
||||
</td></tr>
|
||||
</table>
|
||||
<!--<video id="local_webcam" autoplay="autoplay" style="width:100%;height:100%;object-fit:inherit;"></video>-->
|
||||
|
||||
</div><!-- rows -->
|
||||
|
8
html5/verto/video_demo/js/verto-min.js
vendored
8
html5/verto/video_demo/js/verto-min.js
vendored
@ -255,8 +255,9 @@ if(!dialog.params.remote_caller_id_number){dialog.params.remote_caller_id_number
|
||||
RTCcallbacks.onMessage=function(rtc,msg){console.debug(msg);};RTCcallbacks.onAnswerSDP=function(rtc,sdp){console.error("answer sdp",sdp);};}else{dialog.params.remote_caller_id_name="Outbound Call";dialog.params.remote_caller_id_number=dialog.params.destination_number;}
|
||||
RTCcallbacks.onICESDP=function(rtc){console.log("RECV "+rtc.type+" SDP",rtc.mediaData.SDP);if(dialog.state==$.verto.enum.state.requesting||dialog.state==$.verto.enum.state.answering||dialog.state==$.verto.enum.state.active){location.reload();return;}
|
||||
if(rtc.type=="offer"){if(dialog.state==$.verto.enum.state.active){dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.attach",{sdp:rtc.mediaData.SDP});}else{dialog.setState($.verto.enum.state.requesting);dialog.sendMethod("verto.invite",{sdp:rtc.mediaData.SDP});}}else{dialog.setState($.verto.enum.state.answering);dialog.sendMethod(dialog.attach?"verto.attach":"verto.answer",{sdp:dialog.rtc.mediaData.SDP});}};RTCcallbacks.onICE=function(rtc){if(rtc.type=="offer"){console.log("offer",rtc.mediaData.candidate);return;}};RTCcallbacks.onStream=function(rtc,stream){console.log("stream started");};RTCcallbacks.onError=function(e){console.error("ERROR:",e);dialog.hangup({cause:"Device or Permission Error"});};dialog.rtc=new $.FSRTC({callbacks:RTCcallbacks,localVideo:dialog.screenShare?null:dialog.localVideo,useVideo:dialog.params.useVideo?dialog.videoStream:null,useAudio:dialog.audioStream,useStereo:dialog.params.useStereo,videoParams:dialog.params.videoParams,audioParams:verto.options.audioParams,iceServers:verto.options.iceServers,screenShare:dialog.screenShare,useCamera:dialog.useCamera,useMic:dialog.useMic,useSpeak:dialog.useSpeak});dialog.rtc.verto=dialog.verto;if(dialog.direction==$.verto.enum.direction.inbound){if(dialog.attach){dialog.answer();}else{dialog.ring();}}};$.verto.dialog.prototype.invite=function(){var dialog=this;dialog.rtc.call();};$.verto.dialog.prototype.sendMethod=function(method,obj){var dialog=this;obj.dialogParams={};for(var i in dialog.params){if(i=="sdp"&&method!="verto.invite"&&method!="verto.attach"){continue;}
|
||||
if((obj.noDialogParams&&i!="callID")){continue;}
|
||||
obj.dialogParams[i]=dialog.params[i];}
|
||||
dialog.verto.rpcClient.call(method,obj,function(e){dialog.processReply(method,true,e);},function(e){dialog.processReply(method,false,e);});};function checkStateChange(oldS,newS){if(newS==$.verto.enum.state.purge||$.verto.enum.states[oldS.name][newS.name]){return true;}
|
||||
delete obj.noDialogParams;dialog.verto.rpcClient.call(method,obj,function(e){dialog.processReply(method,true,e);},function(e){dialog.processReply(method,false,e);});};function checkStateChange(oldS,newS){if(newS==$.verto.enum.state.purge||$.verto.enum.states[oldS.name][newS.name]){return true;}
|
||||
return false;}
|
||||
function find_name(id){for(var i in $.verto.audioOutDevices){var source=$.verto.audioOutDevices[i];if(source.id===id){return(source.label);}}
|
||||
return id;}
|
||||
@ -280,7 +281,8 @@ if(success){}
|
||||
break;default:break;}};$.verto.dialog.prototype.hangup=function(params){var dialog=this;if(params){if(params.causeCode){dialog.causeCode=params.causeCode;}
|
||||
if(params.cause){dialog.cause=params.cause;}}
|
||||
if(dialog.state.val>=$.verto.enum.state.new.val&&dialog.state.val<$.verto.enum.state.hangup.val){dialog.setState($.verto.enum.state.hangup);}else if(dialog.state.val<$.verto.enum.state.destroy){dialog.setState($.verto.enum.state.destroy);}};$.verto.dialog.prototype.stopRinging=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.stop();}};$.verto.dialog.prototype.indicateRing=function(){var dialog=this;if(dialog.verto.ringer){dialog.verto.ringer.attr("src",dialog.verto.options.ringFile)[0].play();setTimeout(function(){dialog.stopRinging();if(dialog.state==$.verto.enum.state.ringing){dialog.indicateRing();}},dialog.verto.options.ringSleep);}};$.verto.dialog.prototype.ring=function(){var dialog=this;dialog.setState($.verto.enum.state.ringing);dialog.indicateRing();};$.verto.dialog.prototype.useVideo=function(on){var dialog=this;dialog.params.useVideo=on;if(on){dialog.videoStream=dialog.audioStream;}else{dialog.videoStream=null;}
|
||||
dialog.rtc.useVideo(dialog.videoStream,dialog.localVideo);};$.verto.dialog.prototype.setMute=function(what){var dialog=this;return dialog.rtc.setMute(what);};$.verto.dialog.prototype.getMute=function(){var dialog=this;return dialog.rtc.getMute();};$.verto.dialog.prototype.setVideoMute=function(what){var dialog=this;return dialog.rtc.setVideoMute(what);};$.verto.dialog.prototype.getVideoMute=function(){var dialog=this;return dialog.rtc.getVideoMute();};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){dialog.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;}
|
||||
dialog.rtc.useVideo(dialog.videoStream,dialog.localVideo);};$.verto.dialog.prototype.setMute=function(what){var dialog=this;return dialog.rtc.setMute(what);};$.verto.dialog.prototype.getMute=function(){var dialog=this;return dialog.rtc.getMute();};$.verto.dialog.prototype.setVideoMute=function(what){var dialog=this;return dialog.rtc.setVideoMute(what);};$.verto.dialog.prototype.getVideoMute=function(){var dialog=this;return dialog.rtc.getVideoMute();};$.verto.dialog.prototype.useStereo=function(on){var dialog=this;dialog.params.useStereo=on;dialog.rtc.useStereo(on);};$.verto.dialog.prototype.dtmf=function(digits){var dialog=this;if(digits){dialog.sendMethod("verto.info",{dtmf:digits});}};$.verto.dialog.prototype.rtt=function(obj){var dialog=this;var pobj={};if(!obj){return false;}
|
||||
pobj.code=obj.code;pobj.chars=obj.chars;if(pobj.chars||pobj.code){dialog.sendMethod("verto.info",{txt:obj,noDialogParams:true});}};$.verto.dialog.prototype.transfer=function(dest,params){var dialog=this;if(dest){dialog.sendMethod("verto.modify",{action:"transfer",destination:dest,params:params});}};$.verto.dialog.prototype.hold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"hold",params:params});};$.verto.dialog.prototype.unhold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"unhold",params:params});};$.verto.dialog.prototype.toggleHold=function(params){var dialog=this;dialog.sendMethod("verto.modify",{action:"toggleHold",params:params});};$.verto.dialog.prototype.message=function(msg){var dialog=this;var err=0;msg.from=dialog.params.login;if(!msg.to){console.error("Missing To");err++;}
|
||||
if(!msg.body){console.error("Missing Body");err++;}
|
||||
if(err){return false;}
|
||||
dialog.sendMethod("verto.info",{msg:msg});return true;};$.verto.dialog.prototype.answer=function(params){var dialog=this;if(!dialog.answered){if(!params){params={};}
|
||||
@ -289,7 +291,7 @@ dialog.params.callee_id_name=params.callee_id_name;dialog.params.callee_id_numbe
|
||||
if(params.useMic){dialog.useMic=params.useMic;}
|
||||
if(params.useSpeak){dialog.useSpeak=params.useSpeak;}}
|
||||
dialog.rtc.createAnswer(params);dialog.answered=true;}};$.verto.dialog.prototype.handleAnswer=function(params){var dialog=this;dialog.gotAnswer=true;if(dialog.state.val>=$.verto.enum.state.active.val){return;}
|
||||
if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+" Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+" Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params.msg);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;}
|
||||
if(dialog.state.val>=$.verto.enum.state.early.val){dialog.setState($.verto.enum.state.active);}else{if(dialog.gotEarly){console.log("Dialog "+dialog.callID+" Got answer while still establishing early media, delaying...");}else{console.log("Dialog "+dialog.callID+" Answering Channel");dialog.rtc.answer(params.sdp,function(){dialog.setState($.verto.enum.state.active);},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"ANSWER SDP",params.sdp);}}};$.verto.dialog.prototype.cidString=function(enc){var dialog=this;var party=dialog.params.remote_caller_id_name+(enc?" <":" <")+dialog.params.remote_caller_id_number+(enc?">":">");return party;};$.verto.dialog.prototype.sendMessage=function(msg,params){var dialog=this;if(dialog.callbacks.onMessage){dialog.callbacks.onMessage(dialog.verto,dialog,msg,params);}};$.verto.dialog.prototype.handleInfo=function(params){var dialog=this;dialog.sendMessage($.verto.enum.message.info,params);};$.verto.dialog.prototype.handleDisplay=function(params){var dialog=this;if(params.display_name){dialog.params.remote_caller_id_name=params.display_name;}
|
||||
if(params.display_number){dialog.params.remote_caller_id_number=params.display_number;}
|
||||
dialog.sendMessage($.verto.enum.message.display,{});};$.verto.dialog.prototype.handleMedia=function(params){var dialog=this;if(dialog.state.val>=$.verto.enum.state.early.val){return;}
|
||||
dialog.gotEarly=true;dialog.rtc.answer(params.sdp,function(){console.log("Dialog "+dialog.callID+"Establishing early media");dialog.setState($.verto.enum.state.early);if(dialog.gotAnswer){console.log("Dialog "+dialog.callID+"Answering Channel");dialog.setState($.verto.enum.state.active);}},function(e){console.error(e);dialog.hangup();});console.log("Dialog "+dialog.callID+"EARLY SDP",params.sdp);};$.verto.ENUM=function(s){var i=0,o={};s.split(" ").map(function(x){o[x]={name:x,val:i++};});return Object.freeze(o);};$.verto.enum={};$.verto.enum.states=Object.freeze({new:{requesting:1,recovering:1,ringing:1,destroy:1,answering:1,hangup:1},requesting:{trying:1,hangup:1,active:1},recovering:{answering:1,hangup:1},trying:{active:1,early:1,hangup:1},ringing:{answering:1,hangup:1},answering:{active:1,hangup:1},active:{answering:1,requesting:1,hangup:1,held:1},held:{hangup:1,active:1},early:{hangup:1,active:1},hangup:{destroy:1},destroy:{},purge:{destroy:1}});$.verto.enum.state=$.verto.ENUM("new requesting trying recovering ringing answering early active held hangup destroy purge");$.verto.enum.direction=$.verto.ENUM("inbound outbound");$.verto.enum.message=$.verto.ENUM("display info pvtEvent");$.verto.enum=Object.freeze($.verto.enum);$.verto.saved=[];$.verto.unloadJobs=[];$(window).bind('beforeunload',function(){for(var f in $.verto.unloadJobs){$.verto.unloadJobs[f]();}
|
||||
|
@ -403,41 +403,67 @@ var callbacks = {
|
||||
}
|
||||
break;
|
||||
case $.verto.enum.message.info:
|
||||
var body = data.body;
|
||||
|
||||
if (data.msg) {
|
||||
data = data.msg;
|
||||
var body = data.body;
|
||||
|
||||
/*
|
||||
// This section has been replaced with messageTextToJQ function
|
||||
|
||||
if (body.match(/\.gif|\.jpg|\.jpeg|\.png/)) {
|
||||
if (body.match(/\.gif|\.jpg|\.jpeg|\.png/)) {
|
||||
var mod = "";
|
||||
if (body.match(/dropbox.com/)) {
|
||||
mod = "?dl=1";
|
||||
mod = "?dl=1";
|
||||
}
|
||||
body = body.replace(/(http[s]{0,1}:\/\/\S+)/g, "<a target='_blank' href='$1'>$1<br><img border='0' class='chatimg' src='$1'" + mod + "><\/a>");
|
||||
} else {
|
||||
} else {
|
||||
body = body.replace(/(http[s]{0,1}:\/\/\S+)/g, "<a target='_blank' href='$1'>$1<\/a>");
|
||||
}
|
||||
}
|
||||
|
||||
if (body.slice(-1) !== "\n") {
|
||||
if (body.slice(-1) !== "\n") {
|
||||
body += "\n";
|
||||
}
|
||||
body = body.replace(/(?:\r\n|\r|\n)/g, '<br />');
|
||||
|
||||
var from = data.from_msg_name || data.from;
|
||||
}
|
||||
body = body.replace(/(?:\r\n|\r|\n)/g, '<br />');
|
||||
|
||||
var from = data.from_msg_name || data.from;
|
||||
|
||||
$("#chatwin").append("<span class=chatuid>" + from + ":</span><br>" + body);
|
||||
$('#chatwin').animate({"scrollTop": $('#chatwin')[0].scrollHeight}, "fast");
|
||||
$("#chatwin").append("<span class=chatuid>" + from + ":</span><br>" + body);
|
||||
$('#chatwin').animate({"scrollTop": $('#chatwin')[0].scrollHeight}, "fast");
|
||||
*/
|
||||
|
||||
var from = data.from_msg_name || data.from;
|
||||
|
||||
$('#chatwin')
|
||||
.append($('<span class="chatuid" />').text(from + ':'))
|
||||
.append($('<br />'))
|
||||
.append(messageTextToJQ(body))
|
||||
.append($('<br />'));
|
||||
$('#chatwin').animate({"scrollTop": $('#chatwin')[0].scrollHeight}, "fast");
|
||||
var from = data.from_msg_name || data.from;
|
||||
|
||||
$('#chatwin')
|
||||
.append($('<span class="chatuid" />').text(from + ':'))
|
||||
.append($('<br />'))
|
||||
.append(messageTextToJQ(body))
|
||||
.append($('<br />'));
|
||||
$('#chatwin').animate({"scrollTop": $('#chatwin')[0].scrollHeight}, "fast");
|
||||
}
|
||||
|
||||
if (data.txt) {
|
||||
console.log(data.txt);
|
||||
if (data.txt.chars) {
|
||||
var a = [...data.txt.chars];
|
||||
//console.log(a);
|
||||
for (var x in a) {
|
||||
if(a[x] == "\r") {
|
||||
$("#rtt_in").append("\n");
|
||||
continue;
|
||||
} else if (a[x] == "\b") {
|
||||
$("#rtt_in").text($("#rtt_in").text().slice(0, -1));
|
||||
continue;
|
||||
}
|
||||
console.log("[" + a[x] + "]");
|
||||
$("#rtt_in").append(a[x]);
|
||||
}
|
||||
|
||||
var psconsole = $('#rtt_in');
|
||||
if(psconsole.length)
|
||||
psconsole.scrollTop(psconsole[0].scrollHeight - psconsole.height());
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case $.verto.enum.message.display:
|
||||
var party = dialog.params.remote_caller_id_name + "<" + dialog.params.remote_caller_id_number + ">";
|
||||
@ -1558,6 +1584,30 @@ function init() {
|
||||
|
||||
setupChat();
|
||||
|
||||
$("#rtt").val("");
|
||||
$("#rtt_in").text("");
|
||||
|
||||
|
||||
$("#rtt").keyup(function (event) {
|
||||
console.error(event);
|
||||
console.log("KEY (" + event.which + ")\n");
|
||||
|
||||
if (event.which == 8) {
|
||||
cur_call.rtt({code: event.which});
|
||||
}
|
||||
|
||||
if (event.which == 13) {
|
||||
$("#rtt").val("");
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
$("#rtt").keypress(function (event) {
|
||||
console.error(event);
|
||||
console.log("TEXT (" + event.which + ")\n");
|
||||
cur_call.rtt({code: event.which});
|
||||
});
|
||||
|
||||
$("#ext").keyup(function (event) {
|
||||
if (event.keyCode == 13) {
|
||||
$( "#callbtn" ).trigger( "click" );
|
||||
|
@ -147,6 +147,7 @@ static const char *EVENT_NAMES[] = {
|
||||
"CALL_SETUP_RESULT",
|
||||
"CALL_DETAIL",
|
||||
"DEVICE_STATE",
|
||||
"REAL_TIME_TEXT",
|
||||
"ALL"
|
||||
};
|
||||
|
||||
|
@ -137,6 +137,7 @@ typedef enum {
|
||||
ESL_EVENT_CALL_SETUP_RESULT,
|
||||
ESL_EVENT_CALL_DETAIL,
|
||||
ESL_EVENT_DEVICE_STATE,
|
||||
ESL_EVENT_REAL_TIME_TEXT,
|
||||
ESL_EVENT_ALL
|
||||
} esl_event_types_t;
|
||||
|
||||
|
@ -85,7 +85,7 @@
|
||||
|
||||
media = 1*(alpha-numeric)
|
||||
;typically "audio", "video", "application"
|
||||
;or "data"
|
||||
;or "data" or "text"
|
||||
|
||||
fmt = 1*(alpha-numeric)
|
||||
;typically an RTP payload type for audio
|
||||
|
@ -1275,7 +1275,7 @@ static void parse_media(sdp_parser_t *p, char *r, sdp_media_t **result)
|
||||
|
||||
media = token
|
||||
;typically "audio", "video", "application"
|
||||
;or "data"
|
||||
;or "data" or "text"
|
||||
|
||||
fmt = token
|
||||
;typically an RTP payload type for audio
|
||||
@ -1378,6 +1378,8 @@ void sdp_media_type(sdp_media_t *m, char const *s)
|
||||
m->m_type = sdp_media_image, m->m_type_name = "image";
|
||||
else if (su_casematch(s, "red"))
|
||||
m->m_type = sdp_media_red, m->m_type_name = "red";
|
||||
else if (su_casematch(s, "text"))
|
||||
m->m_type = sdp_media_text, m->m_type_name = "text";
|
||||
else
|
||||
m->m_type = sdp_media_x, m->m_type_name = s;
|
||||
}
|
||||
|
@ -583,6 +583,7 @@ static void print_media(sdp_printer_t *p,
|
||||
case sdp_media_control: media = "control"; break;
|
||||
case sdp_media_message: media = "message"; break;
|
||||
case sdp_media_image : media = "image"; break;
|
||||
case sdp_media_text : media = "text"; break;
|
||||
default: media = m->m_type_name;
|
||||
}
|
||||
|
||||
|
@ -232,7 +232,8 @@ typedef enum
|
||||
sdp_media_message, /**< Messaging sessions*/
|
||||
sdp_media_image, /**< Image browsing sessions,
|
||||
* e.g., JPIP or T.38. */
|
||||
sdp_media_red /**< Redundancy. @NEW_1_12_4. */
|
||||
sdp_media_red, /**< Redundancy. @NEW_1_12_4. */
|
||||
sdp_media_text, /**< Realtime Text */
|
||||
} sdp_media_e;
|
||||
|
||||
/** Media transport protocol. */
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -122,9 +122,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;
|
||||
@ -331,10 +333,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_codec_control(switch_core_sess
|
||||
|
||||
|
||||
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);
|
||||
|
||||
@ -353,7 +355,23 @@ 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_END_EXTERN_C
|
||||
#endif
|
||||
/* For Emacs:
|
||||
|
@ -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);
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -39,7 +39,8 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
SJB_VIDEO = 0,
|
||||
SJB_AUDIO
|
||||
SJB_AUDIO,
|
||||
SJB_TEXT
|
||||
} switch_jb_type_t;
|
||||
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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 {
|
||||
@ -769,6 +773,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;
|
||||
|
||||
@ -1369,6 +1374,8 @@ typedef enum {
|
||||
CC_JITTERBUFFER,
|
||||
CC_FS_RTP,
|
||||
CC_QUEUEABLE_DTMF_DELAY,
|
||||
CC_IO_OVERRIDE,
|
||||
CC_RTP_RTT,
|
||||
/* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
|
||||
CC_FLAG_MAX
|
||||
} switch_channel_cap_t;
|
||||
@ -1514,6 +1521,13 @@ 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,
|
||||
/* 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
|
||||
@ -1570,7 +1584,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;
|
||||
|
||||
@ -1714,9 +1729,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
|
||||
|
||||
|
||||
/*!
|
||||
@ -1775,7 +1791,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;
|
||||
|
||||
@ -2021,6 +2038,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;
|
||||
|
||||
@ -2236,13 +2254,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,
|
||||
@ -2609,6 +2629,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:
|
||||
|
@ -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)
|
||||
{
|
||||
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,16 @@ 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)
|
||||
{
|
||||
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 +4291,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
|
||||
};
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -159,6 +159,7 @@ 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_QUEUEABLE_DTMF_DELAY);
|
||||
|
||||
|
||||
|
@ -53,7 +53,7 @@
|
||||
#include <poll.h>
|
||||
#define closesocket(x) close(x)
|
||||
#endif
|
||||
#include <switch_utils.h>
|
||||
#include <switch.h>
|
||||
#include "mcast.h"
|
||||
|
||||
|
||||
|
@ -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, ¶ms);
|
||||
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);
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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)) {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -219,6 +219,7 @@ static char *EVENT_NAMES[] = {
|
||||
"CALL_SETUP_RESULT",
|
||||
"CALL_DETAIL",
|
||||
"DEVICE_STATE",
|
||||
"REAL_TIME_TEXT",
|
||||
"ALL"
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
@ -223,7 +249,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
|
||||
|
||||
@ -334,6 +360,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 };
|
||||
@ -449,6 +477,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;
|
||||
@ -512,6 +541,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++;
|
||||
@ -716,6 +755,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;
|
||||
@ -760,8 +800,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;
|
||||
}
|
||||
@ -772,7 +822,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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -511,7 +511,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)
|
||||
@ -1278,7 +1278,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));
|
||||
}
|
||||
|
||||
}
|
||||
@ -3626,7 +3626,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);
|
||||
@ -3648,7 +3648,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);
|
||||
@ -4057,11 +4057,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)
|
||||
@ -4123,7 +4123,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_video_buffer_size(switch_rtp_t *r
|
||||
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);
|
||||
@ -5659,7 +5659,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);
|
||||
|
||||
@ -5718,7 +5718,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);
|
||||
|
||||
@ -5778,9 +5778,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;
|
||||
@ -5854,6 +5866,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);
|
||||
@ -6281,7 +6294,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) {
|
||||
@ -6368,10 +6383,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();
|
||||
}
|
||||
@ -6393,7 +6404,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) {
|
||||
@ -6665,11 +6676,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 {
|
||||
@ -6752,6 +6763,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;
|
||||
@ -7923,14 +7947,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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user