]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-9638
authorAnthony Minessale <anthm@freeswitch.org>
Wed, 12 Oct 2016 23:00:13 +0000 (18:00 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 10 Nov 2016 18:09:00 +0000 (12:09 -0600)
32 files changed:
Makefile.am
configure.ac
scripts/lua/tdd_echo.lua [new file with mode: 0644]
src/include/private/switch_core_pvt.h
src/include/switch_channel.h
src/include/switch_cpp.h
src/include/switch_types.h
src/include/switch_utils.h
src/mod/applications/mod_conference/mod_conference.c
src/mod/applications/mod_dptools/mod_dptools.c
src/mod/applications/mod_spandsp/mod_spandsp_dsp.c
src/mod/endpoints/mod_sofia/mod_sofia.c
src/mod/endpoints/mod_sofia/sofia.c
src/mod/languages/mod_java/src/org/freeswitch/swig/CoreSession.java
src/mod/languages/mod_java/src/org/freeswitch/swig/freeswitchJNI.java
src/mod/languages/mod_java/switch_swig_wrap.cpp
src/mod/languages/mod_lua/freeswitch_lua.cpp
src/mod/languages/mod_lua/mod_lua.cpp
src/mod/languages/mod_lua/mod_lua_wrap.cpp
src/mod/languages/mod_managed/freeswitch_wrap.cxx
src/mod/languages/mod_managed/managed/swig.cs
src/mod/languages/mod_perl/freeswitch.pm
src/mod/languages/mod_perl/mod_perl_wrap.cpp
src/mod/languages/mod_python/freeswitch.py
src/mod/languages/mod_python/mod_python_wrap.cpp
src/switch_channel.c
src/switch_core_media.c
src/switch_core_session.c
src/switch_cpp.cpp
src/switch_ivr_bridge.c
src/switch_msrp.c
src/switch_utils.c

index 934fe4272cea7c92ef64acdbf8d0ec0f6cdf0453..0c55f61b6d9a086866d85f495a8d2cb8c9ef34a7 100644 (file)
@@ -168,6 +168,10 @@ if HAVE_FREETYPE
 CORE_CFLAGS += -DSWITCH_HAVE_FREETYPE $(LIBFREETYPE_CFLAGS)
 endif
 
+if HAVE_GUMBO
+CORE_CFLAGS += -DSWITCH_HAVE_GUMBO $(LIBGUMBO_CFLAGS)
+endif
+
 ##
 ## libfreeswitch
 ##
@@ -230,9 +234,9 @@ CORE_LIBS+=libfreeswitch_libyuv.la
 endif
 
 lib_LTLIBRARIES                 = libfreeswitch.la
-libfreeswitch_la_CFLAGS  = $(CORE_CFLAGS) $(SQLITE_CFLAGS) $(FREETYPE_CFLAGS) $(CURL_CFLAGS) $(PCRE_CFLAGS) $(SPEEX_CFLAGS) $(LIBEDIT_CFLAGS) $(openssl_CFLAGS)  $(AM_CFLAGS)
+libfreeswitch_la_CFLAGS  = $(CORE_CFLAGS) $(SQLITE_CFLAGS) $(GUMBO_CFLAGS) $(FREETYPE_CFLAGS) $(CURL_CFLAGS) $(PCRE_CFLAGS) $(SPEEX_CFLAGS) $(LIBEDIT_CFLAGS) $(openssl_CFLAGS)  $(AM_CFLAGS)
 libfreeswitch_la_LDFLAGS = -version-info 1:0:0 $(AM_LDFLAGS) $(PLATFORM_CORE_LDFLAGS) -no-undefined
-libfreeswitch_la_LIBADD  = $(CORE_LIBS) $(APR_LIBS) $(SQLITE_LIBS) $(FREETYPE_LIBS) $(CURL_LIBS) $(PCRE_LIBS) $(SPEEX_LIBS) $(LIBEDIT_LIBS) $(openssl_LIBS) $(PLATFORM_CORE_LIBS)
+libfreeswitch_la_LIBADD  = $(CORE_LIBS) $(APR_LIBS) $(SQLITE_LIBS) $(GUMBO_LIBS) $(FREETYPE_LIBS) $(CURL_LIBS) $(PCRE_LIBS) $(SPEEX_LIBS) $(LIBEDIT_LIBS) $(openssl_LIBS) $(PLATFORM_CORE_LIBS)
 libfreeswitch_la_DEPENDENCIES = $(BUILT_SOURCES)
 
 if HAVE_PNG
index 539ab5d385809c6092963353c781c2214a9c77bf..6dac862d729c5fe512d9d599692c3cf35930b3df 100644 (file)
@@ -1288,6 +1288,11 @@ PKG_CHECK_MODULES([LIBPNG], [libpng >= 1.6.16],[
 PKG_CHECK_MODULES([FREETYPE], [freetype2 >= 2.4.9],[
   AM_CONDITIONAL([HAVE_FREETYPE],[true])],[
   AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_FREETYPE],[false])])
+
+PKG_CHECK_MODULES([GUMBO], [gumbo >= 0.10.1],[
+  AM_CONDITIONAL([HAVE_GUMBO],[true])],[
+  AC_MSG_RESULT([no]); AM_CONDITIONAL([HAVE_GUMBO],[false])])
+
 PKG_CHECK_MODULES([SQLITE], [sqlite3 >= 3.6.20])
 PKG_CHECK_MODULES([CURL], [libcurl >= 7.19])
 PKG_CHECK_MODULES([PCRE], [libpcre >= 7.8])
diff --git a/scripts/lua/tdd_echo.lua b/scripts/lua/tdd_echo.lua
new file mode 100644 (file)
index 0000000..a6c67d9
--- /dev/null
@@ -0,0 +1,52 @@
+
+local count = 0;
+local tddstring = {};
+
+
+function my_cb(s, type, obj, arg)
+   if (arg) then
+      freeswitch.console_log("info", "\ntype: " .. type .. "\n" .. "arg: " .. arg .. "\n");
+   else
+      freeswitch.console_log("info", "\ntype: " .. type .. "\n");
+   end
+
+
+   tdddata = obj:getHeader("TDD-Data");
+   count = 0;
+   table.insert(tddstring, tdddata);
+   
+   
+   freeswitch.console_log("info", obj:serialize("xml"));
+end
+
+function all_done(s, how)
+   freeswitch.console_log("info", "done: " .. how .. "\n");
+end
+
+function tablelength(T)
+   local count = 0
+   for _ in pairs(T) do count = count + 1 end
+   return count
+end
+
+
+blah = "args";
+session:setHangupHook("all_done");
+session:setInputCallback("my_cb", "blah");
+session:answer();
+
+session:execute("playback", "silence_stream://2000");
+session:execute("spandsp_detect_tdd");
+session:execute("spandsp_send_tdd", "Welcome to FreeSWITCH");
+
+while session:ready() do
+   session:streamFile("silence_stream://10000");
+   if (count > 0) then
+      count = 0;
+      if (tablelength(tddstring) > 0) then
+        session:execute("spandsp_send_tdd", "You said: " .. table.concat(tddstring));
+        tddstring = {};
+      end
+   end
+   count = count + 1;
+end
index bf4dd351e196df88f0d0bf14992fec63e61d86c8..d3b9de1e80a2b80e7e7382ad9e7ab443030481ed 100644 (file)
@@ -195,6 +195,7 @@ struct switch_core_session {
        switch_slin_data_t *sdata;
 
        switch_buffer_t *text_buffer;
+       switch_buffer_t *text_line_buffer;
        switch_mutex_t *text_mutex;
 };
 
index b1f4b2d219bb8f6c55bb9257320f466ebb2422a1..f720bf2d981036be494653bb6e33c987a17374a2 100644 (file)
@@ -93,6 +93,9 @@ SWITCH_DECLARE(int) switch_channel_test_ready(switch_channel_t *channel, switch_
 
 #define switch_channel_media_ack(_channel) (!switch_channel_test_cap(_channel, CC_MEDIA_ACK) || switch_channel_test_flag(_channel, CF_MEDIA_ACK))
 
+#define switch_channel_text_only(_channel) (switch_channel_test_flag(_channel, CF_HAS_TEXT) && !switch_channel_test_flag(_channel, CF_AUDIO))
+
+
 SWITCH_DECLARE(void) switch_channel_wait_for_state(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state);
 SWITCH_DECLARE(void) switch_channel_wait_for_state_timeout(switch_channel_t *other_channel, switch_channel_state_t want_state, uint32_t timeout);
 SWITCH_DECLARE(switch_status_t) switch_channel_wait_for_flag(switch_channel_t *channel,
index 7fef07f4cd0a4bc7d15de5d36468c7a9798babea..9a9adb83a1b973892cca666081122a05b1d34acf 100644 (file)
@@ -235,6 +235,7 @@ SWITCH_DECLARE(bool) email(char *to, char *from, char *headers = NULL, char *bod
 
                 SWITCH_DECLARE(int) insertFile(const char *file, const char *insert_file, int sample_point);
                 SWITCH_DECLARE(int) answer();
+                SWITCH_DECLARE(int) print(char *txt);
                 SWITCH_DECLARE(int) preAnswer();
                 SWITCH_DECLARE(void) hangup(const char *cause = "normal_clearing");
                 SWITCH_DECLARE(void) hangupState(void);
index 98829e2461c36f1eacc6a24e63209b078aaec6da..b7d4b0dd8841633d1766c3f185f9db767aefdaf5 100644 (file)
@@ -1535,7 +1535,15 @@ typedef enum {
        CF_TEXT_ECHO,
        CF_TEXT_ACTIVE,
        CF_TEXT_IDLE,
+       CF_TEXT_LINE_BASED,
+       CF_QUEUE_TEXT_EVENTS,
        CF_MSRP,
+       CF_MSRPS,
+       CF_WANT_MSRP,
+       CF_WANT_MSRPS,
+       CF_RTT,
+       CF_WANT_RTT,
+       CF_AUDIO,
        /* 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
@@ -1604,7 +1612,8 @@ typedef enum {
        SAF_ROUTING_EXEC = (1 << 1),
        SAF_MEDIA_TAP = (1 << 2),
        SAF_ZOMBIE_EXEC = (1 << 3),
-       SAF_NO_LOOPBACK = (1 << 4)
+       SAF_NO_LOOPBACK = (1 << 4),
+       SAF_SUPPORT_TEXT_ONLY = (1 << 5)
 } switch_application_flag_enum_t;
 typedef uint32_t switch_application_flag_t;
 
index 9c507010449172895ad9da11ddcb952b69c6f83f..5b3285a43d7801c30ff1ad8493d7a152f7e18e63 100644 (file)
@@ -47,6 +47,25 @@ SWITCH_BEGIN_EXTERN_C
 #define SWITCH_URL_UNSAFE "\r\n #%&+:;<=>?@[\\]^`{|}\""
 
 
+static inline char *switch_get_hex_bytes(switch_byte_t *buf, switch_size_t datalen, char *new_buf, switch_size_t new_datalen)
+{
+       switch_byte_t *p, *e;
+       char *pp, *ee;
+
+       e = buf + datalen;
+       ee = new_buf + new_datalen;
+       pp = new_buf;
+
+       for (p = buf; p < e && pp < ee - 4; p++) {
+               snprintf(pp, 4, "%.2x ", (int)*p);
+               pp += 3;
+       }
+       *(pp-1) = '\0';
+
+       return new_buf;
+}
+
+
 static inline uint32_t switch_round_to_step(uint32_t num, uint32_t step)
 {
        uint32_t r;
@@ -1321,6 +1340,8 @@ typedef struct {
 **/
 SWITCH_DECLARE(void) switch_getcputime(switch_cputime *t);
 
+SWITCH_DECLARE(char *)switch_html_strip(const char *str);
+
 SWITCH_END_EXTERN_C
 #endif
 /* For Emacs:
index 1be23ea88e383fabf403d0a82f2cde13deaf00ba..1a3e17a76721a5bd8acd8b44411880c39f9fe85a 100644 (file)
@@ -1700,8 +1700,7 @@ switch_status_t conference_text_thread_callback(switch_core_session_t *session,
        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;
+               int bytes = 0;//, ok = 0;
 
                if (inuse + 1 > member->text_framesize) {
                        void *tmp = malloc(inuse + 1024);
@@ -1718,7 +1717,8 @@ switch_status_t conference_text_thread_callback(switch_core_session_t *session,
 
                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++;
@@ -1728,7 +1728,7 @@ switch_status_t conference_text_thread_callback(switch_core_session_t *session,
                if (!ok) {
                        member->text_framedata[0] = '\0';
                }
-
+               */
        }
        
        switch_mutex_unlock(member->text_mutex);
@@ -2326,7 +2326,7 @@ SWITCH_STANDARD_APP(conference_function)
        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)) {
+       if (switch_channel_test_flag(channel, CF_VIDEO_ONLY) || !switch_channel_test_flag(channel, CF_AUDIO)) {
                while(conference_utils_member_test_flag((&member), MFLAG_RUNNING) && switch_channel_ready(channel)) {
                        switch_yield(100000);
                }
@@ -3603,7 +3603,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_conference_load)
        }
 
        SWITCH_ADD_API(api_interface, "conference", "Conference module commands", conference_api_main, p);
-       SWITCH_ADD_APP(app_interface, mod_conference_app_name, mod_conference_app_name, NULL, conference_function, NULL, SAF_NONE);
+       SWITCH_ADD_APP(app_interface, mod_conference_app_name, mod_conference_app_name, NULL, conference_function, NULL, SAF_SUPPORT_TEXT_ONLY);
        SWITCH_ADD_APP(app_interface, "conference_set_auto_outcall", "conference_set_auto_outcall", NULL, conference_auto_function, NULL, SAF_NONE);
        SWITCH_ADD_CHAT(chat_interface, CONF_CHAT_PROTO, chat_send);
 
index 28b1de428fd38824b076230fa84d68b9f0c5ce5a..7ea0175b669a41d00d0e77ba6f642ce9639f0377 100644 (file)
@@ -6301,7 +6301,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
        SWITCH_ADD_APP(app_interface, "stop_tone_detect", "stop detecting tones", "Stop detecting tones", stop_fax_detect_session_function, "", SAF_NONE);
        SWITCH_ADD_APP(app_interface, "fax_detect", "Detect faxes", "Detect fax send tone", fax_detect_session_function, "", SAF_MEDIA_TAP);
        SWITCH_ADD_APP(app_interface, "tone_detect", "Detect tones", "Detect tones", tone_detect_session_function, "", SAF_MEDIA_TAP);
-       SWITCH_ADD_APP(app_interface, "echo", "Echo", "Perform an echo test against the calling channel", echo_function, "", SAF_NONE);
+       SWITCH_ADD_APP(app_interface, "echo", "Echo", "Perform an echo test against the calling channel", echo_function, "", SAF_SUPPORT_TEXT_ONLY);
        SWITCH_ADD_APP(app_interface, "park", "Park", "Park", park_function, "", SAF_SUPPORT_NOMEDIA);
        SWITCH_ADD_APP(app_interface, "park_state", "Park State", "Park State", park_state_function, "", SAF_NONE);
        SWITCH_ADD_APP(app_interface, "gentones", "Generate Tones", "Generate tones to the channel", gentones_function, "<tgml_script>[|<loops>]", SAF_NONE);
@@ -6335,7 +6335,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dptools_load)
        SWITCH_ADD_APP(app_interface, "clear_speech_cache", "Clear Speech Handle Cache", "Clear Speech Handle Cache", clear_speech_cache_function, "",
                                   SAF_NONE);
        SWITCH_ADD_APP(app_interface, "bridge", "Bridge Audio", "Bridge the audio between two sessions", audio_bridge_function, "<channel_url>",
-                                  SAF_SUPPORT_NOMEDIA);
+                                  SAF_SUPPORT_NOMEDIA|SAF_SUPPORT_TEXT_ONLY);
        SWITCH_ADD_APP(app_interface, "system", "Execute a system command", "Execute a system command", system_session_function, "<command>",
                                   SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC);
        SWITCH_ADD_APP(app_interface, "bgsystem", "Execute a system command in the background", "Execute a background system command", bgsystem_session_function, "<command>",
index 5ca1fcb87c1dd88d963b64736b1e502a1b13ffde..18c3977a8c8719047b915f6dce4d40942781bd78 100644 (file)
@@ -135,6 +135,12 @@ static void put_text_msg(void *user_data, const uint8_t *msg, int len)
                        }
 
                        switch_core_session_rwunlock(other_session);
+
+               } else if (switch_channel_test_flag(channel, CF_QUEUE_TEXT_EVENTS)) {
+
+                       if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) {
+                               switch_core_session_queue_event(pvt->session, &clone);
+                       }
                }
 
                switch_event_fire(&event);
index 63c92cc852beafdc2454d6ca4cb2549e48be9ce3..5874597976fcac0748bc430ec28936d6cc2f033a 100644 (file)
@@ -924,6 +924,62 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
 
 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)
 {
+       switch_status_t status;
+
+       if (switch_channel_test_flag(switch_core_session_get_channel(session), CF_MSRP)) {
+               switch_msrp_session_t *msrp_session = switch_core_media_get_msrp_session(session);
+               switch_frame_t *rframe = &msrp_session->frame;
+               msrp_msg_t *msrp_msg = switch_msrp_session_pop_msg(msrp_session);
+
+               rframe->flags = 0;
+
+#if 0
+               if (msrp_msg && msrp_msg->method == MSRP_METHOD_SEND) { /*echo back*/
+                       char *p;
+                       p = msrp_msg->headers[MSRP_H_TO_PATH];
+                       msrp_msg->headers[MSRP_H_TO_PATH] = msrp_msg->headers[MSRP_H_FROM_PATH];
+                       msrp_msg->headers[MSRP_H_FROM_PATH] = p;
+                       switch_msrp_send(msrp_session, msrp_msg);
+               }
+#endif
+
+               rframe->data = msrp_session->frame_data;
+               rframe->buflen = sizeof(msrp_session->frame_data);
+
+               if (msrp_msg && msrp_msg->method == MSRP_METHOD_SEND && !switch_stristr("?OTRv3?", msrp_msg->payload) &&
+                       (switch_stristr("text/plain", msrp_msg->payload) || 
+                        switch_stristr("text/html", msrp_msg->payload))) {
+                       rframe->datalen = msrp_msg->payload_bytes;
+                       rframe->packetlen = msrp_msg->payload_bytes;
+                       memcpy(rframe->data, msrp_msg->payload, msrp_msg->payload_bytes);
+                       
+                       rframe->m = 1;
+                       
+                       *frame = rframe;
+                       
+                       if (msrp_msg->headers[MSRP_H_CONTENT_TYPE] &&  !strcasecmp(msrp_msg->headers[MSRP_H_CONTENT_TYPE], "message/cpim")) {
+                               char *stripped_text = switch_html_strip((char *)rframe->data);
+                               memcpy(rframe->data, stripped_text, strlen(stripped_text)+1);
+                               rframe->datalen = strlen(stripped_text)+1;
+                               free(stripped_text);
+                       }
+
+
+                       switch_safe_free(msrp_msg);
+                       msrp_msg = NULL;
+                       status = SWITCH_STATUS_SUCCESS;
+               } else {
+                       rframe->datalen = 2;
+                       rframe->flags = SFF_CNG;
+                       *frame = rframe;
+                       status = SWITCH_STATUS_SUCCESS;
+               }
+
+               return status;
+       }
+
+
+
        return switch_core_media_read_frame(session, frame, flags, stream_id, SWITCH_MEDIA_TYPE_TEXT);
 }
 
@@ -935,11 +991,10 @@ static switch_status_t sofia_write_text_frame(switch_core_session_t *session, sw
                if (frame && msrp_session) {
                        switch_msrp_msg_t msrp_msg = { 0 };
 
-                       msrp_msg.headers[MSRP_H_CONTENT_TYPE] = "message/cpim";
-                       // msrp_msg.headers[MSRP_H_CONTENT_TYPE] = "text/plain";
+                       //msrp_msg.headers[MSRP_H_CONTENT_TYPE] = "message/cpim";
+                       msrp_msg.headers[MSRP_H_CONTENT_TYPE] = "text/plain";
                        msrp_msg.payload = frame->data;
                        msrp_msg.payload_bytes = frame->datalen;
-
                        return switch_msrp_send(msrp_session, &msrp_msg);
                }
 
index a7833b16c6b57dc59ec54d19e7c8dacc25c0a8a8..eaf48dd519c3e40404bf8bdc61ecfc8d00f15a4b 100644 (file)
@@ -8098,9 +8098,9 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                } else {
                                        uint8_t match = 0;
 
-                                       if (tech_pvt->mparams.num_codecs) {
-                                               match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
-                                       }
+                                       
+                                       match = sofia_media_negotiate_sdp(session, r_sdp, SDP_TYPE_RESPONSE);
+                                       
 
                                        sofia_set_flag_locked(tech_pvt, TFLAG_ANS);
 
@@ -8129,7 +8129,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status,
                                                        goto done;
                                                }
                                        }
-
+                                       
                                        switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "NO CODECS");
                                        switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
                                }
index e62fddf4fd480ea829e0dcc0ad728fd5656a8e97..b104d7b70622d2aeab2ebc807b027c9df34a4436 100644 (file)
@@ -126,6 +126,10 @@ public class CoreSession {
     return freeswitchJNI.CoreSession_answer(swigCPtr, this);
   }
 
+  public int print(String txt) {
+    return freeswitchJNI.CoreSession_print(swigCPtr, this, txt);
+  }
+
   public int preAnswer() {
     return freeswitchJNI.CoreSession_preAnswer(swigCPtr, this);
   }
index 32d4748df5de0e4ef6c0fc4436bb591b6f152030..d4a922db8f919b016398566b1966460725664a0f 100644 (file)
@@ -113,6 +113,7 @@ public class freeswitchJNI {
   public final static native String CoreSession_voice_name_get(long jarg1, CoreSession jarg1_);
   public final static native int CoreSession_insertFile(long jarg1, CoreSession jarg1_, String jarg2, String jarg3, int jarg4);
   public final static native int CoreSession_answer(long jarg1, CoreSession jarg1_);
+  public final static native int CoreSession_print(long jarg1, CoreSession jarg1_, String jarg2);
   public final static native int CoreSession_preAnswer(long jarg1, CoreSession jarg1_);
   public final static native void CoreSession_hangup(long jarg1, CoreSession jarg1_, String jarg2);
   public final static native void CoreSession_hangupState(long jarg1, CoreSession jarg1_);
index 697e535ac63ff40106eef49f042dcae1016d4d1b..b0b65246a7f3c314d2bfbb384046c51987075f28 100644 (file)
@@ -2166,6 +2166,28 @@ SWIGEXPORT jint JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1answ
 }
 
 
+SWIGEXPORT jint JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1print(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_, jstring jarg2) {
+  jint jresult = 0 ;
+  CoreSession *arg1 = (CoreSession *) 0 ;
+  char *arg2 = (char *) 0 ;
+  int result;
+  
+  (void)jenv;
+  (void)jcls;
+  (void)jarg1_;
+  arg1 = *(CoreSession **)&jarg1; 
+  arg2 = 0;
+  if (jarg2) {
+    arg2 = (char *)jenv->GetStringUTFChars(jarg2, 0);
+    if (!arg2) return 0;
+  }
+  result = (int)(arg1)->print(arg2);
+  jresult = (jint)result; 
+  if (arg2) jenv->ReleaseStringUTFChars(jarg2, (const char *)arg2);
+  return jresult;
+}
+
+
 SWIGEXPORT jint JNICALL Java_org_freeswitch_swig_freeswitchJNI_CoreSession_1preAnswer(JNIEnv *jenv, jclass jcls, jlong jarg1, jobject jarg1_) {
   jint jresult = 0 ;
   CoreSession *arg1 = (CoreSession *) 0 ;
index 0f2071aec0c174d7c68dbd190e8ba17a4037aa35..e9196654019f63aff0fa630e52a7169e18ae1c6d 100644 (file)
@@ -47,6 +47,8 @@ void Session::destroy(const char *err)
        switch_safe_free(cb_function);
        switch_safe_free(cb_arg);
 
+       unsetInputCallback();
+
        CoreSession::destroy();
 
 
@@ -240,6 +242,7 @@ void Session::unsetInputCallback(void)
        switch_safe_free(cb_arg);
        args.input_callback = NULL;
        ap = NULL;
+       switch_channel_clear_flag_recursive(channel, CF_QUEUE_TEXT_EVENTS);
 }
 
 void Session::setInputCallback(char *cbfunc, char *funcargs)
@@ -262,6 +265,9 @@ void Session::setInputCallback(char *cbfunc, char *funcargs)
 
        args.input_callback = dtmf_callback;
        ap = &args;
+
+       switch_channel_set_flag_recursive(channel, CF_QUEUE_TEXT_EVENTS);
+
 }
 
 switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t itype)
index 21855e39806eb91efc4b252ab87de1928c352baf..09bfac596d9ba7f680b1b35352523e4031577b8e 100644 (file)
@@ -688,7 +688,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_lua_load)
        SWITCH_ADD_API(api_interface, "luarun", "run a script", luarun_api_function, "<script>");
        SWITCH_ADD_API(api_interface, "lua", "run a script as an api function", lua_api_function, "<script>");
        SWITCH_ADD_APP(app_interface, "lua", "Launch LUA ivr", "Run a lua ivr on a channel", lua_function, "<script>", 
-                                  SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC);
+                                  SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC | SAF_SUPPORT_TEXT_ONLY);
        SWITCH_ADD_DIALPLAN(dp_interface, "LUA", lua_dialplan_hunt);
 
        SWITCH_ADD_CHAT_APP(chat_app_interface, "lua", "execute a lua script", "execute a lua script", lua_chat_function, "<script>", SCAF_NONE);
index f3ca51cbc20f222f1b3fa79be4a4f39f8ce08161..705b72eb44f2e890b9ce0586361143dd055409fc 100644 (file)
@@ -4967,6 +4967,33 @@ fail:
 }
 
 
+static int _wrap_CoreSession_print(lua_State* L) {
+  int SWIG_arg = 0;
+  CoreSession *arg1 = (CoreSession *) 0 ;
+  char *arg2 = (char *) 0 ;
+  int result;
+  
+  SWIG_check_num_args("CoreSession::print",2,2)
+  if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("CoreSession::print",1,"CoreSession *");
+  if(!SWIG_lua_isnilstring(L,2)) SWIG_fail_arg("CoreSession::print",2,"char *");
+  
+  if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_CoreSession,0))){
+    SWIG_fail_ptr("CoreSession_print",1,SWIGTYPE_p_CoreSession);
+  }
+  
+  arg2 = (char *)lua_tostring(L, 2);
+  result = (int)(arg1)->print(arg2);
+  lua_pushnumber(L, (lua_Number) result); SWIG_arg++;
+  return SWIG_arg;
+  
+  if(0) SWIG_fail;
+  
+fail:
+  lua_error(L);
+  return SWIG_arg;
+}
+
+
 static int _wrap_CoreSession_preAnswer(lua_State* L) {
   int SWIG_arg = 0;
   CoreSession *arg1 = (CoreSession *) 0 ;
@@ -6579,6 +6606,7 @@ delete arg1;
 static swig_lua_method swig_CoreSession_methods[] = {
     {"insertFile", _wrap_CoreSession_insertFile}, 
     {"answer", _wrap_CoreSession_answer}, 
+    {"print", _wrap_CoreSession_print}, 
     {"preAnswer", _wrap_CoreSession_preAnswer}, 
     {"hangup", _wrap_CoreSession_hangup}, 
     {"hangupState", _wrap_CoreSession_hangupState}, 
index 714d8c896d18eac36825e4d090fb7a81db2ab474..197b832a29ebe0c9e20a7fae45be4483d3d49d5e 100644 (file)
@@ -18192,6 +18192,36 @@ result = (char *)("\r\n #%&+:;<=>?@[\\]^`{|}\"");
 }
 
 
+SWIGEXPORT char * SWIGSTDCALL CSharp_switch_get_hex_bytes(void * jarg1, void * jarg2, char * jarg3, void * jarg4) {
+  char * jresult ;
+  switch_byte_t *arg1 = (switch_byte_t *) 0 ;
+  switch_size_t arg2 ;
+  char *arg3 = (char *) 0 ;
+  switch_size_t arg4 ;
+  switch_size_t *argp2 ;
+  switch_size_t *argp4 ;
+  char *result = 0 ;
+  
+  arg1 = (switch_byte_t *)jarg1; 
+  argp2 = (switch_size_t *)jarg2; 
+  if (!argp2) {
+    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_size_t", 0);
+    return 0;
+  }
+  arg2 = *argp2; 
+  arg3 = (char *)jarg3; 
+  argp4 = (switch_size_t *)jarg4; 
+  if (!argp4) {
+    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_size_t", 0);
+    return 0;
+  }
+  arg4 = *argp4; 
+  result = (char *)switch_get_hex_bytes(arg1,arg2,arg3,arg4);
+  jresult = SWIG_csharp_string_callback((const char *)result); 
+  return jresult;
+}
+
+
 SWIGEXPORT unsigned long SWIGSTDCALL CSharp_switch_round_to_step(unsigned long jarg1, unsigned long jarg2) {
   unsigned long jresult ;
   uint32_t arg1 ;
@@ -20858,6 +20888,18 @@ SWIGEXPORT void SWIGSTDCALL CSharp_switch_getcputime(void * jarg1) {
 }
 
 
+SWIGEXPORT char * SWIGSTDCALL CSharp_switch_html_strip(char * jarg1) {
+  char * jresult ;
+  char *arg1 = (char *) 0 ;
+  char *result = 0 ;
+  
+  arg1 = (char *)jarg1; 
+  result = (char *)switch_html_strip((char const *)arg1);
+  jresult = SWIG_csharp_string_callback((const char *)result); 
+  return jresult;
+}
+
+
 SWIGEXPORT void SWIGSTDCALL CSharp_profile_node_t_var_set(void * jarg1, char * jarg2) {
   profile_node_s *arg1 = (profile_node_s *) 0 ;
   char *arg2 = (char *) 0 ;
@@ -47299,6 +47341,20 @@ SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_Answer(void * jarg1) {
 }
 
 
+SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_print(void * jarg1, char * jarg2) {
+  int jresult ;
+  CoreSession *arg1 = (CoreSession *) 0 ;
+  char *arg2 = (char *) 0 ;
+  int result;
+  
+  arg1 = (CoreSession *)jarg1; 
+  arg2 = (char *)jarg2; 
+  result = (int)(arg1)->print(arg2);
+  jresult = result; 
+  return jresult;
+}
+
+
 SWIGEXPORT int SWIGSTDCALL CSharp_CoreSession_preAnswer(void * jarg1) {
   int jresult ;
   CoreSession *arg1 = (CoreSession *) 0 ;
index 042b385d3c89b99f885f1b7019a78973afb33c8a..2b6058927c55c6f86aa3878de82b282a0c1da265 100644 (file)
@@ -303,6 +303,11 @@ public class CoreSession : IDisposable {
     return ret;
   }
 
+  public int print(string txt) {
+    int ret = freeswitchPINVOKE.CoreSession_print(swigCPtr, txt);
+    return ret;
+  }
+
   public int preAnswer() {
     int ret = freeswitchPINVOKE.CoreSession_preAnswer(swigCPtr);
     return ret;
@@ -3745,6 +3750,12 @@ else
     return ret;
   }
 
+  public static string switch_get_hex_bytes(SWIGTYPE_p_unsigned_char buf, SWIGTYPE_p_switch_size_t datalen, string new_buf, SWIGTYPE_p_switch_size_t new_datalen) {
+    string ret = freeswitchPINVOKE.switch_get_hex_bytes(SWIGTYPE_p_unsigned_char.getCPtr(buf), SWIGTYPE_p_switch_size_t.getCPtr(datalen), new_buf, SWIGTYPE_p_switch_size_t.getCPtr(new_datalen));
+    if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve();
+    return ret;
+  }
+
   public static uint switch_round_to_step(uint num, uint step) {
     uint ret = freeswitchPINVOKE.switch_round_to_step(num, step);
     return ret;
@@ -4439,6 +4450,11 @@ else
     freeswitchPINVOKE.switch_getcputime(switch_cputime.getCPtr(t));
   }
 
+  public static string switch_html_strip(string str) {
+    string ret = freeswitchPINVOKE.switch_html_strip(str);
+    return ret;
+  }
+
   public static switch_caller_extension switch_caller_extension_new(SWIGTYPE_p_switch_core_session session, string extension_name, string extension_number) {
     IntPtr cPtr = freeswitchPINVOKE.switch_caller_extension_new(SWIGTYPE_p_switch_core_session.getCPtr(session), extension_name, extension_number);
     switch_caller_extension ret = (cPtr == IntPtr.Zero) ? null : new switch_caller_extension(cPtr, false);
@@ -12416,6 +12432,9 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_SWITCH_URL_UNSAFE_get")]
   public static extern string SWITCH_URL_UNSAFE_get();
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_get_hex_bytes")]
+  public static extern string switch_get_hex_bytes(HandleRef jarg1, HandleRef jarg2, string jarg3, HandleRef jarg4);
+
   [DllImport("mod_managed", EntryPoint="CSharp_switch_round_to_step")]
   public static extern uint switch_round_to_step(uint jarg1, uint jarg2);
 
@@ -12980,6 +12999,9 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_switch_getcputime")]
   public static extern void switch_getcputime(HandleRef jarg1);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_switch_html_strip")]
+  public static extern string switch_html_strip(string jarg1);
+
   [DllImport("mod_managed", EntryPoint="CSharp_profile_node_t_var_set")]
   public static extern void profile_node_t_var_set(HandleRef jarg1, string jarg2);
 
@@ -19355,6 +19377,9 @@ class freeswitchPINVOKE {
   [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_Answer")]
   public static extern int CoreSession_Answer(HandleRef jarg1);
 
+  [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_print")]
+  public static extern int CoreSession_print(HandleRef jarg1, string jarg2);
+
   [DllImport("mod_managed", EntryPoint="CSharp_CoreSession_preAnswer")]
   public static extern int CoreSession_preAnswer(HandleRef jarg1);
 
@@ -27112,7 +27137,8 @@ namespace FreeSWITCH.Native {
   SAF_ROUTING_EXEC = (1 << 1),
   SAF_MEDIA_TAP = (1 << 2),
   SAF_ZOMBIE_EXEC = (1 << 3),
-  SAF_NO_LOOPBACK = (1 << 4)
+  SAF_NO_LOOPBACK = (1 << 4),
+  SAF_SUPPORT_TEXT_ONLY = (1 << 5)
 }
 
 }
@@ -29780,7 +29806,15 @@ public enum switch_channel_flag_t {
   CF_TEXT_ECHO,
   CF_TEXT_ACTIVE,
   CF_TEXT_IDLE,
+  CF_TEXT_LINE_BASED,
+  CF_QUEUE_TEXT_EVENTS,
   CF_MSRP,
+  CF_MSRPS,
+  CF_WANT_MSRP,
+  CF_WANT_MSRPS,
+  CF_RTT,
+  CF_WANT_RTT,
+  CF_AUDIO,
   CF_FLAG_MAX
 }
 
index 6111f48f716734551a1cb75ea64dbc7caa00ca6d..1496b314256c97499b620a93241fbd60ad00b608 100644 (file)
@@ -418,6 +418,7 @@ sub DESTROY {
 *swig_voice_name_set = *freeswitchc::CoreSession_voice_name_set;
 *insertFile = *freeswitchc::CoreSession_insertFile;
 *answer = *freeswitchc::CoreSession_answer;
+*print = *freeswitchc::CoreSession_print;
 *preAnswer = *freeswitchc::CoreSession_preAnswer;
 *hangup = *freeswitchc::CoreSession_hangup;
 *hangupState = *freeswitchc::CoreSession_hangupState;
index 0537a66e4bd691e2e4c29aa9db4b26f0c1896852..91842fa03e7a4a41cb6e2dffce039e21c3bcc2d5 100644 (file)
@@ -5941,6 +5941,45 @@ XS(_wrap_CoreSession_answer) {
 }
 
 
+XS(_wrap_CoreSession_print) {
+  {
+    CoreSession *arg1 = (CoreSession *) 0 ;
+    char *arg2 = (char *) 0 ;
+    void *argp1 = 0 ;
+    int res1 = 0 ;
+    int res2 ;
+    char *buf2 = 0 ;
+    int alloc2 = 0 ;
+    int argvi = 0;
+    int result;
+    dXSARGS;
+    
+    if ((items < 2) || (items > 2)) {
+      SWIG_croak("Usage: CoreSession_print(self,txt);");
+    }
+    res1 = SWIG_ConvertPtr(ST(0), &argp1,SWIGTYPE_p_CoreSession, 0 |  0 );
+    if (!SWIG_IsOK(res1)) {
+      SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession_print" "', argument " "1"" of type '" "CoreSession *""'"); 
+    }
+    arg1 = reinterpret_cast< CoreSession * >(argp1);
+    res2 = SWIG_AsCharPtrAndSize(ST(1), &buf2, NULL, &alloc2);
+    if (!SWIG_IsOK(res2)) {
+      SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CoreSession_print" "', argument " "2"" of type '" "char *""'");
+    }
+    arg2 = reinterpret_cast< char * >(buf2);
+    result = (int)(arg1)->print(arg2);
+    ST(argvi) = SWIG_From_int  SWIG_PERL_CALL_ARGS_1(static_cast< int >(result)); argvi++ ;
+    
+    if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+    XSRETURN(argvi);
+  fail:
+    
+    if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+    SWIG_croak_null();
+  }
+}
+
+
 XS(_wrap_CoreSession_preAnswer) {
   {
     CoreSession *arg1 = (CoreSession *) 0 ;
@@ -10267,6 +10306,7 @@ static swig_command_info swig_commands[] = {
 {"freeswitchc::CoreSession_voice_name_get", _wrap_CoreSession_voice_name_get},
 {"freeswitchc::CoreSession_insertFile", _wrap_CoreSession_insertFile},
 {"freeswitchc::CoreSession_answer", _wrap_CoreSession_answer},
+{"freeswitchc::CoreSession_print", _wrap_CoreSession_print},
 {"freeswitchc::CoreSession_preAnswer", _wrap_CoreSession_preAnswer},
 {"freeswitchc::CoreSession_hangup", _wrap_CoreSession_hangup},
 {"freeswitchc::CoreSession_hangupState", _wrap_CoreSession_hangupState},
index 967e3eb51ee0fcfe73f9f3cd5e268322726097cd..4c9e4dd6b4ec98a700b6724d99cecc7d452f910c 100644 (file)
@@ -317,6 +317,7 @@ class CoreSession(_object):
     if _newclass:voice_name = _swig_property(_freeswitch.CoreSession_voice_name_get, _freeswitch.CoreSession_voice_name_set)
     def insertFile(self, *args): return _freeswitch.CoreSession_insertFile(self, *args)
     def answer(self): return _freeswitch.CoreSession_answer(self)
+    def _print(self, *args): return _freeswitch.CoreSession__print(self, *args)
     def preAnswer(self): return _freeswitch.CoreSession_preAnswer(self)
     def hangup(self, cause="normal_clearing"): return _freeswitch.CoreSession_hangup(self, cause)
     def hangupState(self): return _freeswitch.CoreSession_hangupState(self)
index 3639a0768f46b1f831f92c478533ace21a956e79..ec4b5bbfd16b5dbf8ac5b34fede2fb3d145d6a78 100644 (file)
@@ -6897,6 +6897,40 @@ fail:
 }
 
 
+SWIGINTERN PyObject *_wrap_CoreSession__print(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
+  PyObject *resultobj = 0;
+  CoreSession *arg1 = (CoreSession *) 0 ;
+  char *arg2 = (char *) 0 ;
+  void *argp1 = 0 ;
+  int res1 = 0 ;
+  int res2 ;
+  char *buf2 = 0 ;
+  int alloc2 = 0 ;
+  PyObject * obj0 = 0 ;
+  PyObject * obj1 = 0 ;
+  int result;
+  
+  if (!PyArg_ParseTuple(args,(char *)"OO:CoreSession__print",&obj0,&obj1)) SWIG_fail;
+  res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_CoreSession, 0 |  0 );
+  if (!SWIG_IsOK(res1)) {
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CoreSession__print" "', argument " "1"" of type '" "CoreSession *""'"); 
+  }
+  arg1 = reinterpret_cast< CoreSession * >(argp1);
+  res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "CoreSession__print" "', argument " "2"" of type '" "char *""'");
+  }
+  arg2 = reinterpret_cast< char * >(buf2);
+  result = (int)(arg1)->print(arg2);
+  resultobj = SWIG_From_int(static_cast< int >(result));
+  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  return resultobj;
+fail:
+  if (alloc2 == SWIG_NEWOBJ) delete[] buf2;
+  return NULL;
+}
+
+
 SWIGINTERN PyObject *_wrap_CoreSession_preAnswer(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
   PyObject *resultobj = 0;
   CoreSession *arg1 = (CoreSession *) 0 ;
@@ -10154,6 +10188,7 @@ static PyMethodDef SwigMethods[] = {
         { (char *)"CoreSession_voice_name_get", _wrap_CoreSession_voice_name_get, METH_VARARGS, NULL},
         { (char *)"CoreSession_insertFile", _wrap_CoreSession_insertFile, METH_VARARGS, NULL},
         { (char *)"CoreSession_answer", _wrap_CoreSession_answer, METH_VARARGS, NULL},
+        { (char *)"CoreSession__print", _wrap_CoreSession__print, METH_VARARGS, NULL},
         { (char *)"CoreSession_preAnswer", _wrap_CoreSession_preAnswer, METH_VARARGS, NULL},
         { (char *)"CoreSession_hangup", _wrap_CoreSession_hangup, METH_VARARGS, NULL},
         { (char *)"CoreSession_hangupState", _wrap_CoreSession_hangupState, METH_VARARGS, NULL},
index 9a1ce6d23b0485fe626b0c9dff8851b0887e4ae7..d3fdd052a6133c24bb67d876819f574fdad2f8bf 100644 (file)
@@ -3773,6 +3773,10 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_answered(switch_chan
        
        switch_core_media_check_autoadj(channel->session);
 
+       if (switch_channel_test_flag(channel, CF_RTT)) {
+               switch_channel_set_flag_partner(channel, CF_RTT);
+       }
+
        return SWITCH_STATUS_SUCCESS;
 }
 
@@ -3810,7 +3814,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_answer(switch_channel_t *
        }
 
 
-       if (switch_core_session_in_thread(channel->session) && !switch_channel_test_flag(channel, CF_PROXY_MODE)) {
+       if (switch_core_session_in_thread(channel->session) && !switch_channel_test_flag(channel, CF_PROXY_MODE) && 
+               !switch_channel_test_flag(channel, CF_HAS_TEXT)) {
                const char *delay;
 
                if ((delay = switch_channel_get_variable(channel, "answer_delay"))) {
index d57a9b0e0a6f1416433417bfdaf755659e341a8e..7bc2abe6bba5210e05f2ba101268dd9279673f0c 100644 (file)
@@ -2418,7 +2418,7 @@ static void *get_rtt_payload(void *data, switch_size_t datalen, switch_payload_t
        *new_datalen = datalen - bytes - 1 - (count *4);
        *new_payload = pt;
        buf += bytes + 1;
-       
+
        if (buf > e) {
                *new_datalen = 0;
                return NULL;
@@ -2447,49 +2447,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
                return SWITCH_STATUS_FALSE;
        }
 
-       if (type == SWITCH_MEDIA_TYPE_TEXT && smh->msrp_session) {
-               switch_msrp_session_t *msrp_session = smh->msrp_session;
-               switch_frame_t *rframe = &msrp_session->frame;
-
-               msrp_msg_t *msrp_msg = switch_msrp_session_pop_msg(msrp_session);
-
-               if (0 && msrp_msg && msrp_msg->method == MSRP_METHOD_SEND) { /*echo back*/
-                       char *p;
-                       p = msrp_msg->headers[MSRP_H_TO_PATH];
-                       msrp_msg->headers[MSRP_H_TO_PATH] = msrp_msg->headers[MSRP_H_FROM_PATH];
-                       msrp_msg->headers[MSRP_H_FROM_PATH] = p;
-                       switch_msrp_send(msrp_session, msrp_msg);
-               }
-
-               if (msrp_msg && msrp_msg->method == MSRP_METHOD_SEND) {
-                       rframe->data = msrp_session->frame_data;
-                       rframe->datalen = msrp_msg->payload_bytes;
-                       rframe->packetlen = msrp_msg->payload_bytes;
-                       memcpy(rframe->data, msrp_msg->payload, msrp_msg->payload_bytes);
-                       rframe->m = 1;
-
-                       *frame = rframe;
-
-                       switch_safe_free(msrp_msg);
-                       msrp_msg = NULL;
-                       status = SWITCH_STATUS_SUCCESS;
-
-                       return status;
-               }
-
-               *frame = NULL;
-               status = SWITCH_STATUS_FALSE;
+       engine = &smh->engines[type];
 
-               return status;
+       if (type == SWITCH_MEDIA_TYPE_AUDIO && ! switch_channel_test_flag(session->channel, CF_AUDIO)) {
+               //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Reading audio from a non-audio session.\n");
+               switch_yield(50000);
+               return SWITCH_STATUS_INUSE;
        }
 
-       engine = &smh->engines[type];
-
        if (type != SWITCH_MEDIA_TYPE_TEXT && (!engine->read_codec.implementation || !switch_core_codec_ready(&engine->read_codec))) {
+               switch_yield(50000);
                return SWITCH_STATUS_FALSE;
        }
 
        if (!switch_channel_up_nosig(session->channel) || !switch_rtp_ready(engine->rtp_session) || switch_channel_test_flag(session->channel, CF_NOT_READY)) {
+               switch_yield(50000);
                return SWITCH_STATUS_FALSE;
        }
 
@@ -2511,6 +2483,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_frame(switch_core_session
                engine->read_frame.flags = SFF_NONE;
                status = switch_rtp_zerocopy_read_frame(engine->rtp_session, &engine->read_frame, flags);
 
+
                if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
                        if (status == SWITCH_STATUS_TIMEOUT) {
 
@@ -4108,8 +4081,7 @@ static void clear_pmaps(switch_rtp_engine_t *engine)
 //?
 SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *session, const char *r_sdp, uint8_t *proceed, switch_sdp_type_t sdp_type)
 {
-       uint8_t match = 0;
-       uint8_t vmatch = 0;
+       uint8_t match = 0, vmatch = 0, tmatch = 0, fmatch = 0;
        switch_payload_t best_te = 0, cng_pt = 0;
        unsigned long best_te_rate = 8000, cng_rate = 8000;
        sdp_media_t *m;
@@ -4308,14 +4280,12 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                        got_msrp++;
                }
 
-               if(got_msrp && m->m_type == sdp_media_message) {
+               if (got_msrp && m->m_type == sdp_media_message) {
                        if (!smh->msrp_session) {
                                smh->msrp_session = switch_msrp_session_new(switch_core_session_get_pool(session), m->m_proto == sdp_proto_msrps);
                        }
 
-                       if (!smh->msrp_session) {
-                               goto endmsrp;
-                       }
+                       switch_assert(smh->msrp_session);
 
                        switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "MSRP session created\n");
 
@@ -4390,11 +4360,13 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
 
                        switch_channel_set_flag(session->channel, CF_HAS_TEXT);
                        switch_channel_set_flag(session->channel, CF_TEXT_POSSIBLE);
+                       switch_channel_set_flag(session->channel, CF_TEXT_LINE_BASED);
                        switch_channel_set_flag(session->channel, CF_MSRP);
-
+                       if (m->m_proto == sdp_proto_msrps) {
+                               switch_channel_set_flag(session->channel, CF_MSRPS);
+                       }
                        switch_core_session_start_text_thread(session);
-
-                       endmsrp:;
+                       tmatch = 1;
                }
 
                if (got_udptl && m->m_type == sdp_media_image) {
@@ -4404,7 +4376,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                                switch_t38_options_t *t38_options = switch_core_media_process_udptl(session, sdp, m);
 
                                if (switch_channel_test_app_flag_key("T38", session->channel, CF_APP_T38_NEGOTIATED)) {
-                                       match = 1;
+                                       fmatch = 1;
                                        goto done;
                                }
 
@@ -4508,7 +4480,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
 
 
                                /* do nothing here, mod_fax will trigger a response (if it's listening =/) */
-                               match = 1;
+                               fmatch = 1;
                                goto done;
                        }
                } else if (m->m_type == sdp_media_audio && m->m_port && got_audio && got_savp) {
@@ -5148,11 +5120,12 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                                        smh->mparams->recv_te = smh->mparams->te = 0;
                                }
                        }
-
-               } else if (switch_channel_var_true(session->channel, "rtp_enable_text") && !got_text && m->m_type == sdp_media_text && m->m_port) {
+                       
+               } else if (!got_text && m->m_type == sdp_media_text && m->m_port) {
                        sdp_rtpmap_t *map;
                        payload_map_t *red_pmap = NULL;
 
+                       switch_channel_set_flag(session->channel, CF_RTT);
 
                        connection = sdp->sdp_connection;
                        if (m->m_connections) {
@@ -5189,7 +5162,9 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
 
                                pmap->remote_sdp_ip = switch_core_session_strdup(session, (char *) connection->c_address);
                                pmap->remote_sdp_port = (switch_port_t) m->m_port;
-                               pmap->rm_fmtp = switch_core_session_strdup(session, (char *) mmap->rm_fmtp);
+                               if (map->rm_fmtp) {
+                                       pmap->rm_fmtp = switch_core_session_strdup(session, (char *) map->rm_fmtp);
+                               }
                                
 
                                t_engine->cur_payload_map = pmap;
@@ -5234,6 +5209,8 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                        //t_engine->cur_payload_map = pmap;
 
                        t_engine->codec_negotiated = 1;
+                       tmatch = 1;
+
 
                        if (!t_engine->local_sdp_port) {
                                switch_core_media_choose_port(session, SWITCH_MEDIA_TYPE_TEXT, 1);
@@ -5595,10 +5572,33 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
                switch_channel_set_flag(channel, CF_AUDIO_PAUSE_WRITE);
        }
 
+ done:
 
-       if (!match && vmatch) match = 1;
+       if (match) {
+               switch_channel_set_flag(channel, CF_AUDIO);
+       } else {
+               switch_channel_clear_flag(channel, CF_AUDIO);
+       }
 
- done:
+       if (vmatch) {
+               switch_channel_set_flag(channel, CF_VIDEO);
+       } else {
+               switch_channel_clear_flag(channel, CF_VIDEO);
+               switch_channel_clear_flag(channel, CF_VIDEO_READY);
+               switch_channel_clear_flag(channel, CF_VIDEO_DECODED_READ);
+       }
+
+       if (tmatch) {
+               switch_channel_set_flag(channel, CF_HAS_TEXT);
+       } else {
+               switch_channel_clear_flag(channel, CF_HAS_TEXT);
+       }
+
+       if (fmatch) {
+               switch_channel_set_flag(channel, CF_IMAGE_SDP);
+       } else {
+               switch_channel_clear_flag(channel, CF_IMAGE_SDP);
+       }
 
        if (parser) {
                sdp_parser_free(parser);
@@ -5607,7 +5607,7 @@ SWITCH_DECLARE(uint8_t) switch_core_media_negotiate_sdp(switch_core_session_t *s
        smh->mparams->cng_pt = cng_pt;
        smh->mparams->cng_rate = cng_rate;
 
-       return match;
+       return match || vmatch || tmatch || fmatch;
 }
 
 //?
@@ -7811,9 +7811,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi
                
        text:
 
-               if (switch_channel_test_flag(session->channel, CF_MSRP)) { // skip RTP RTT
-                       goto video;
-               }
+               //if (switch_channel_test_flag(session->channel, CF_MSRP)) { // skip RTP RTT
+               //      goto video;
+               //}
 
                if (switch_channel_test_flag(session->channel, CF_TEXT_POSSIBLE) && t_engine->cur_payload_map->rm_encoding && t_engine->cur_payload_map->remote_sdp_port) {
                        /******************************************************************************************/
@@ -10050,8 +10050,40 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
 
        }
 
-msrp:
+       if (switch_channel_test_cap(session->channel, CC_MSRP) && !smh->msrp_session) {
+               int want_msrp = switch_channel_var_true(session->channel, "sip_enable_msrp");
+               int want_msrps = switch_channel_var_true(session->channel, "sip_enable_msrps");
+
+               if (!want_msrp) {
+                       want_msrp = switch_channel_test_flag(session->channel, CF_WANT_MSRP);
+               }
+
+               if (!want_msrps) {
+                       want_msrps = switch_channel_test_flag(session->channel, CF_WANT_MSRPS);
+               }
+       
+               if (want_msrp || want_msrps) {
+                       smh->msrp_session = switch_msrp_session_new(switch_core_session_get_pool(session), want_msrps);
+
+                       switch_assert(smh->msrp_session);
+
+
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "MSRP session created\n");
+
+                       smh->msrp_session->call_id = switch_core_session_get_uuid(session);
+
+                       switch_channel_set_flag(session->channel, CF_HAS_TEXT);
+                       switch_channel_set_flag(session->channel, CF_TEXT_POSSIBLE);
+                       switch_channel_set_flag(session->channel, CF_MSRP);
+
+                       if (want_msrps) {
+                               switch_channel_set_flag(session->channel, CF_MSRPS);
+                       }
 
+                       switch_core_session_start_text_thread(session);
+               }
+       }
+       
        if (smh->msrp_session) {
                switch_msrp_session_t *msrp_session = smh->msrp_session;
 
@@ -10100,37 +10132,11 @@ msrp:
                                        "a=sendonly\na=file-selector:%s\n", file_selector);
                        }
                }
-
-               goto no_rtt;
-       } else if (switch_channel_test_cap(session->channel, CC_RTP_RTT) && (
-               // switch_channel_test_flag(session->channel, CF_TEXT_POSSIBLE) ||
-               switch_channel_var_true(session->channel, "sip_enable_msrp") ||
-               switch_channel_var_true(session->channel, "sip_enable_msrps"))) {
-
-               smh->msrp_session = switch_msrp_session_new(switch_core_session_get_pool(session), switch_channel_var_true(session->channel, "sip_enable_msrps"));
-
-               if (!smh->msrp_session) {
-                       goto endmsrp;
-               }
-
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "MSRP session created\n");
-
-               smh->msrp_session->call_id = switch_core_session_get_uuid(session);
-
-               switch_channel_set_flag(session->channel, CF_HAS_TEXT);
-               switch_channel_set_flag(session->channel, CF_TEXT_POSSIBLE);
-               switch_channel_set_flag(session->channel, CF_MSRP);
-
-               switch_core_session_start_text_thread(session);
-
-               goto msrp;
-
-               endmsrp: ;
-       }
+       } 
 
        // RTP TEXT
 
-       if (sdp_type == SDP_TYPE_RESPONSE && !switch_channel_test_flag(session->channel, CF_TEXT_POSSIBLE)) {
+       if (sdp_type == SDP_TYPE_RESPONSE && !switch_channel_test_flag(session->channel, CF_RTT)) {
                if (switch_channel_test_flag(session->channel, CF_TEXT_SDP_RECVD)) {
                        switch_channel_clear_flag(session->channel, CF_TEXT_SDP_RECVD);
                        switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "m=text 0 %s 19\r\n", 
@@ -10139,11 +10145,11 @@ msrp:
                                                                                                        && switch_channel_direction(session->channel) == SWITCH_CALL_DIRECTION_OUTBOUND) || 
                                                                                                   a_engine->crypto_type != CRYPTO_INVALID || switch_channel_test_flag(session->channel, CF_DTLS)));
                }
-       } else if ((switch_channel_test_flag(session->channel, CF_TEXT_POSSIBLE) || switch_channel_var_true(session->channel, "rtp_enable_text")) &&
+       } else if ((switch_channel_test_flag(session->channel, CF_WANT_RTT) || switch_channel_test_flag(session->channel, CF_RTT) || 
+                               switch_channel_var_true(session->channel, "rtp_enable_text")) &&
                           switch_channel_test_cap(session->channel, CC_RTP_RTT)) {
                t_engine->t140_pt = 0;
                t_engine->red_pt = 0;
-               
 
                if (sdp_type == SDP_TYPE_REQUEST) {
                        t_engine->t140_pt = 96;
@@ -10389,8 +10395,6 @@ msrp:
 
        }
 
-       no_rtt:
-
        if (map) {
                switch_event_destroy(&map);
        }
@@ -13780,7 +13784,44 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_text_frame(switch_core_
                }
        }
 
-       if (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK) {
+       if (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK) {         
+               if (switch_channel_test_flag(session->channel, CF_QUEUE_TEXT_EVENTS) && (*frame)->datalen && !switch_test_flag((*frame), SFF_CNG)) {
+                       int ok = 1;
+                       switch_event_t *event;
+                       void *data = (*frame)->data;
+                       char eof[1] = {'\0'};
+
+                       //uint32_t datalen = (*frame)->datalen;
+
+                       if (!switch_channel_test_flag(session->channel, CF_TEXT_LINE_BASED)) {
+                               if (!session->text_line_buffer) {
+                                       switch_buffer_create_dynamic(&session->text_line_buffer, 512, 1024, 0);
+                               }
+                               switch_buffer_write(session->text_line_buffer, (*frame)->data, (*frame)->datalen);
+                               
+                               
+                               if (switch_channel_test_flag(session->channel, CF_TEXT_IDLE) || switch_test_flag((*frame), SFF_TEXT_LINE_BREAK)) {
+                                       switch_buffer_write(session->text_line_buffer, eof, 1);
+                                       data = switch_buffer_get_head_pointer(session->text_line_buffer);
+                                       //datalen = strlen((char *)smh->line_text_frame.data);
+                               } else {
+                                       ok = 0;
+                               }
+                       }
+
+
+                       if (ok) {
+                               if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
+                                       switch_channel_event_set_extended_data(session->channel, event);
+
+                                       switch_event_add_body(event, (char *)data);
+                                       switch_core_session_queue_event(session, &event);
+                               }
+                               if (session->text_line_buffer) {
+                                       switch_buffer_zero(session->text_line_buffer);
+                               }
+                       }
+               }
                switch_core_session_text_read_callback(session, *frame);
        }
 
@@ -13789,7 +13830,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_text_frame(switch_core_
        return status;
 }
 
-
 static void build_red_packet(switch_rtp_engine_t *t_engine)
 {
        int pos;
@@ -13833,10 +13873,8 @@ static void build_red_packet(switch_rtp_engine_t *t_engine)
                if (pos == t_engine->tf->red_max) pos = 0;
        }
 
-
+       
        plen = ((loops - 1) * 4) + 1;
-
-
        pos = t_engine->tf->red_pos + 1;
        
        if (pos == t_engine->tf->red_max) pos = 0;
@@ -13942,8 +13980,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_text_frame(switch_core
                        *(t_engine->tf->red_buf[t_engine->tf->red_pos] + t_engine->tf->red_buflen[t_engine->tf->red_pos]) = '\0';
 
                        build_red_packet(t_engine);
-               
-               
                } else {
                        frame->datalen = switch_buffer_read(t_engine->tf->write_buffer, t_engine->tf->text_write_frame.data, RED_PACKET_SIZE);
                        frame->payload = t_engine->t140_pt;
@@ -13991,21 +14027,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_printf(switch_core_session_t
        int ret = 0;
        va_list ap;
        switch_frame_t frame = { 0 };
-       switch_rtp_engine_t *t_engine;
-       switch_media_handle_t *smh;
        unsigned char CR[] = TEXT_UNICODE_LINEFEED;
 
-       if (!(smh = session->media_handle)) {
-               return SWITCH_STATUS_FALSE;
-       }               
-
-       t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
-       
-       if (!switch_rtp_ready(t_engine->rtp_session)) {
-               return SWITCH_STATUS_NOTIMPL;
-       }
-
-
        va_start(ap, fmt);
        ret = switch_vasprintf(&data, fmt, ap);
        va_end(ap);
@@ -14014,7 +14037,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_printf(switch_core_session_t
                abort();
        }
 
-
        frame.data = data;
        frame.datalen = strlen(data);
        
@@ -14034,19 +14056,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_printf(switch_core_session_t
 SWITCH_DECLARE(switch_status_t) switch_core_session_print(switch_core_session_t *session, const char *data)
 {
        switch_frame_t frame = { 0 };
-       //switch_rtp_engine_t *t_engine;
-       //switch_media_handle_t *smh;
-
-       //if (!(smh = session->media_handle)) {
-       //      return SWITCH_STATUS_FALSE;
-       //}               
-
-       //t_engine = &smh->engines[SWITCH_MEDIA_TYPE_TEXT];
-       
-       //if (!switch_rtp_ready(t_engine->rtp_session)) {
-       //      return SWITCH_STATUS_NOTIMPL;
-       //}
-
 
        if (!switch_channel_test_flag(session->channel, CF_HAS_TEXT)) {
                return SWITCH_STATUS_NOTIMPL;
@@ -14054,7 +14063,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_print(switch_core_session_t
 
        frame.data = (char *) data;
        frame.datalen = strlen(data);
-       
+
        switch_core_session_write_text_frame(session, &frame, 0, 0);
 
        return SWITCH_STATUS_SUCCESS;
index 240da2388618084903357cee054706adf40c88e9..2e84dd7b5ed7dd6690cb667c19bc5213574504dd 100644 (file)
@@ -671,6 +671,18 @@ SWITCH_DECLARE(switch_call_cause_t) switch_core_session_outgoing_channel(switch_
                                switch_channel_set_variable(peer_channel, SWITCH_ORIGINATOR_CODEC_VARIABLE, ep);
                        }
 
+                       
+                       if (switch_channel_test_flag(channel, CF_MSRPS)) {
+                               switch_channel_set_flag(peer_channel, CF_WANT_MSRPS);
+                       } else if (switch_channel_test_flag(channel, CF_MSRP)) {
+                               switch_channel_set_flag(peer_channel, CF_WANT_MSRP);
+                       }
+
+                       if (switch_channel_test_flag(channel, CF_RTT)) {
+                               switch_channel_set_flag(peer_channel, CF_WANT_RTT);
+                       }
+
+
                        switch_channel_set_variable(peer_channel, SWITCH_ORIGINATOR_VARIABLE, switch_core_session_get_uuid(session));
                        switch_channel_set_variable(peer_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(session));
                        // Needed by 3PCC proxy so that aleg can find bleg to pass SDP to, when final ACK arrives.
@@ -1499,6 +1511,10 @@ SWITCH_DECLARE(void) switch_core_session_perform_destroy(switch_core_session_t *
                switch_buffer_destroy(&(*session)->text_buffer);
        }
 
+       if ((*session)->text_line_buffer) {
+               switch_buffer_destroy(&(*session)->text_line_buffer);
+       }
+
        switch_core_session_reset(*session, SWITCH_TRUE, SWITCH_TRUE);
 
        switch_core_media_bug_remove_all(*session);
@@ -2659,6 +2675,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_execute_application_get_flag
                *flags = application_interface->flags;
        }
 
+       if (switch_channel_text_only(session->channel) && 
+               !switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA) && 
+               !switch_test_flag(application_interface, SAF_SUPPORT_TEXT_ONLY)) {
+               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Application %s does not support text-only mode on channel %s!\n",
+                                                 app, switch_channel_get_name(session->channel));
+               switch_channel_hangup(session->channel, SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED);
+               switch_goto_status(SWITCH_STATUS_FALSE, done);
+       }
+
        if (!switch_test_flag(application_interface, SAF_SUPPORT_NOMEDIA) && (switch_channel_test_flag(session->channel, CF_VIDEO))) {
                switch_core_session_request_video_refresh(session);
        }
index 4c120aad1d7f09dbb6e81260648d1bfcf6fd2a6d..038a0df6519df27ab4c78592aacd13ea3fddc80c 100644 (file)
@@ -379,7 +379,7 @@ SWITCH_DECLARE(const char *)Event::serialize(const char *format)
                return serialized_string;
        } else {
                if (switch_event_serialize(event, &serialized_string, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
-                       char *new_serialized_string = switch_mprintf("'%s'", serialized_string);
+                       char *new_serialized_string = switch_mprintf("%s", serialized_string);
                        free(serialized_string);
                        serialized_string = new_serialized_string;
                        return serialized_string;
@@ -687,6 +687,16 @@ SWITCH_DECLARE(int) CoreSession::answer()
     return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
 }
 
+
+SWITCH_DECLARE(int) CoreSession::print(char *txt)
+{
+    switch_status_t status;
+       status = switch_core_session_print(session, switch_str_nil(txt));
+       this_check(-1);
+       sanity_check(-1);
+    return status == SWITCH_STATUS_SUCCESS ? 1 : 0;
+}
+
 SWITCH_DECLARE(int) CoreSession::insertFile(const char *file, const char *insert_file, int sample_point)
 {
     switch_status_t status;
@@ -1357,6 +1367,7 @@ SWITCH_DECLARE(void) console_log(char *level_str, char *msg)
                        level = SWITCH_LOG_DEBUG;
                }
     }
+
     switch_log_printf(SWITCH_CHANNEL_LOG, level, "%s", switch_str_nil(msg));
 }
 
index ae3b38a990ed87f324560115421d4934597ffd2c..4a169f93f8c98675982a6ed71f913b29adc1aabd 100644 (file)
@@ -53,20 +53,90 @@ static void text_bridge_thread(switch_core_session_t *session, void *obj)
        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);
+       switch_buffer_t *text_buffer = NULL;
+       switch_size_t text_framesize = 1024, inuse = 0;
+       unsigned char *text_framedata = NULL;
+       switch_frame_t frame = { 0 };
+
+       switch_buffer_create_dynamic(&text_buffer, 512, 1024, 0);
+       switch_zmalloc(text_framedata, 1024);
+       text_framesize = 1024;
 
        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);
+               if (!SWITCH_READ_ACCEPTABLE(status)) {
+                       switch_core_session_write_text_frame(vh->session_a, NULL, 0, 0);
+                       continue;
                }
 
+               if (!switch_channel_test_flag(channel, CF_TEXT_LINE_BASED) && switch_channel_test_flag(b_channel, CF_TEXT_LINE_BASED)) {
+                       if (read_frame->data && read_frame->datalen && !switch_test_flag(read_frame, SFF_CNG)) {
+                               switch_buffer_write(text_buffer, read_frame->data, read_frame->datalen);
+                       }
+                       
+                       inuse = switch_buffer_inuse(text_buffer);
+
+                       if (inuse && (switch_channel_test_flag(channel, CF_TEXT_IDLE) || switch_test_flag(read_frame, SFF_TEXT_LINE_BREAK))) {
+                               int bytes = 0;
+                               
+                               if (inuse + 4 > text_framesize) {
+                                       void *tmp = malloc(inuse + 1024);
+
+                                       memcpy(tmp, text_framedata, text_framesize);
+
+                                       switch_assert(tmp);
+                       
+                                       text_framesize = inuse + 1024;
+                                       
+                                       free(text_framedata);
+                                       text_framedata = tmp;
+                               }
+
+                               bytes = switch_buffer_read(text_buffer, text_framedata, inuse);
+
+                               /* need to strip the unicode line feed because Blink ignores the message, need to see if that is a thing with other msrp clients */
+                               if (switch_test_flag(read_frame, SFF_TEXT_LINE_BREAK)) {
+                                       int x;
+
+                                       for (x = 0; x < bytes - 2; x++) {
+                                               if (text_framedata[x] == 0xe2 && text_framedata[x+1] == 0x80 && text_framedata[x+2] == 0xa8) {
+                                                       text_framedata[x] = '\0';
+                                                       bytes = strlen((char *)text_framedata);
+                                                       break;
+                                               } 
+                                       }
+                               }
+
+                               if (!bytes) continue;
+
+                               *(text_framedata + bytes) = '\r'; 
+                               *(text_framedata + bytes + 1) = '\n'; 
+                               *(text_framedata + bytes + 2) = '\0'; 
+                               bytes += 2;
+                               
+                               frame.data = text_framedata;
+                               frame.datalen = strlen((char *)frame.data);
+                               read_frame = &frame;
+
+                       } else {
+                               continue;
+                       }
+
+               }
+               
+               if (!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;
+
+       switch_buffer_destroy(&text_buffer);
+       switch_safe_free(text_framedata);
 }
 
 
@@ -688,6 +758,12 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj)
                }
 #endif
 
+               if (!switch_channel_test_flag(chan_a, CF_AUDIO)) {
+                       switch_ivr_sleep(session_a, 5000, SWITCH_FALSE, NULL);
+                       continue;
+               }
+                       
+
                /* read audio from 1 channel and write it to the other */
                status = switch_core_session_read_frame(session_a, &read_frame, SWITCH_IO_FLAG_NONE, stream_id);
 
@@ -1615,6 +1691,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_multi_threaded_bridge(switch_core_ses
                        switch_channel_set_private(peer_channel, "_bridge_", b_leg);
                        switch_channel_set_state(peer_channel, CS_EXCHANGE_MEDIA);
 
+
                        audio_bridge_thread(NULL, (void *) a_leg);
 
                        switch_channel_clear_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR);
index d31b5bd4b8506ecf0d1ac0c52165ba80a224a8c7..8832dd741b124669a3e7071850cedc78c95a1923 100644 (file)
@@ -319,6 +319,12 @@ SWITCH_DECLARE(switch_status_t) switch_msrp_session_destroy(switch_msrp_session_
 switch_status_t switch_msrp_session_push_msg(switch_msrp_session_t *ms, msrp_msg_t *msg)
 {
        switch_mutex_lock(ms->mutex);
+
+       if (msg->payload && msg->payload_bytes) { /* add NULL byte */
+               *((char *)msg->payload + msg->payload_bytes) = '\0';
+               msg->payload_bytes++;
+       }
+       
        if (ms->last_msg == NULL) {
                ms->last_msg = msg;
                ms->msrp_msg = msg;
index 9ffff39300466759155b1d6286ad94e463de8269..160756acbaa959dfd9f16ab6893a2df15c44e00f 100644 (file)
@@ -42,6 +42,7 @@
 #endif
 #include "private/switch_core_pvt.h"
 #define ESCAPE_META '\\'
+#include "gumbo.h"
 
 struct switch_network_node {
        ip_t ip;
@@ -4207,6 +4208,102 @@ SWITCH_DECLARE(void) switch_getcputime(switch_cputime *t)
 }
 
 
+#ifdef SWITCH_HAVE_GUMBO
+static void process(GumboNode *node, switch_stream_handle_t *stream)
+{
+       if (node->type == GUMBO_NODE_TEXT) {
+               stream->write_function(stream, "%s", node->v.text.text);
+               return;
+       } else if (node->type == GUMBO_NODE_ELEMENT && node->v.element.tag != GUMBO_TAG_SCRIPT && node->v.element.tag != GUMBO_TAG_STYLE) {
+               GumboVector *children = &node->v.element.children;
+               int i;
+               
+               if (node->v.element.tag != GUMBO_TAG_UNKNOWN && node->v.element.tag <= GUMBO_TAG_LAST) {
+                       GumboAttribute* attr = NULL;
+                       const char *aval = NULL;
+                       
+                       if (node->v.element.tag == GUMBO_TAG_SPAN) {
+                               if ((attr = gumbo_get_attribute(&node->v.element.attributes, "class"))) {
+                                       aval = attr->value;
+                               }
+                       }
+
+                       if (aval && !strcasecmp(aval, "Apple-converted-space")) {
+                               const char *txt = ((GumboNode*)children->data[0])->v.text.text;
+                               int x, len = 0;
+
+                               for (x = 0; txt[x]; x++) {
+                                       if (txt[x] == ' ') {
+                                               len++;
+                                       }
+                               }
+                               
+                               for (x = 0; x < len*2; x++) {
+                                       stream->write_function(stream, "%s", " ");
+                               }
+                       } else {
+                               for (i = 0; i < children->length; ++i) {
+                                       process((GumboNode*) children->data[i], stream);                                
+                               }
+                       }
+
+                       if (node->v.element.tag == GUMBO_TAG_P || node->v.element.tag == GUMBO_TAG_BR) {
+                               stream->write_function(stream, "%s", "\n");
+                       }
+
+               }
+       }
+}
+#endif
+
+SWITCH_DECLARE(char *)switch_html_strip(const char *str)
+{
+       char *p, *html = NULL, *text = NULL;
+       int x = 0, got_ct = 0;
+#ifdef SWITCH_HAVE_GUMBO
+       GumboOutput *output;
+       switch_stream_handle_t stream;
+
+       SWITCH_STANDARD_STREAM(stream);
+#endif
+
+       for(p = (char *)str; p && *p; p++) {
+
+               if (!strncasecmp(p, "Content-Type:", 13)) {
+                       got_ct++;
+               }
+               
+               if (!got_ct) continue;
+
+               if (*p == '\n') {
+                       x++;
+                       if (x == 2) {
+                               break;
+                       }
+               } else if (x && (*p != '\r')) {
+                       x = 0;
+               }
+       }
+
+       html = p;
+
+#ifdef SWITCH_HAVE_GUMBO
+       if ((output = gumbo_parse_with_options(&kGumboDefaultOptions, html, strlen(html)))) {
+               process(output->root, &stream);
+               gumbo_destroy_output(&kGumboDefaultOptions, output);
+       }
+
+       text = (char *)stream.data;
+#else
+       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Support for html parser is not compiled.\n");
+       text = strdup(html);
+#endif
+
+       return text;
+}
+
+
+
 /* For Emacs:
  * Local Variables:
  * mode:c