[commit] r1743 - in freeswitch/branches/stkn: . conf libs/libdingaling/src src src/include src/mod/applications/mod_commands src/mod/applications/mod_rss src/mod/codecs/mod_g711 src/mod/codecs/mod_g729 src/mod/codecs/mod_gsm src/mod/codecs/mod_ilbc src/mod/codecs/mod_l16 src/mod/codecs/mod_speex src/mod/endpoints/mod_dingaling src/mod/endpoints/mod_exosip src/mod/endpoints/mod_iax src/mod/endpoints/mod_portaudio src/mod/endpoints/mod_wanpipe src/mod/endpoints/mod_woomera
Author: stkn Date: Mon Jul 3 21:47:59 2006 New Revision: 1743 Modified: freeswitch/branches/stkn/AUTHORS freeswitch/branches/stkn/conf/freeswitch.xml freeswitch/branches/stkn/libs/libdingaling/src/libdingaling.c freeswitch/branches/stkn/libs/libdingaling/src/libdingaling.h freeswitch/branches/stkn/src/include/switch_module_interfaces.h freeswitch/branches/stkn/src/include/switch_utils.h freeswitch/branches/stkn/src/mod/applications/mod_commands/mod_commands.c freeswitch/branches/stkn/src/mod/applications/mod_rss/mod_rss.c freeswitch/branches/stkn/src/mod/codecs/mod_g711/mod_g711.c freeswitch/branches/stkn/src/mod/codecs/mod_g729/mod_g729.c freeswitch/branches/stkn/src/mod/codecs/mod_gsm/mod_gsm.c freeswitch/branches/stkn/src/mod/codecs/mod_ilbc/mod_ilbc.c freeswitch/branches/stkn/src/mod/codecs/mod_l16/mod_l16.c freeswitch/branches/stkn/src/mod/codecs/mod_speex/mod_speex.c freeswitch/branches/stkn/src/mod/endpoints/mod_dingaling/mod_dingaling.c freeswitch/branches/stkn/src/mod/endpoints/mod_exosip/mod_exosip.c freeswitch/branches/stkn/src/mod/endpoints/mod_iax/mod_iax.c freeswitch/branches/stkn/src/mod/endpoints/mod_portaudio/mod_portaudio.c freeswitch/branches/stkn/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c freeswitch/branches/stkn/src/mod/endpoints/mod_woomera/mod_woomera.c freeswitch/branches/stkn/src/switch.c freeswitch/branches/stkn/src/switch_channel.c freeswitch/branches/stkn/src/switch_core.c freeswitch/branches/stkn/src/switch_ivr.c freeswitch/branches/stkn/src/switch_loadable_module.c freeswitch/branches/stkn/src/switch_rtp.c freeswitch/branches/stkn/src/switch_xml.c Log: Update branch Modified: freeswitch/branches/stkn/AUTHORS ============================================================================== --- freeswitch/branches/stkn/AUTHORS (original) +++ freeswitch/branches/stkn/AUTHORS Mon Jul 3 21:47:59 2006 @@ -21,6 +21,7 @@ and moral support. Michal "cypromis" Bielicki (michal.bielicki AT halo2.pl) - Solaris porting, and autotools enhancements. James Martelletti <james@nerdc0re.com> - All around cool guy (mod_syslog) + Johny Kadarisman <jkr888@gmail.com> A big THANK YOU goes to: Modified: freeswitch/branches/stkn/conf/freeswitch.xml ============================================================================== --- freeswitch/branches/stkn/conf/freeswitch.xml (original) +++ freeswitch/branches/stkn/conf/freeswitch.xml Mon Jul 3 21:47:59 2006 @@ -275,7 +275,7 @@ <!-- *NOTE* The special context name 'any' will match any context --> <context name="default"> <extension name="tollfree"> - <condition field="destination_number" expression="^(18[0{2}8{2}7{2}6{2}].*)$"> + <condition field="destination_number" expression="^(18[0{2}8{2}7{2}6{2}]\d{7})"> <action application="bridge" data="exosip/$1-freeswitch@voip.trxtel.com"/> </condition> </extension> Modified: freeswitch/branches/stkn/libs/libdingaling/src/libdingaling.c ============================================================================== --- freeswitch/branches/stkn/libs/libdingaling/src/libdingaling.c (original) +++ freeswitch/branches/stkn/libs/libdingaling/src/libdingaling.c Mon Jul 3 21:47:59 2006 @@ -549,7 +549,7 @@ handle->features = iks_stream_features(node); if (opt_use_tls && !iks_is_secure(handle->parser)) break; - if (ldl_test_flag(handle, LDL_FLAG_AUTHORIZED)) { + if (ldl_test_flag(handle, LDL_FLAG_CONNECTED)) { iks *t; if (handle->features & IKS_STREAM_BIND) { t = iks_make_resource_bind(handle->acc); @@ -576,14 +576,22 @@ } } else if (strcmp("success", iks_name(node)) == 0) { globals.logger(DL_LOG_DEBUG, "XMPP server connected\n"); + iks_send_header(handle->parser, handle->acc->server); + ldl_set_flag(handle, LDL_FLAG_CONNECTED); if (handle->session_callback) { - handle->session_callback(handle, NULL, LDL_SIGNAL_LOGIN_SUCCESS, "core", "Login Success", handle->login); + handle->session_callback(handle, NULL, LDL_SIGNAL_CONNECTED, "core", "Server Connected", handle->login); } - iks_send_header(handle->parser, handle->acc->server); - ldl_set_flag(handle, LDL_FLAG_AUTHORIZED); } else { ikspak *pak; + if (!ldl_test_flag(handle, LDL_FLAG_AUTHORIZED)) { + if (handle->session_callback) { + handle->session_callback(handle, NULL, LDL_SIGNAL_LOGIN_SUCCESS, "core", "Login Success", handle->login); + } + globals.logger(DL_LOG_DEBUG, "XMPP authenticated\n"); + ldl_set_flag(handle, LDL_FLAG_AUTHORIZED); + } + pak = iks_packet(node); iks_filter_packet(handle->filter, pak); if (handle->job_done == 1) @@ -803,7 +811,7 @@ ldl_flush_queue(handle); } - if (!ldl_test_flag(handle, LDL_FLAG_AUTHORIZED)) { + if (!ldl_test_flag(handle, LDL_FLAG_CONNECTED)) { if (IKS_NET_TLSFAIL == e) { globals.logger(DL_LOG_DEBUG, "tls handshake failed\n"); microsleep(500); @@ -820,6 +828,7 @@ iks_disconnect(handle->parser); iks_parser_delete(handle->parser); + ldl_clear_flag(handle, LDL_FLAG_CONNECTED); ldl_clear_flag(handle, LDL_FLAG_AUTHORIZED); } Modified: freeswitch/branches/stkn/libs/libdingaling/src/libdingaling.h ============================================================================== --- freeswitch/branches/stkn/libs/libdingaling/src/libdingaling.h (original) +++ freeswitch/branches/stkn/libs/libdingaling/src/libdingaling.h Mon Jul 3 21:47:59 2006 @@ -99,7 +99,8 @@ LDL_FLAG_INIT = (1 << 0), LDL_FLAG_RUNNING = (1 << 1), LDL_FLAG_AUTHORIZED = (1 << 2), - LDL_FLAG_READY = (1 << 3) + LDL_FLAG_READY = (1 << 3), + LDL_FLAG_CONNECTED = (1 << 4) } ldl_flag_t; typedef enum { @@ -111,6 +112,7 @@ LDL_SIGNAL_ERROR, LDL_SIGNAL_LOGIN_SUCCESS, LDL_SIGNAL_LOGIN_FAILURE, + LDL_SIGNAL_CONNECTED } ldl_signal_t; typedef enum { Modified: freeswitch/branches/stkn/src/include/switch_module_interfaces.h ============================================================================== --- freeswitch/branches/stkn/src/include/switch_module_interfaces.h (original) +++ freeswitch/branches/stkn/src/include/switch_module_interfaces.h Mon Jul 3 21:47:59 2006 @@ -444,6 +444,10 @@ /*! \brief A table of settings and callbacks that define a paticular implementation of a codec */ struct switch_codec_implementation { + /*! the IANA code number */ + switch_payload_t ianacode; + /*! the IANA code name */ + char *iananame; /*! samples transferred per second */ uint32_t samples_per_second; /*! bits transferred per second */ @@ -495,10 +499,6 @@ const char *interface_name; /*! enumeration defining the type of the codec */ const switch_codec_type_t codec_type; - /*! the IANA code number */ - switch_payload_t ianacode; - /*! the IANA code name */ - char *iananame; /*! a list of codec implementations related to the codec */ const switch_codec_implementation_t *implementations; const struct switch_codec_interface *next; Modified: freeswitch/branches/stkn/src/include/switch_utils.h ============================================================================== --- freeswitch/branches/stkn/src/include/switch_utils.h (original) +++ freeswitch/branches/stkn/src/include/switch_utils.h Mon Jul 3 21:47:59 2006 @@ -113,7 +113,24 @@ #define switch_set_flag(obj, flag) (obj)->flags |= (flag) /*! + \brief Set a flag on an arbitrary object while locked + \param obj the object to set the flags on + \param flag the or'd list of flags to set +*/ +#define switch_set_flag_locked(obj, flag) assert(obj->flag_mutex != NULL);\ +switch_mutex_lock(obj->flag_mutex);\ +(obj)->flags |= (flag);\ +switch_mutex_unlock(obj->flag_mutex); + +/*! \brief Clear a flag on an arbitrary object + \param obj the object to test + \param flag the or'd list of flags to clear +*/ +#define switch_clear_flag_locked(obj, flag) switch_mutex_lock(obj->flag_mutex); (obj)->flags &= ~(flag); switch_mutex_unlock(obj->flag_mutex); + +/*! + \brief Clear a flag on an arbitrary object while locked \param obj the object to test \param flag the or'd list of flags to clear */ Modified: freeswitch/branches/stkn/src/mod/applications/mod_commands/mod_commands.c ============================================================================== --- freeswitch/branches/stkn/src/mod/applications/mod_commands/mod_commands.c (original) +++ freeswitch/branches/stkn/src/mod/applications/mod_commands/mod_commands.c Mon Jul 3 21:47:59 2006 @@ -24,6 +24,8 @@ * Contributor(s): * * Anthony Minessale II <anthmct@yahoo.com> + * Michael Jerris <mike@jerris.com> + * Johny Kadarisman <jkr888@gmail.com> * * * mod_commands.c -- Misc. Command Module @@ -185,7 +187,7 @@ static int show_callback(void *pArg, int argc, char **argv, char **columnNames){ switch_stream_handle_t *stream = (switch_stream_handle_t *) pArg; - stream->write_function(stream, "%s\n", argv[1]); + stream->write_function(stream, "%s|%s\n", argv[0], argv[1] ? argv[1] : "NULL"); return 0; } @@ -196,7 +198,22 @@ char *errmsg; switch_core_db_t *db = switch_core_db_handle(); - sprintf (sql, "select * from interfaces"); + if (!cmd) { + sprintf (sql, "select * from interfaces"); + } + else if ( !strcmp(cmd,"codec") || !strcmp(cmd,"application") || + !strcmp(cmd,"api") || !strcmp(cmd,"dialplan") || + !strcmp(cmd,"file") || !strcmp(cmd,"timer") + ) { + sprintf (sql, "select * from interfaces where type = '%s'", cmd); + } + else { + stream->write_function(stream, "Invalid interfaces type!\n"); + stream->write_function(stream, "Example:\n"); + stream->write_function(stream, "show <blank>|codec|application|api|dialplan|file|timer\n"); + return SWITCH_STATUS_SUCCESS; + } + switch_core_db_exec(db, sql, show_callback, stream, &errmsg); if (errmsg) { Modified: freeswitch/branches/stkn/src/mod/applications/mod_rss/mod_rss.c ============================================================================== --- freeswitch/branches/stkn/src/mod/applications/mod_rss/mod_rss.c (original) +++ freeswitch/branches/stkn/src/mod/applications/mod_rss/mod_rss.c Mon Jul 3 21:47:59 2006 @@ -53,6 +53,8 @@ #define TTS_DEFAULT_ENGINE "cepstral" #define TTS_DEFAULT_VOICE "david" +#define MATCH_COUNT + struct rss_entry { uint8_t inuse; char *title_txt; @@ -66,12 +68,11 @@ { char tstr[80] = ""; uint32_t matches = 0, x = 0; - uint32_t len = strlen(str); - printf("%s\n", str); + uint32_t len = (uint32_t)strlen(str); + for (x = 0; x < max ; x++) { snprintf(tstr, sizeof(tstr), "%u", x); if (!strncasecmp(str, tstr, len)) { - printf("match %s=%s\n", str, tstr); matches++; } } @@ -291,16 +292,24 @@ if (jumpto > -1) { snprintf(cmd, sizeof(cmd), "%d", jumpto); + jumpto = -1; } else { switch_core_speech_flush_tts(&sh); +#ifdef MATCH_COUNT snprintf(buf + len, sizeof(buf) - len, "Main Menu. <break time=\"600ms\"/> " - "Choose one of the following Feeds followed by the pound key or press 0 to exit. " + "Select one of the following news sources, or press 0 to exit. " "<break time=\"600ms\"/>"); +#else + snprintf(buf + len, sizeof(buf) - len, + "Main Menu. <break time=\"600ms\"/> " + "Select one of the following news sources, followed by the pound key or press 0 to exit. " + "<break time=\"600ms\"/>"); +#endif len = (int32_t)strlen(buf); for (idx = 0; idx < feed_index; idx++) { - snprintf(buf + len, sizeof(buf) - len, "Feed Number %d %s. <break time=\"600ms\"/>", idx + 1, feed_names[idx]); + snprintf(buf + len, sizeof(buf) - len, "%d: %s. <break time=\"600ms\"/>", idx + 1, feed_names[idx]); len = (int32_t)strlen(buf); } @@ -471,7 +480,7 @@ char cmd[5] = ""; switch_time_exp_lt(&tm, switch_time_now()); - switch_strftime(date, &retsize, sizeof(date), "%A, %B %d, %Y. %I:%M %p", &tm); + switch_strftime(date, &retsize, sizeof(date), "%I:%M %p", &tm); snprintf(buf, sizeof(buf), "%s. %s. %s. local time: %s, Press 0 for options, 5 to change voice, or pound to return to the main menu. ", @@ -537,7 +546,7 @@ if (switch_test_flag(&dtb, SFLAG_INFO)) { switch_clear_flag(&dtb, SFLAG_INFO); snprintf(buf + len, sizeof(buf) - len, - "Hello my name is %s %s. I am speaking at %u words per minute. ", + "%s %s. I am speaking at %u words per minute. ", sh.engine, sh.voice, dtb.speed Modified: freeswitch/branches/stkn/src/mod/codecs/mod_g711/mod_g711.c ============================================================================== --- freeswitch/branches/stkn/src/mod/codecs/mod_g711/mod_g711.c (original) +++ freeswitch/branches/stkn/src/mod/codecs/mod_g711/mod_g711.c Mon Jul 3 21:47:59 2006 @@ -190,6 +190,8 @@ #if 0 static const switch_codec_implementation_t g711u_8k_60ms_implementation = { + /*.ianacode */ 0, + /*.iananame */ "PCMU", /*.samples_per_second */ 8000, /*.bits_per_second */ 19200, /*.microseconds_per_frame */ 60000, @@ -207,6 +209,8 @@ static const switch_codec_implementation_t g711u_8k_30ms_implementation = { + /*.ianacode */ 0, + /*.iananame */ "PCMU", /*.samples_per_second */ 8000, /*.bits_per_second */ 96000, /*.microseconds_per_frame */ 30000, @@ -225,6 +229,8 @@ #endif static const switch_codec_implementation_t g711u_16k_implementation = { + /*.ianacode */ 0, + /*.iananame */ "PCMU", /*.samples_per_second */ 16000, /*.bits_per_second */ 128000, /*.microseconds_per_frame */ 20000, @@ -241,6 +247,8 @@ }; static const switch_codec_implementation_t g711u_8k_implementation = { + /*.ianacode */ 0, + /*.iananame */ "PCMU", /*.samples_per_second */ 8000, /*.bits_per_second */ 64000, /*.microseconds_per_frame */ 20000, @@ -259,6 +267,8 @@ static const switch_codec_implementation_t g711a_8k_implementation = { + /*.ianacode */ 8, + /*.iananame */ "PCMA", /*.samples_per_second */ 8000, /*.bits_per_second */ 64000, /*.microseconds_per_frame */ 20000, @@ -278,16 +288,12 @@ static const switch_codec_interface_t g711a_codec_interface = { /*.interface_name */ "g711 alaw", /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, - /*.ianacode */ 8, - /*.iananame */ "PCMA", /*.implementations */ &g711a_8k_implementation }; static const switch_codec_interface_t g711u_codec_interface = { /*.interface_name */ "g711 ulaw", /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, - /*.ianacode */ 0, - /*.iananame */ "PCMU", /*.implementations */ &g711u_8k_implementation, /*.next */ &g711a_codec_interface }; Modified: freeswitch/branches/stkn/src/mod/codecs/mod_g729/mod_g729.c ============================================================================== --- freeswitch/branches/stkn/src/mod/codecs/mod_g729/mod_g729.c (original) +++ freeswitch/branches/stkn/src/mod/codecs/mod_g729/mod_g729.c Mon Jul 3 21:47:59 2006 @@ -219,6 +219,8 @@ /* Registration */ static const switch_codec_implementation_t g729_10ms_8k_implementation = { + /*.ianacode */ 18, + /*.iananame */ "G729", /*.samples_per_second */ 8000, /*.bits_per_second */ 32000, /*.microseconds_per_frame */ 10000, @@ -235,6 +237,8 @@ }; static const switch_codec_implementation_t g729_8k_implementation = { + /*.ianacode */ 18, + /*.iananame */ "G729", /*.samples_per_second */ 8000, /*.bits_per_second */ 64000, /*.microseconds_per_frame */ 20000, @@ -255,8 +259,6 @@ static const switch_codec_interface_t g729_codec_interface = { /*.interface_name */ "g729", /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, - /*.ianacode */ 18, - /*.iananame */ "G729", /*.implementations */ &g729_8k_implementation, }; Modified: freeswitch/branches/stkn/src/mod/codecs/mod_gsm/mod_gsm.c ============================================================================== --- freeswitch/branches/stkn/src/mod/codecs/mod_gsm/mod_gsm.c (original) +++ freeswitch/branches/stkn/src/mod/codecs/mod_gsm/mod_gsm.c Mon Jul 3 21:47:59 2006 @@ -133,6 +133,8 @@ /* Registration */ static const switch_codec_implementation_t gsm_8k_implementation = { + /*.ianacode */ 3, + /*.iananame */ "gsm", /*.samples_per_second */ 8000, /*.bits_per_second */ 13200, /*.microseconds_per_frame */ 20000, @@ -150,8 +152,6 @@ static const switch_codec_interface_t gsm_codec_interface = { /*.interface_name */ "gsm", /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, - /*.ianacode */ 3, - /*.iananame */ "gsm", /*.implementations */ &gsm_8k_implementation, }; static switch_loadable_module_interface_t gsm_module_interface = { Modified: freeswitch/branches/stkn/src/mod/codecs/mod_ilbc/mod_ilbc.c ============================================================================== --- freeswitch/branches/stkn/src/mod/codecs/mod_ilbc/mod_ilbc.c (original) +++ freeswitch/branches/stkn/src/mod/codecs/mod_ilbc/mod_ilbc.c Mon Jul 3 21:47:59 2006 @@ -186,6 +186,8 @@ /* Registration */ static const switch_codec_implementation_t ilbc_8k_30ms_implementation = { + /*.ianacode */ 97, + /*.iananame */ "iLBC", /*.samples_per_second */ 8000, /*.bits_per_second */ NO_OF_BYTES_30MS*8*8000/BLOCKL_30MS, /*.microseconds_per_frame */ 30000, @@ -202,6 +204,8 @@ }; static const switch_codec_implementation_t ilbc_8k_20ms_implementation = { + /*.ianacode */ 97, + /*.iananame */ "iLBC", /*.samples_per_second */ 8000, /*.bits_per_second */ NO_OF_BYTES_20MS*8*8000/BLOCKL_20MS, /*.microseconds_per_frame */ 20000, @@ -219,7 +223,48 @@ }; + +static const switch_codec_implementation_t ilbc_102_8k_30ms_implementation = { + /*.ianacode */ 102, + /*.iananame */ "iLBC", + /*.samples_per_second */ 8000, + /*.bits_per_second */ NO_OF_BYTES_30MS*8*8000/BLOCKL_30MS, + /*.microseconds_per_frame */ 30000, + /*.samples_per_frame */ 240, + /*.bytes_per_frame */ 480, + /*.encoded_bytes_per_frame */ NO_OF_BYTES_30MS, + /*.number_of_channels */ 1, + /*.pref_frames_per_packet */ 1, + /*.max_frames_per_packet */ 1, + /*.init */ switch_ilbc_init, + /*.encode */ switch_ilbc_encode, + /*.decode */ switch_ilbc_decode, + /*.destroy */ switch_ilbc_destroy +}; + +static const switch_codec_implementation_t ilbc_102_8k_20ms_implementation = { + /*.ianacode */ 102, + /*.iananame */ "iLBC102", + /*.samples_per_second */ 8000, + /*.bits_per_second */ NO_OF_BYTES_20MS*8*8000/BLOCKL_20MS, + /*.microseconds_per_frame */ 20000, + /*.samples_per_frame */ 160, + /*.bytes_per_frame */ 320, + /*.encoded_bytes_per_frame */ NO_OF_BYTES_20MS, + /*.number_of_channels */ 1, + /*.pref_frames_per_packet */ 1, + /*.max_frames_per_packet */ 1, + /*.init */ switch_ilbc_init, + /*.encode */ switch_ilbc_encode, + /*.decode */ switch_ilbc_decode, + /*.destroy */ switch_ilbc_destroy, + /*.next */ &ilbc_102_8k_30ms_implementation +}; + + static const switch_codec_implementation_t ilbc_8k_20ms_nonext_implementation = { + /*.ianacode */ 97, + /*.iananame */ "iLBC20ms", /*.samples_per_second */ 8000, /*.bits_per_second */ NO_OF_BYTES_20MS*8*8000/BLOCKL_20MS, /*.microseconds_per_frame */ 20000, @@ -239,25 +284,19 @@ static const switch_codec_interface_t ilbc_20ms_codec_interface = { /*.interface_name */ "ilbc", /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, - /*.ianacode */ 97, - /*.iananame */ "iLBC20ms", /*.implementations */ &ilbc_8k_20ms_nonext_implementation }; static const switch_codec_interface_t ilbc_102_codec_interface = { /*.interface_name */ "ilbc", /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, - /*.ianacode */ 102, - /*.iananame */ "iLBC102", - /*.implementations */ &ilbc_8k_20ms_implementation, + /*.implementations */ &ilbc_102_8k_20ms_implementation, /*.next*/ &ilbc_20ms_codec_interface }; static const switch_codec_interface_t ilbc_codec_interface = { /*.interface_name */ "ilbc", /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, - /*.ianacode */ 97, - /*.iananame */ "iLBC", /*.implementations */ &ilbc_8k_20ms_implementation, /*.next*/ &ilbc_102_codec_interface }; Modified: freeswitch/branches/stkn/src/mod/codecs/mod_l16/mod_l16.c ============================================================================== --- freeswitch/branches/stkn/src/mod/codecs/mod_l16/mod_l16.c (original) +++ freeswitch/branches/stkn/src/mod/codecs/mod_l16/mod_l16.c Mon Jul 3 21:47:59 2006 @@ -57,7 +57,6 @@ void *encoded_data, uint32_t *encoded_data_len, uint32_t *encoded_rate, unsigned int *flag) { - /* NOOP indicates that the audio in is already the same as the audio out, so no conversion was necessary. */ if (codec && other_codec && codec->implementation->samples_per_second != other_codec->implementation->samples_per_second) { memcpy(encoded_data, decoded_data, decoded_data_len); @@ -91,6 +90,8 @@ } static const switch_codec_implementation_t raw_32k_implementation = { + /*.ianacode */ 10, + /*.iananame */ "L16", /*.samples_per_second = */ 32000, /*.bits_per_second = */ 512000, /*.microseconds_per_frame = */ 20000, @@ -107,6 +108,8 @@ }; static const switch_codec_implementation_t raw_22k_implementation = { + /*.ianacode */ 10, + /*.iananame */ "L16", /*.samples_per_second = */ 22050, /*.bits_per_second = */ 352800, /*.microseconds_per_frame = */ 20000, @@ -124,6 +127,8 @@ }; static const switch_codec_implementation_t raw_16k_implementation = { + /*.ianacode */ 10, + /*.iananame */ "L16", /*.samples_per_second = */ 16000, /*.bits_per_second = */ 256000, /*.microseconds_per_frame = */ 20000, @@ -141,6 +146,8 @@ }; static const switch_codec_implementation_t raw_8k_implementation = { + /*.ianacode */ 10, + /*.iananame */ "L16", /*.samples_per_second = */ 8000, /*.bits_per_second = */ 128000, /*.microseconds_per_frame = */ 20000, @@ -159,6 +166,8 @@ static const switch_codec_implementation_t raw_8k_30ms_implementation = { + /*.ianacode */ 10, + /*.iananame */ "L16", /*.samples_per_second */ 8000, /*.bits_per_second */ 128000, /*.microseconds_per_frame */ 30000, @@ -176,12 +185,49 @@ }; +static const switch_codec_implementation_t raw_8k_60ms_implementation = { + /*.ianacode */ 10, + /*.iananame */ "L16", + /*.samples_per_second */ 8000, + /*.bits_per_second */ 256000, + /*.microseconds_per_frame */ 60000, + /*.samples_per_frame */ 480, + /*.bytes_per_frame */ 960, + /*.encoded_bytes_per_frame */ 960, + /*.number_of_channels */ 1, + /*.pref_frames_per_packet */ 1, + /*.max_frames_per_packet */ 1, + /*.init */ switch_raw_init, + /*.encode */ switch_raw_encode, + /*.decode */ switch_raw_decode, + /*.destroy */ switch_raw_destroy, + /*.next */ &raw_8k_30ms_implementation +}; + +static const switch_codec_implementation_t raw_8k_120ms_implementation = { + /*.ianacode */ 10, + /*.iananame */ "L16", + /*.samples_per_second */ 8000, + /*.bits_per_second */ 512000, + /*.microseconds_per_frame */ 120000, + /*.samples_per_frame */ 960, + /*.bytes_per_frame */ 1920, + /*.encoded_bytes_per_frame */ 1920, + /*.number_of_channels */ 1, + /*.pref_frames_per_packet */ 1, + /*.max_frames_per_packet */ 1, + /*.init */ switch_raw_init, + /*.encode */ switch_raw_encode, + /*.decode */ switch_raw_decode, + /*.destroy */ switch_raw_destroy, + /*.next */ &raw_8k_60ms_implementation +}; + + static const switch_codec_interface_t raw_codec_interface = { /*.interface_name */ "raw signed linear (16 bit)", /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, - /*.ianacode */ 10, - /*.iananame */ "L16", - /*.implementations */ &raw_8k_30ms_implementation + /*.implementations */ &raw_8k_120ms_implementation }; static switch_loadable_module_interface_t raw_module_interface = { Modified: freeswitch/branches/stkn/src/mod/codecs/mod_speex/mod_speex.c ============================================================================== --- freeswitch/branches/stkn/src/mod/codecs/mod_speex/mod_speex.c (original) +++ freeswitch/branches/stkn/src/mod/codecs/mod_speex/mod_speex.c Mon Jul 3 21:47:59 2006 @@ -268,6 +268,8 @@ /* Registration */ static const switch_codec_implementation_t speex_32k_implementation = { + /*.ianacode */ 98, + /*.iananame */ "speex", /*.samples_per_second */ 32000, /*.bits_per_second */ 512000, /*.nanoseconds_per_frame */ 20000, @@ -284,6 +286,8 @@ }; static const switch_codec_implementation_t speex_16k_implementation = { + /*.ianacode */ 98, + /*.iananame */ "speex", /*.samples_per_second */ 16000, /*.bits_per_second */ 256000, /*.nanoseconds_per_frame */ 20000, @@ -301,6 +305,8 @@ }; static const switch_codec_implementation_t speex_8k_implementation = { + /*.ianacode */ 98, + /*.iananame */ "speex", /*.samples_per_second */ 8000, /*.bits_per_second */ 128000, /*.nanoseconds_per_frame */ 20000, @@ -320,8 +326,6 @@ static const switch_codec_interface_t speex_codec_interface = { /*.interface_name */ "speex", /*.codec_type */ SWITCH_CODEC_TYPE_AUDIO, - /*.ianacode */ 98, - /*.iananame */ "speex", /*.implementations */ &speex_8k_implementation }; Modified: freeswitch/branches/stkn/src/mod/endpoints/mod_dingaling/mod_dingaling.c ============================================================================== --- freeswitch/branches/stkn/src/mod/endpoints/mod_dingaling/mod_dingaling.c (original) +++ freeswitch/branches/stkn/src/mod/endpoints/mod_dingaling/mod_dingaling.c Mon Jul 3 21:47:59 2006 @@ -39,6 +39,7 @@ #define DL_EVENT_LOGIN_SUCCESS "dingaling::login_success" #define DL_EVENT_LOGIN_FAILURE "dingaling::login_failure" #define DL_EVENT_MESSAGE "dingaling::message" +#define DL_EVENT_CONNECTED "dingaling::connected" static const char modname[] = "mod_dingaling"; @@ -137,6 +138,7 @@ char *recip; char *dnis; uint16_t stun_port; + switch_mutex_t *flag_mutex; }; struct rfc2833_digit { @@ -308,7 +310,7 @@ switch_rtp_activate_ice(tech_pvt->rtp_session, tech_pvt->remote_user, tech_pvt->local_user); if ((vad_in && inb) || (vad_out && !inb)) { switch_rtp_enable_vad(tech_pvt->rtp_session, tech_pvt->session, &tech_pvt->read_codec, SWITCH_VAD_FLAG_TALKING); - switch_set_flag(tech_pvt, TFLAG_VAD); + switch_set_flag_locked(tech_pvt, TFLAG_VAD); } } @@ -332,7 +334,7 @@ if (switch_test_flag(tech_pvt, TFLAG_BYE)) { return -1; } - switch_set_flag(tech_pvt, TFLAG_DO_CAND); + switch_set_flag_locked(tech_pvt, TFLAG_DO_CAND); if (force || !switch_test_flag(tech_pvt, TFLAG_RTP_READY)) { ldl_candidate_t cand[1]; @@ -392,9 +394,9 @@ cand[0].protocol = "udp"; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Send Candidate %s:%d [%s]\n", cand[0].address, cand[0].port, cand[0].username); tech_pvt->cand_id = ldl_session_candidates(tech_pvt->dlsession, cand, 1); - switch_set_flag(tech_pvt, TFLAG_RTP_READY); + switch_set_flag_locked(tech_pvt, TFLAG_RTP_READY); } - switch_clear_flag(tech_pvt, TFLAG_DO_CAND); + switch_clear_flag_locked(tech_pvt, TFLAG_DO_CAND); return 0; } @@ -424,13 +426,13 @@ } memset(payloads, 0, sizeof(payloads)); - switch_set_flag(tech_pvt, TFLAG_DO_CAND); + switch_set_flag_locked(tech_pvt, TFLAG_DO_CAND); if (!tech_pvt->num_codecs) { get_codecs(tech_pvt); if (!tech_pvt->num_codecs) { switch_channel_hangup(channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); - switch_set_flag(tech_pvt, TFLAG_BYE); - switch_clear_flag(tech_pvt, TFLAG_IO); + switch_set_flag_locked(tech_pvt, TFLAG_BYE); + switch_clear_flag_locked(tech_pvt, TFLAG_IO); return -1; } } @@ -438,25 +440,25 @@ if (force || !switch_test_flag(tech_pvt, TFLAG_CODEC_READY)) { if (tech_pvt->codec_index < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Don't have my codec yet here's one\n"); - tech_pvt->codec_name = lame(tech_pvt->codecs[0]->iananame); - tech_pvt->codec_num = tech_pvt->codecs[0]->ianacode; + tech_pvt->codec_name = lame(tech_pvt->codecs[0]->implementations->iananame); + tech_pvt->codec_num = tech_pvt->codecs[0]->implementations->ianacode; tech_pvt->codec_index = 0; - payloads[0].name = lame(tech_pvt->codecs[0]->iananame); - payloads[0].id = tech_pvt->codecs[0]->ianacode; + payloads[0].name = lame(tech_pvt->codecs[0]->implementations->iananame); + payloads[0].id = tech_pvt->codecs[0]->implementations->ianacode; } else { - payloads[0].name = lame(tech_pvt->codecs[tech_pvt->codec_index]->iananame); - payloads[0].id = tech_pvt->codecs[tech_pvt->codec_index]->ianacode; + payloads[0].name = lame(tech_pvt->codecs[tech_pvt->codec_index]->implementations->iananame); + payloads[0].id = tech_pvt->codecs[tech_pvt->codec_index]->implementations->ianacode; } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Send Describe [%s]\n", payloads[0].name); tech_pvt->desc_id = ldl_session_describe(tech_pvt->dlsession, payloads, 1, switch_test_flag(tech_pvt, TFLAG_OUTBOUND) ? LDL_DESCRIPTION_INITIATE : LDL_DESCRIPTION_ACCEPT); - switch_set_flag(tech_pvt, TFLAG_CODEC_READY); + switch_set_flag_locked(tech_pvt, TFLAG_CODEC_READY); } - switch_clear_flag(tech_pvt, TFLAG_DO_CAND); + switch_clear_flag_locked(tech_pvt, TFLAG_DO_CAND); return 0; } @@ -476,7 +478,7 @@ channel = switch_core_session_get_channel(session); assert(channel != NULL); - switch_set_flag(tech_pvt, TFLAG_IO); + switch_set_flag_locked(tech_pvt, TFLAG_IO); started = switch_time_now(); @@ -512,8 +514,8 @@ } if (elapsed > 60000) { switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); - switch_set_flag(tech_pvt, TFLAG_BYE); - switch_clear_flag(tech_pvt, TFLAG_IO); + switch_set_flag_locked(tech_pvt, TFLAG_BYE); + switch_clear_flag_locked(tech_pvt, TFLAG_IO); return NULL; } if (switch_test_flag(tech_pvt, TFLAG_BYE) || ! switch_test_flag(tech_pvt, TFLAG_IO)) { @@ -623,9 +625,9 @@ tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - switch_set_flag(tech_pvt, TFLAG_BYE); + switch_clear_flag_locked(tech_pvt, TFLAG_IO); + switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); + switch_set_flag_locked(tech_pvt, TFLAG_BYE); if (tech_pvt->dlsession) { ldl_session_terminate(tech_pvt->dlsession); @@ -658,9 +660,9 @@ if ((channel = switch_core_session_get_channel(session))) { if ((tech_pvt = switch_core_session_get_private(session))) { - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); - switch_set_flag(tech_pvt, TFLAG_BYE); + switch_clear_flag_locked(tech_pvt, TFLAG_IO); + switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); + switch_set_flag_locked(tech_pvt, TFLAG_BYE); switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); if (tech_pvt->dlsession) { ldl_session_terminate(tech_pvt->dlsession); @@ -748,7 +750,7 @@ } tech_pvt->read_frame.datalen = 0; - switch_set_flag(tech_pvt, TFLAG_READING); + switch_set_flag_locked(tech_pvt, TFLAG_READING); bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame; samples = tech_pvt->read_codec.implementation->samples_per_frame; @@ -769,11 +771,11 @@ char dtmf[128]; switch_rtp_dequeue_dtmf(tech_pvt->rtp_session, dtmf, sizeof(dtmf)); switch_channel_queue_dtmf(channel, dtmf); - switch_set_flag(tech_pvt, TFLAG_DTMF); + switch_set_flag_locked(tech_pvt, TFLAG_DTMF); } if (switch_test_flag(tech_pvt, TFLAG_DTMF)) { - switch_clear_flag(tech_pvt, TFLAG_DTMF); + switch_clear_flag_locked(tech_pvt, TFLAG_DTMF); return SWITCH_STATUS_BREAK; } @@ -797,7 +799,7 @@ } - switch_clear_flag(tech_pvt, TFLAG_READING); + switch_clear_flag_locked(tech_pvt, TFLAG_READING); if (switch_test_flag(tech_pvt, TFLAG_BYE)) { switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); @@ -837,7 +839,7 @@ return SWITCH_STATUS_FALSE; } - switch_set_flag(tech_pvt, TFLAG_WRITING); + switch_set_flag_locked(tech_pvt, TFLAG_WRITING); bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame; @@ -851,7 +853,7 @@ } tech_pvt->timestamp_send += (int) samples; - switch_clear_flag(tech_pvt, TFLAG_WRITING); + switch_clear_flag_locked(tech_pvt, TFLAG_WRITING); //switch_mutex_unlock(tech_pvt->rtp_lock); return status; } @@ -1021,6 +1023,7 @@ switch_core_session_add_stream(*new_session, NULL); if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object))) != 0) { memset(tech_pvt, 0, sizeof(*tech_pvt)); + switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session)); tech_pvt->flags |= globals.flags; tech_pvt->flags |= mdl_profile->flags; channel = switch_core_session_get_channel(*new_session); @@ -1052,7 +1055,7 @@ } switch_channel_set_flag(channel, CF_OUTBOUND); - switch_set_flag(tech_pvt, TFLAG_OUTBOUND); + switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND); switch_stun_random_string(sess_id, 10, "0123456789"); @@ -1099,6 +1102,11 @@ return SWITCH_STATUS_GENERR; } + if (switch_event_reserve_subclass(DL_EVENT_CONNECTED) != SWITCH_STATUS_SUCCESS) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!", DL_EVENT_CONNECTED); + return SWITCH_STATUS_GENERR; + } + /* connect my internal structure to the blank pointer passed to me */ *module_interface = &channel_module_interface; @@ -1399,11 +1407,6 @@ return LDL_STATUS_FALSE; } - - //#define DL_EVENT_LOGIN_SUCCESS "dingaling::login_success" - //#define DL_EVENT_LOGIN_FAILURE "dingaling::login_failure" - //#define DL_EVENT_MESSAGE "dingaling::message" - if (!dlsession) { switch(signal) { case LDL_SIGNAL_MSG: @@ -1427,6 +1430,12 @@ switch_event_fire(&event); } break; + case LDL_SIGNAL_CONNECTED: + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, DL_EVENT_CONNECTED) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", profile->login); + switch_event_fire(&event); + } + break; default: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR\n"); break; @@ -1459,6 +1468,7 @@ switch_core_session_add_stream(session, NULL); if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object))) != 0) { memset(tech_pvt, 0, sizeof(*tech_pvt)); + switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); tech_pvt->flags |= globals.flags; tech_pvt->flags |= profile->flags; channel = switch_core_session_get_channel(session); @@ -1467,7 +1477,7 @@ tech_pvt->codec_index = -1; tech_pvt->profile = profile; tech_pvt->local_port = switch_rtp_request_port(); - switch_set_flag(tech_pvt, TFLAG_ANSWER); + switch_set_flag_locked(tech_pvt, TFLAG_ANSWER); tech_pvt->recip = switch_core_session_strdup(session, from); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Hey where is my memory pool?\n"); @@ -1488,7 +1498,7 @@ if (msg) { if (*msg == '+') { switch_channel_queue_dtmf(channel, msg + 1); - switch_set_flag(tech_pvt, TFLAG_DTMF); + switch_set_flag_locked(tech_pvt, TFLAG_DTMF); switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_BREAK); } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "SESSION MSG [%s]\n", msg); @@ -1512,7 +1522,7 @@ if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { if (!strcasecmp(msg, "accept")) { - switch_set_flag(tech_pvt, TFLAG_ANSWER); + switch_set_flag_locked(tech_pvt, TFLAG_ANSWER); do_candidates(tech_pvt, 0); } } @@ -1536,22 +1546,22 @@ for(x = 0; x < len; x++) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Available Payload %s %u\n", payloads[x].name, payloads[x].id); for(y = 0; y < tech_pvt->num_codecs; y++) { - char *name = tech_pvt->codecs[y]->iananame; + char *name = tech_pvt->codecs[y]->implementations->iananame; if (!strncasecmp(name, "ilbc", 4)) { name = "ilbc"; } - if (tech_pvt->codecs[y]->ianacode > 96) { + if (tech_pvt->codecs[y]->implementations->ianacode > 96) { match = strcasecmp(name, payloads[x].name) ? 0 : 1; } else { - match = (payloads[x].id == tech_pvt->codecs[y]->ianacode) ? 1 : 0; + match = (payloads[x].id == tech_pvt->codecs[y]->implementations->ianacode) ? 1 : 0; } if (match) { tech_pvt->codec_index = y; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Choosing Payload index %u %s %u\n", y, payloads[x].name, payloads[x].id); - tech_pvt->codec_name = tech_pvt->codecs[y]->iananame; - tech_pvt->codec_num = tech_pvt->codecs[y]->ianacode; + tech_pvt->codec_name = tech_pvt->codecs[y]->implementations->iananame; + tech_pvt->codec_num = tech_pvt->codecs[y]->implementations->ianacode; if (!switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { do_describe(tech_pvt, 0); } @@ -1658,7 +1668,7 @@ } if (lanaddr) { - switch_set_flag(tech_pvt, TFLAG_LANADDR); + switch_set_flag_locked(tech_pvt, TFLAG_LANADDR); } if (!tech_pvt->num_codecs) { @@ -1676,7 +1686,7 @@ if (!switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { do_candidates(tech_pvt, 0); } - switch_set_flag(tech_pvt, TFLAG_TRANSPORT); + switch_set_flag_locked(tech_pvt, TFLAG_TRANSPORT); return LDL_STATUS_SUCCESS; } @@ -1689,8 +1699,10 @@ if (channel) { switch_channel_state_t state = switch_channel_get_state(channel); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hungup %s %u %d\n", switch_channel_get_name(channel), state, CS_INIT); + switch_mutex_lock(tech_pvt->flag_mutex); switch_set_flag(tech_pvt, TFLAG_BYE); switch_clear_flag(tech_pvt, TFLAG_IO); + switch_mutex_unlock(tech_pvt->flag_mutex); switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); if (state <= CS_INIT && !switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) { Modified: freeswitch/branches/stkn/src/mod/endpoints/mod_exosip/mod_exosip.c ============================================================================== --- freeswitch/branches/stkn/src/mod/endpoints/mod_exosip/mod_exosip.c (original) +++ freeswitch/branches/stkn/src/mod/endpoints/mod_exosip/mod_exosip.c Mon Jul 3 21:47:59 2006 @@ -141,6 +141,7 @@ switch_codec_interface_t *codecs[SWITCH_MAX_CODECS]; int num_codecs; switch_payload_t te; + switch_mutex_t *flag_mutex; }; @@ -350,22 +351,27 @@ if (tech_pvt->num_codecs > 0) { - int i; + int i, lastcode = -1; + static const switch_codec_implementation_t *imp; - for (i = 0; i < tech_pvt->num_codecs; i++) { - int x = 1; - snprintf(tmp, sizeof(tmp), "%u", tech_pvt->codecs[i]->ianacode); - sdp_message_m_payload_add(tech_pvt->local_sdp, 0, osip_strdup(tmp)); + for (i = 0; i < tech_pvt->num_codecs; i++) { imp = tech_pvt->codecs[i]->implementations; while(NULL != imp) { uint32_t sps = imp->samples_per_second; + + if (lastcode != imp->ianacode) { + snprintf(tmp, sizeof(tmp), "%u", imp->ianacode); + sdp_message_m_payload_add(tech_pvt->local_sdp, 0, osip_strdup(tmp)); + lastcode = imp->ianacode; + } + /* Add to SDP config */ - sdp_add_codec(tech_pvt->sdp_config, tech_pvt->codecs[i]->codec_type, tech_pvt->codecs[i]->ianacode, tech_pvt->codecs[i]->iananame, sps, x++); + sdp_add_codec(tech_pvt->sdp_config, tech_pvt->codecs[i]->codec_type, imp->ianacode, imp->iananame, sps, 0); /* Add to SDP message */ - snprintf(tmp, sizeof(tmp), "%u %s/%d", tech_pvt->codecs[i]->ianacode, tech_pvt->codecs[i]->iananame, sps); + snprintf(tmp, sizeof(tmp), "%u %s/%d", imp->ianacode, imp->iananame, sps); sdp_message_a_attribute_add(tech_pvt->local_sdp, 0, "rtpmap", osip_strdup(tmp)); memset(tmp, 0, sizeof(tmp)); if (imp) { @@ -408,7 +414,7 @@ } /* Let Media Work */ - switch_set_flag(tech_pvt, TFLAG_IO); + switch_set_flag_locked(tech_pvt, TFLAG_IO); /* Move Channel's State Machine to RING */ switch_channel_set_state(channel, CS_RING); @@ -446,8 +452,8 @@ deactivate_rtp(tech_pvt); eXosip_lock(); switch_core_hash_delete(globals.call_hash, tech_pvt->call_id); - switch_set_flag(tech_pvt, TFLAG_BYE); - switch_clear_flag(tech_pvt, TFLAG_IO); + switch_set_flag_locked(tech_pvt, TFLAG_BYE); + switch_clear_flag_locked(tech_pvt, TFLAG_IO); i = eXosip_call_terminate(tech_pvt->cid, tech_pvt->did); eXosip_unlock(); @@ -518,18 +524,18 @@ } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Activating RTP %s:%d->%s:%d codec: %u ms: %d\n", - tech_pvt->local_sdp_audio_ip, - tech_pvt->local_sdp_audio_port, - tech_pvt->remote_sdp_audio_ip, - tech_pvt->remote_sdp_audio_port, tech_pvt->read_codec.codec_interface->ianacode, ms); + tech_pvt->local_sdp_audio_ip, + tech_pvt->local_sdp_audio_port, + tech_pvt->remote_sdp_audio_ip, + tech_pvt->remote_sdp_audio_port, tech_pvt->read_codec.implementation->ianacode, ms); if (tech_pvt->realm) { if (!(key = (char *) switch_core_hash_find(globals.srtp_hash, tech_pvt->realm))) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "undefined Realm %s\n", tech_pvt->realm); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - switch_set_flag(tech_pvt, TFLAG_BYE); - switch_clear_flag(tech_pvt, TFLAG_IO); + switch_set_flag_locked(tech_pvt, TFLAG_BYE); + switch_clear_flag_locked(tech_pvt, TFLAG_IO); return SWITCH_STATUS_FALSE; } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "using Realm %s\n", tech_pvt->realm); @@ -545,15 +551,15 @@ } tech_pvt->rtp_session = switch_rtp_new(tech_pvt->local_sdp_audio_ip, - tech_pvt->local_sdp_audio_port, - tech_pvt->remote_sdp_audio_ip, - tech_pvt->remote_sdp_audio_port, - tech_pvt->read_codec.codec_interface->ianacode, - tech_pvt->read_codec.implementation->encoded_bytes_per_frame, - ms, - flags, - key, - &err, switch_core_session_get_pool(tech_pvt->session)); + tech_pvt->local_sdp_audio_port, + tech_pvt->remote_sdp_audio_ip, + tech_pvt->remote_sdp_audio_port, + tech_pvt->read_codec.implementation->ianacode, + tech_pvt->read_codec.implementation->encoded_bytes_per_frame, + ms, + flags, + key, + &err, switch_core_session_get_pool(tech_pvt->session)); if (tech_pvt->rtp_session) { uint8_t vad_in = switch_test_flag(tech_pvt, TFLAG_VAD_IN) ? 1 : 0; @@ -561,7 +567,7 @@ uint8_t inb = switch_test_flag(tech_pvt, TFLAG_OUTBOUND) ? 0 : 1; tech_pvt->ssrc = switch_rtp_get_ssrc(tech_pvt->rtp_session); - switch_set_flag(tech_pvt, TFLAG_RTP); + switch_set_flag_locked(tech_pvt, TFLAG_RTP); if (tech_pvt->te > 96) { switch_rtp_set_telephony_event(tech_pvt->rtp_session, tech_pvt->te); @@ -569,14 +575,14 @@ if ((vad_in && inb) || (vad_out && !inb)) { switch_rtp_enable_vad(tech_pvt->rtp_session, tech_pvt->session, &tech_pvt->read_codec, SWITCH_VAD_FLAG_TALKING); - switch_set_flag(tech_pvt, TFLAG_VAD); + switch_set_flag_locked(tech_pvt, TFLAG_VAD); } } else { switch_channel_t *channel = switch_core_session_get_channel(tech_pvt->session); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "RTP REPORTS ERROR: [%s]\n", err); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - switch_set_flag(tech_pvt, TFLAG_BYE); - switch_clear_flag(tech_pvt, TFLAG_IO); + switch_set_flag_locked(tech_pvt, TFLAG_BYE); + switch_clear_flag_locked(tech_pvt, TFLAG_IO); return SWITCH_STATUS_FALSE; } @@ -599,7 +605,8 @@ if (!switch_test_flag(tech_pvt, TFLAG_ANS) && !switch_channel_test_flag(channel, CF_OUTBOUND) ) { char *buf = NULL; osip_message_t *answer = NULL; - + char *sdp_str; + /* Transmit 200 OK with SDP */ eXosip_lock(); eXosip_call_build_answer(tech_pvt->tid, 200, &answer); @@ -609,7 +616,14 @@ free(buf); eXosip_call_send_answer(tech_pvt->tid, 200, answer); eXosip_unlock(); - switch_set_flag(tech_pvt, TFLAG_ANS); + switch_set_flag_locked(tech_pvt, TFLAG_ANS); + + sdp_message_to_str(tech_pvt->local_sdp, &sdp_str); + if (sdp_str) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Answer SDP:\n%s", sdp_str); + free(sdp_str); + } + } @@ -635,7 +649,7 @@ assert(tech_pvt != NULL); tech_pvt->read_frame.datalen = 0; - switch_set_flag(tech_pvt, TFLAG_READING); + switch_set_flag_locked(tech_pvt, TFLAG_READING); if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) { bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame; @@ -712,7 +726,7 @@ } - switch_clear_flag(tech_pvt, TFLAG_READING); + switch_clear_flag_locked(tech_pvt, TFLAG_READING); if (switch_test_flag(tech_pvt, TFLAG_BYE)) { switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); @@ -752,7 +766,7 @@ return SWITCH_STATUS_FALSE; } - switch_set_flag(tech_pvt, TFLAG_WRITING); + switch_set_flag_locked(tech_pvt, TFLAG_WRITING); if (switch_test_flag(tech_pvt, TFLAG_USING_CODEC)) { bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame; @@ -770,7 +784,7 @@ tech_pvt->timestamp_send += (int) samples; - switch_clear_flag(tech_pvt, TFLAG_WRITING); + switch_clear_flag_locked(tech_pvt, TFLAG_WRITING); return status; } @@ -787,8 +801,8 @@ tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_set_flag(tech_pvt, TFLAG_BYE); + switch_clear_flag_locked(tech_pvt, TFLAG_IO); + switch_set_flag_locked(tech_pvt, TFLAG_BYE); if (tech_pvt->rtp_session) { switch_rtp_kill_socket(tech_pvt->rtp_session); @@ -887,13 +901,19 @@ eXosip_lock(); eXosip_call_build_answer(tech_pvt->tid, 183, &progress); if (progress) { - sdp_message_to_str(tech_pvt->local_sdp, &buf); - osip_message_set_body(progress, buf, strlen(buf)); - osip_message_set_content_type(progress, "application/sdp"); - free(buf); - eXosip_call_send_answer(tech_pvt->tid, 183, progress); - switch_set_flag(tech_pvt, TFLAG_EARLY_MEDIA); - switch_channel_set_flag(channel, CF_EARLY_MEDIA); + char *sdp_str; + sdp_message_to_str(tech_pvt->local_sdp, &buf); + osip_message_set_body(progress, buf, strlen(buf)); + osip_message_set_content_type(progress, "application/sdp"); + free(buf); + eXosip_call_send_answer(tech_pvt->tid, 183, progress); + switch_set_flag_locked(tech_pvt, TFLAG_EARLY_MEDIA); + switch_channel_set_flag(channel, CF_EARLY_MEDIA); + sdp_message_to_str(tech_pvt->local_sdp, &sdp_str); + if (sdp_str) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Progress SDP:\n%s", sdp_str); + free(sdp_str); + } } eXosip_unlock(); } @@ -1032,6 +1052,7 @@ switch_core_session_set_private(*new_session, tech_pvt); tech_pvt->session = *new_session; tech_pvt->te = globals.te; + switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session)); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); switch_core_session_destroy(new_session); @@ -1081,7 +1102,7 @@ } switch_channel_set_flag(channel, CF_OUTBOUND); - switch_set_flag(tech_pvt, TFLAG_OUTBOUND); + switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND); switch_channel_set_state(channel, CS_INIT); return SWITCH_STATUS_SUCCESS; } @@ -1140,7 +1161,7 @@ sdp_message_t *remote_sdp = NULL; sdp_connection_t *conn = NULL; sdp_media_t *remote_med = NULL, *audio_tab[10], *video_tab[10], *t38_tab[10], *app_tab[10]; - char local_sdp_str[8192] = "", port[8] = ""; + char local_sdp_str[1024] = "", port[8] = ""; int mline = 0, pos = 0; switch_channel_t *channel = NULL; char name[128]; @@ -1166,6 +1187,7 @@ switch_core_session_set_private(session, tech_pvt); tech_pvt->session = session; tech_pvt->te = globals.te; + switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n"); switch_core_session_destroy(&session); @@ -1222,7 +1244,7 @@ switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); } - switch_set_flag(tech_pvt, TFLAG_INBOUND); + switch_set_flag_locked(tech_pvt, TFLAG_INBOUND); tech_pvt->did = event->did; tech_pvt->cid = event->cid; tech_pvt->tid = event->tid; @@ -1271,40 +1293,43 @@ } } osip_rfc3264_init(&tech_pvt->sdp_config); + /* Add in what codecs we support locally */ tech_set_codecs(tech_pvt); - + sdp_message_init(&tech_pvt->local_sdp); + + sprintf(dbuf, "%u", tech_pvt->te); sdp_message_m_payload_add(tech_pvt->local_sdp, 0, osip_strdup(dbuf)); sdp_add_codec(tech_pvt->sdp_config, SWITCH_CODEC_TYPE_AUDIO, tech_pvt->te, "telephone-event", 8000, 0); sprintf(dbuf, "%u telephone-event/8000", tech_pvt->te); sdp_message_a_attribute_add(tech_pvt->local_sdp, 0, "rtpmap", osip_strdup(dbuf)); - + + if (tech_pvt->num_codecs > 0) { int i; static const switch_codec_implementation_t *imp; - - for (i = 0; i < tech_pvt->num_codecs; i++) { - int x = 1; - for (imp = tech_pvt->codecs[i]->implementations; imp; imp = imp->next) { - sdp_add_codec(tech_pvt->sdp_config, tech_pvt->codecs[i]->codec_type, tech_pvt->codecs[i]->ianacode, tech_pvt->codecs[i]->iananame, - imp->samples_per_second, x++); + sdp_add_codec(tech_pvt->sdp_config, tech_pvt->codecs[i]->codec_type, imp->ianacode, imp->iananame, + imp->samples_per_second, 0); + } } } + + - osip_rfc3264_prepare_answer(tech_pvt->sdp_config, remote_sdp, local_sdp_str, 8192); + osip_rfc3264_prepare_answer(tech_pvt->sdp_config, remote_sdp, local_sdp_str, sizeof(local_sdp_str)); sdp_message_parse(tech_pvt->local_sdp, local_sdp_str); sdp_message_to_str(remote_sdp, &remote_sdp_str); - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "LOCAL SDP:\n%s\nREMOTE SDP:\n%s", local_sdp_str, remote_sdp_str); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "REMOTE SDP:\n%s", remote_sdp_str); mline = 0; while (0 == osip_rfc3264_match(tech_pvt->sdp_config, remote_sdp, audio_tab, video_tab, t38_tab, app_tab, mline)) { @@ -1382,7 +1407,7 @@ } else { int ms; tech_pvt->read_frame.rate = rate; - switch_set_flag(tech_pvt, TFLAG_USING_CODEC); + switch_set_flag_locked(tech_pvt, TFLAG_USING_CODEC); ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Activate Inbound Codec %s/%d %d ms\n", dname, rate, ms); tech_pvt->read_frame.codec = &tech_pvt->read_codec; @@ -1498,22 +1523,20 @@ for(i = 0; !match && i < tech_pvt->num_codecs; i++) { const switch_codec_implementation_t *imp; - if (pt < 97) { - match = (pt == tech_pvt->codecs[i]->ianacode) ? 1 : 0; - } else { - match = strcasecmp(name, tech_pvt->codecs[i]->iananame) ? 0 : 1; - } - if (match) { - match = 0; + for (imp = tech_pvt->codecs[i]->implementations; imp; imp = imp->next) { + + if (pt < 97) { + match = (pt == imp->ianacode) ? 1 : 0; + } else { + match = strcasecmp(name, imp->iananame) ? 0 : 1; + } - for (imp = tech_pvt->codecs[i]->implementations; imp; imp = imp->next) { - if ((r == imp->samples_per_second)) { - match = 1; - break; - } + if (match && (r == imp->samples_per_second)) { + break; } } + } if (match) { @@ -1702,7 +1725,7 @@ } else { int ms; tech_pvt->read_frame.rate = rate; - switch_set_flag(tech_pvt, TFLAG_USING_CODEC); + switch_set_flag_locked(tech_pvt, TFLAG_USING_CODEC); ms = tech_pvt->write_codec.implementation->microseconds_per_frame / 1000; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Activate Outbound Codec %s/%d %d ms\n", dname, rate, ms); tech_pvt->read_frame.codec = &tech_pvt->read_codec; Modified: freeswitch/branches/stkn/src/mod/endpoints/mod_iax/mod_iax.c ============================================================================== --- freeswitch/branches/stkn/src/mod/endpoints/mod_iax/mod_iax.c (original) +++ freeswitch/branches/stkn/src/mod/endpoints/mod_iax/mod_iax.c Mon Jul 3 21:47:59 2006 @@ -90,6 +90,7 @@ unsigned int codecs; unsigned short samprate; switch_mutex_t *mutex; + switch_mutex_t *flag_mutex; //switch_thread_cond_t *cond; }; @@ -233,11 +234,15 @@ } for (x = 0; x < num_codecs; x++) { - unsigned int codec = iana2ast(codecs[x]->ianacode); - if (io == IAX_QUERY) { - iax_pref_codec_add(iax_session, codec); + static const switch_codec_implementation_t *imp; + for (imp = codecs[x]->implementations; imp; imp = imp->next) { + unsigned int codec = iana2ast(imp->ianacode); + + if (io == IAX_QUERY) { + iax_pref_codec_add(iax_session, codec); + } + local_cap |= codec; } - local_cap |= codec; } if (io == IAX_SET) { @@ -246,7 +251,7 @@ mixed_cap = local_cap; } - leading = iana2ast(codecs[0]->ianacode); + leading = iana2ast(codecs[0]->implementations->ianacode); if (io == IAX_QUERY) { chosen = leading; *format = chosen; @@ -258,7 +263,7 @@ return SWITCH_STATUS_SUCCESS; } else if (switch_test_flag(&globals, GFLAG_MY_CODEC_PREFS) && (leading & mixed_cap)) { chosen = leading; - dname = codecs[0]->iananame; + dname = codecs[0]->implementations->iananame; } else { unsigned int prefs[32]; int len = 0; @@ -282,8 +287,12 @@ int z; chosen = prefs[x]; for (z = 0; z < num_codecs; z++) { - if (prefs[x] == iana2ast(codecs[z]->ianacode)) { - dname = codecs[z]->iananame; + static const switch_codec_implementation_t *imp; + for (imp = codecs[z]->implementations; imp; imp = imp->next) { + if (prefs[x] == iana2ast(imp->ianacode)) { + dname = imp->iananame; + break; + } } } break; @@ -293,17 +302,25 @@ if (*format & mixed_cap) { /* is the one we asked for here? */ chosen = *format; for (x = 0; x < num_codecs; x++) { - unsigned int cap = iana2ast(codecs[x]->ianacode); - if (cap == chosen) { - dname = codecs[x]->iananame; + static const switch_codec_implementation_t *imp; + for (imp = codecs[x]->implementations; imp; imp = imp->next) { + unsigned int cap = iana2ast(imp->ianacode); + if (cap == chosen) { + dname = imp->iananame; + break; + } } } } else { /* c'mon there has to be SOMETHING... */ for (x = 0; x < num_codecs; x++) { - unsigned int cap = iana2ast(codecs[x]->ianacode); - if (cap & mixed_cap) { - chosen = cap; - dname = codecs[x]->iananame; + static const switch_codec_implementation_t *imp; + for (imp = codecs[x]->implementations; imp; imp = imp->next) { + unsigned int cap = iana2ast(imp->ianacode); + if (cap & mixed_cap) { + chosen = cap; + dname = imp->iananame; + break; + } } } } @@ -344,7 +361,7 @@ } if (!strcasecmp(dname, "l16")) { - switch_set_flag(tech_pvt, TFLAG_LINEAR); + switch_set_flag_locked(tech_pvt, TFLAG_LINEAR); } if (switch_core_codec_init(&tech_pvt->read_codec, dname, @@ -376,7 +393,7 @@ tech_pvt->read_frame.codec = &tech_pvt->read_codec; switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec); switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec); - switch_set_flag(tech_pvt, TFLAG_CODEC); + switch_set_flag_locked(tech_pvt, TFLAG_CODEC); } tech_pvt->codec = chosen; tech_pvt->codecs = local_cap; @@ -437,7 +454,7 @@ tech_pvt->read_frame.buflen = sizeof(tech_pvt->databuf); iax_set_private(tech_pvt->iax_session, tech_pvt); - switch_set_flag(tech_pvt, TFLAG_IO); + switch_set_flag_locked(tech_pvt, TFLAG_IO); switch_mutex_init(&tech_pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); //switch_thread_cond_create(&tech_pvt->cond, switch_core_session_get_pool(session)); @@ -494,8 +511,8 @@ tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); + switch_clear_flag_locked(tech_pvt, TFLAG_IO); + switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); //switch_thread_cond_signal(tech_pvt->cond); if (tech_pvt->read_codec.implementation) { @@ -509,7 +526,7 @@ if (tech_pvt->iax_session) { if (!switch_test_flag(tech_pvt, TFLAG_HANGUP)) { iax_hangup(tech_pvt->iax_session, "Hangup"); - switch_set_flag(tech_pvt, TFLAG_HANGUP); + switch_set_flag_locked(tech_pvt, TFLAG_HANGUP); } iax_session_destroy(&tech_pvt->iax_session); } @@ -530,8 +547,8 @@ tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); - switch_clear_flag(tech_pvt, TFLAG_IO); - switch_clear_flag(tech_pvt, TFLAG_VOICE); + switch_clear_flag_locked(tech_pvt, TFLAG_IO); + switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); //switch_thread_cond_signal(tech_pvt->cond); @@ -612,7 +629,7 @@ } if (switch_test_flag(tech_pvt, TFLAG_IO) && switch_test_flag(tech_pvt, TFLAG_VOICE)) { - switch_clear_flag(tech_pvt, TFLAG_VOICE); + switch_clear_flag_locked(tech_pvt, TFLAG_VOICE); if (!tech_pvt->read_frame.datalen) { continue; } @@ -737,6 +754,7 @@ if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object))) != 0) { memset(tech_pvt, 0, sizeof(*tech_pvt)); + switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session)); channel = switch_core_session_get_channel(*new_session); switch_core_session_set_private(*new_session, tech_pvt); tech_pvt->session = *new_session; @@ -781,7 +799,7 @@ caller_profile->caller_id_name, caller_profile->destination_number, NULL, 0, req, cap); switch_channel_set_flag(channel, CF_OUTBOUND); - switch_set_flag(tech_pvt, TFLAG_OUTBOUND); + switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND); switch_channel_set_state(channel, CS_INIT); return SWITCH_STATUS_SUCCESS; } @@ -988,6 +1006,7 @@ (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object))) != 0) { memset(tech_pvt, 0, sizeof(*tech_pvt)); + switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); channel = switch_core_session_get_channel(session); switch_core_session_set_private(session, tech_pvt); tech_pvt->session = session; @@ -1041,12 +1060,15 @@ case IAX_EVENT_HANGUP: if (tech_pvt) { switch_channel_t *channel; - + + switch_mutex_lock(tech_pvt->flag_mutex); switch_clear_flag(tech_pvt, TFLAG_IO); switch_clear_flag(tech_pvt, TFLAG_VOICE); + switch_mutex_unlock(tech_pvt->flag_mutex); + if ((channel = switch_core_session_get_channel(tech_pvt->session)) != 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Hangup %s\n", switch_channel_get_name(channel)); - switch_set_flag(tech_pvt, TFLAG_HANGUP); + switch_set_flag_locked(tech_pvt, TFLAG_HANGUP); switch_channel_hangup(channel, iaxevent->etype == IAX_EVENT_HANGUP ? SWITCH_CAUSE_NORMAL_CLEARING : SWITCH_CAUSE_FACILITY_REJECTED); //switch_thread_cond_signal(tech_pvt->cond); iaxevent->session = NULL; @@ -1079,7 +1101,7 @@ tech_pvt->read_frame.samples = frames * tech_pvt->read_codec.implementation->samples_per_frame; memcpy(tech_pvt->read_frame.data, iaxevent->data, iaxevent->datalen); /* wake up the i/o thread */ - switch_set_flag(tech_pvt, TFLAG_VOICE); + switch_set_flag_locked(tech_pvt, TFLAG_VOICE); //switch_thread_cond_signal(tech_pvt->cond); } } Modified: freeswitch/branches/stkn/src/mod/endpoints/mod_portaudio/mod_portaudio.c ============================================================================== --- freeswitch/branches/stkn/src/mod/endpoints/mod_portaudio/mod_portaudio.c (original) +++ freeswitch/branches/stkn/src/mod/endpoints/mod_portaudio/mod_portaudio.c Mon Jul 3 21:47:59 2006 @@ -92,6 +92,7 @@ PABLIO_Stream *audio_out; int indev; int outdev; + switch_mutex_t *flag_mutex; }; SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan) @@ -162,6 +163,7 @@ if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, MY_EVENT_RINGING) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_info", buf); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "call_id", tech_pvt->call_id); switch_channel_event_set_data(channel, event); switch_event_fire(&event); } @@ -177,7 +179,7 @@ if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND) && !switch_test_flag(tech_pvt, TFLAG_ANSWER)) { switch_channel_hangup(channel, SWITCH_CAUSE_NO_ANSWER); } else { - switch_set_flag(tech_pvt, TFLAG_IO); + switch_set_flag_locked(tech_pvt, TFLAG_IO); /* Move Channel's State Machine to RING */ switch_channel_set_state(channel, CS_RING); @@ -245,7 +247,7 @@ tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); - switch_clear_flag(tech_pvt, TFLAG_IO); + switch_clear_flag_locked(tech_pvt, TFLAG_IO); switch_core_hash_delete(globals.call_hash, tech_pvt->call_id); switch_core_codec_destroy(&tech_pvt->read_codec); @@ -269,7 +271,7 @@ tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); - switch_clear_flag(tech_pvt, TFLAG_IO); + switch_clear_flag_locked(tech_pvt, TFLAG_IO); deactivate_audio_device(tech_pvt); switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); @@ -425,7 +427,7 @@ case SWITCH_MESSAGE_INDICATE_PROGRESS: { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engage Early Media\n"); - switch_set_flag(tech_pvt, TFLAG_IO); + switch_set_flag_locked(tech_pvt, TFLAG_IO); } default: break; @@ -524,6 +526,7 @@ if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object))) != 0) { memset(tech_pvt, 0, sizeof(*tech_pvt)); + switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session)); channel = switch_core_session_get_channel(*new_session); switch_core_session_set_private(*new_session, tech_pvt); tech_pvt->session = *new_session; @@ -550,7 +553,7 @@ } switch_channel_set_flag(channel, CF_OUTBOUND); - switch_set_flag(tech_pvt, TFLAG_OUTBOUND); + switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND); switch_channel_set_state(channel, CS_INIT); return SWITCH_STATUS_SUCCESS; } @@ -838,6 +841,7 @@ switch_core_session_add_stream(session, NULL); if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object))) != 0) { memset(tech_pvt, 0, sizeof(*tech_pvt)); + switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); channel = switch_core_session_get_channel(session); switch_core_session_set_private(session, tech_pvt); tech_pvt->session = session; @@ -947,7 +951,7 @@ if ((tech_pvt = switch_core_hash_find(globals.call_hash, callid)) != 0) { channel = switch_core_session_get_channel(tech_pvt->session); assert(channel != NULL); - switch_set_flag(tech_pvt, TFLAG_ANSWER); + switch_set_flag_locked(tech_pvt, TFLAG_ANSWER); switch_channel_answer(channel); } else { stream->write_function(stream, "NO SUCH CALL"); Modified: freeswitch/branches/stkn/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c ============================================================================== --- freeswitch/branches/stkn/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c (original) +++ freeswitch/branches/stkn/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c Mon Jul 3 21:47:59 2006 @@ -116,6 +116,7 @@ switch_buffer_t *dtmf_buffer; unsigned int skip_read_frames; unsigned int skip_write_frames; + switch_mutex_t *flag_mutex; #ifdef DOTRACE int fd; int fd2; @@ -337,7 +338,7 @@ tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); - switch_set_flag(tech_pvt, TFLAG_BYE); + switch_set_flag_locked(tech_pvt, TFLAG_BYE); if (!switch_test_flag(tech_pvt, TFLAG_NOSIG)) { chanmap = tech_pvt->spri->private_info; @@ -656,9 +657,11 @@ tech_pvt = switch_core_session_get_private(session); assert(tech_pvt != NULL); - + switch_mutex_lock(tech_pvt->flag_mutex); switch_set_flag(tech_pvt, TFLAG_BYE); switch_clear_flag(tech_pvt, TFLAG_MEDIA); + switch_mutex_unlock(tech_pvt->flag_mutex); + sangoma_socket_close(&tech_pvt->socket); return SWITCH_STATUS_SUCCESS; @@ -737,6 +740,7 @@ switch_core_session_add_stream(*new_session, NULL); if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object)))) { memset(tech_pvt, 0, sizeof(*tech_pvt)); + switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session)); channel = switch_core_session_get_channel(*new_session); switch_core_session_set_private(*new_session, tech_pvt); tech_pvt->session = *new_session; @@ -806,7 +810,7 @@ switch_core_session_destroy(new_session); return SWITCH_STATUS_GENERR; } - switch_set_flag(tech_pvt, TFLAG_NOSIG); + switch_set_flag_locked(tech_pvt, TFLAG_NOSIG); snprintf(name, sizeof(name), "WanPipe/%s/nosig-%04x", bchan, rand() & 0xffff); switch_channel_set_name(channel, name); switch_channel_set_caller_profile(channel, caller_profile); @@ -901,7 +905,7 @@ } switch_channel_set_flag(channel, CF_OUTBOUND); - switch_set_flag(tech_pvt, TFLAG_OUTBOUND); + switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND); switch_channel_set_state(channel, CS_INIT); return SWITCH_STATUS_SUCCESS; } @@ -1118,6 +1122,7 @@ switch_core_session_add_stream(session, NULL); if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object)))) { memset(tech_pvt, 0, sizeof(*tech_pvt)); + switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); channel = switch_core_session_get_channel(session); switch_core_session_set_private(session, tech_pvt); sprintf(name, "s%dc%d", spri->span, event->ring.channel); @@ -1148,7 +1153,7 @@ switch_channel_set_caller_profile(channel, tech_pvt->caller_profile); } - switch_set_flag(tech_pvt, TFLAG_INBOUND); + switch_set_flag_locked(tech_pvt, TFLAG_INBOUND); tech_pvt->spri = spri; tech_pvt->cause = -1; Modified: freeswitch/branches/stkn/src/mod/endpoints/mod_woomera/mod_woomera.c ============================================================================== --- freeswitch/branches/stkn/src/mod/endpoints/mod_woomera/mod_woomera.c (original) +++ freeswitch/branches/stkn/src/mod/endpoints/mod_woomera/mod_woomera.c Mon Jul 3 21:47:59 2006 @@ -154,6 +154,7 @@ char dtmfbuf[WOOMERA_STRLEN]; switch_caller_profile_t *caller_profile; struct woomera_event_queue event_queue; + switch_mutex_t *flag_mutex; }; typedef struct private_object private_object; @@ -230,7 +231,7 @@ switch_core_session_set_write_codec(session, &tech_pvt->write_codec); - switch_set_flag(tech_pvt, TFLAG_ACTIVATE); + switch_set_flag_locked(tech_pvt, TFLAG_ACTIVATE); switch_core_session_launch_thread(session, woomera_channel_thread_run, session); @@ -483,6 +484,7 @@ if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object))) != 0) { memset(tech_pvt, 0, sizeof(*tech_pvt)); + switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session)); tech_pvt->profile = &default_profile; channel = switch_core_session_get_channel(*new_session); switch_core_session_set_private(*new_session, tech_pvt); @@ -510,7 +512,7 @@ } switch_channel_set_flag(channel, CF_OUTBOUND); - switch_set_flag(tech_pvt, TFLAG_OUTBOUND); + switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND); switch_channel_set_state(channel, CS_INIT); return SWITCH_STATUS_SUCCESS; } @@ -907,13 +909,13 @@ woomera_message_parse(tech_pvt->command_channel, &wmsg, WOOMERA_HARD_TIMEOUT, tech_pvt->profile, &tech_pvt->event_queue); } else { - switch_set_flag(tech_pvt, TFLAG_PARSE_INCOMING); + switch_set_flag_locked(tech_pvt, TFLAG_PARSE_INCOMING); woomera_printf(tech_pvt->profile, tech_pvt->command_channel, "LISTEN%s", WOOMERA_RECORD_SEPERATOR); if (woomera_message_parse(tech_pvt->command_channel, &wmsg, WOOMERA_HARD_TIMEOUT, tech_pvt->profile, &tech_pvt->event_queue) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "{%s} HELP! Woomera is broken!\n", tech_pvt->profile->name); - switch_set_flag(tech_pvt, TFLAG_ABORT); + switch_set_flag_locked(tech_pvt, TFLAG_ABORT); globals.panic = 1; } } @@ -949,7 +951,7 @@ for (;;) { if (globals.panic) { - switch_set_flag(tech_pvt, TFLAG_ABORT); + switch_set_flag_locked(tech_pvt, TFLAG_ABORT); } if (switch_test_flag(tech_pvt, TFLAG_ABORT)) { @@ -959,12 +961,12 @@ } if (switch_test_flag(tech_pvt, TFLAG_ACTIVATE)) { - switch_clear_flag(tech_pvt, TFLAG_ACTIVATE); + switch_clear_flag_locked(tech_pvt, TFLAG_ACTIVATE); tech_activate(tech_pvt); } if (switch_test_flag(tech_pvt, TFLAG_ANSWER)) { - switch_clear_flag(tech_pvt, TFLAG_ANSWER); + switch_clear_flag_locked(tech_pvt, TFLAG_ANSWER); #ifdef USE_ANSWER woomera_printf(tech_pvt->profile, tech_pvt->command_channel, "ANSWER %s%s", tech_pvt->call_info.callid, WOOMERA_RECORD_SEPERATOR); @@ -973,7 +975,7 @@ &tech_pvt->event_queue) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "{%s} HELP! Woomera is broken!\n", tech_pvt->profile->name); - switch_set_flag(tech_pvt, TFLAG_ABORT); + switch_set_flag_locked(tech_pvt, TFLAG_ABORT); globals.panic = 1; continue; } @@ -989,11 +991,11 @@ &tech_pvt->event_queue) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "{%s} HELP! Woomera is broken!\n", tech_pvt->profile->name); - switch_set_flag(tech_pvt, TFLAG_ABORT); + switch_set_flag_locked(tech_pvt, TFLAG_ABORT); globals.panic = 1; continue; } - switch_clear_flag(tech_pvt, TFLAG_DTMF); + switch_clear_flag_locked(tech_pvt, TFLAG_DTMF); memset(tech_pvt->dtmfbuf, 0, sizeof(tech_pvt->dtmfbuf)); switch_mutex_unlock(tech_pvt->iolock); } @@ -1007,7 +1009,7 @@ ((tech_pvt->started.tv_sec * 1000) + tech_pvt->started.tv_usec / 1000)); if (elapsed > tech_pvt->timeout) { /* call timed out! */ - switch_set_flag(tech_pvt, TFLAG_ABORT); + switch_set_flag_locked(tech_pvt, TFLAG_ABORT); } } #endif @@ -1020,7 +1022,7 @@ (res = woomera_message_parse(tech_pvt->command_channel, &wmsg, 100, tech_pvt->profile, NULL)) != 0) { if (res < 0 || !strcasecmp(wmsg.command, "HANGUP")) { - switch_set_flag(tech_pvt, TFLAG_ABORT); + switch_set_flag_locked(tech_pvt, TFLAG_ABORT); continue; } else if (!strcasecmp(wmsg.command, "DTMF")) { /* @@ -1043,8 +1045,8 @@ char *cid_num; char *ip; char *p; - switch_clear_flag(tech_pvt, TFLAG_PARSE_INCOMING); - switch_set_flag(tech_pvt, TFLAG_INCOMING); + switch_clear_flag_locked(tech_pvt, TFLAG_PARSE_INCOMING); + switch_set_flag_locked(tech_pvt, TFLAG_INCOMING); tech_pvt->call_info = wmsg; exten = woomera_message_header(&wmsg, "Local-Number"); @@ -1088,7 +1090,7 @@ &wmsg, WOOMERA_HARD_TIMEOUT, tech_pvt->profile, &tech_pvt->event_queue) < 0) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "{%s} HELP! Woomera is broken!\n", tech_pvt->profile->name); - switch_set_flag(tech_pvt, TFLAG_ABORT); + switch_set_flag_locked(tech_pvt, TFLAG_ABORT); globals.panic = 1; continue; } @@ -1242,6 +1244,7 @@ if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object))) != 0) { memset(tech_pvt, 0, sizeof(*tech_pvt)); + switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); tech_pvt->profile = &default_profile; channel = switch_core_session_get_channel(session); switch_core_session_set_private(session, tech_pvt); Modified: freeswitch/branches/stkn/src/switch.c ============================================================================== --- freeswitch/branches/stkn/src/switch.c (original) +++ freeswitch/branches/stkn/src/switch.c Mon Jul 3 21:47:59 2006 @@ -81,7 +81,7 @@ SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); #else int pid; - //nice(-20); + nice(-20); #endif #ifdef HAVE_MLOCKALL Modified: freeswitch/branches/stkn/src/switch_channel.c ============================================================================== --- freeswitch/branches/stkn/src/switch_channel.c (original) +++ freeswitch/branches/stkn/src/switch_channel.c Mon Jul 3 21:47:59 2006 @@ -90,6 +90,7 @@ char *name; switch_buffer_t *dtmf_buffer; switch_mutex_t *dtmf_mutex; + switch_mutex_t *flag_mutex; switch_mutex_t *profile_mutex; switch_core_session_t *session; switch_channel_state_t state; @@ -162,6 +163,7 @@ switch_core_hash_init(&(*channel)->variables, pool); switch_buffer_create(pool, &(*channel)->dtmf_buffer, 128); switch_mutex_init(&(*channel)->dtmf_mutex, SWITCH_MUTEX_NESTED, pool); + switch_mutex_init(&(*channel)->flag_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&(*channel)->profile_mutex, SWITCH_MUTEX_NESTED, pool); (*channel)->hangup_cause = SWITCH_CAUSE_UNALLOCATED; @@ -352,13 +354,13 @@ SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flags) { assert(channel != NULL); - switch_set_flag(channel, flags); + switch_set_flag_locked(channel, flags); } SWITCH_DECLARE(void) switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flags) { assert(channel != NULL); - switch_clear_flag(channel, flags); + switch_clear_flag_locked(channel, flags); } SWITCH_DECLARE(switch_channel_state_t) switch_channel_get_state(switch_channel_t *channel) Modified: freeswitch/branches/stkn/src/switch_core.c ============================================================================== --- freeswitch/branches/stkn/src/switch_core.c (original) +++ freeswitch/branches/stkn/src/switch_core.c Mon Jul 3 21:47:59 2006 @@ -370,7 +370,7 @@ return SWITCH_STATUS_SUCCESS; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Codec %s Exists but not then desired implementation.\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Codec %s Exists but not at the desired implementation.\n", codec_name); } @@ -1057,9 +1057,13 @@ int timeout, int stream_id) { switch_io_event_hook_read_frame_t *ptr; - switch_status_t status = SWITCH_STATUS_FALSE; - int need_codec = 0, perfect = 0; - + switch_status_t status; + int need_codec, perfect; + top: + + status = SWITCH_STATUS_FALSE; + need_codec = perfect = 0; + assert(session != NULL); *frame = NULL; @@ -1180,18 +1184,22 @@ session->raw_read_frame.rate = (*frame)->rate; } else { session->raw_read_frame.datalen = (uint32_t)switch_buffer_read(session->raw_read_buffer, - session->raw_read_frame.data, - session->read_codec->implementation-> - bytes_per_frame); + session->raw_read_frame.data, + session->read_codec->implementation->bytes_per_frame); + session->raw_read_frame.rate = session->read_codec->implementation->samples_per_second; enc_frame = &session->raw_read_frame; } session->enc_read_frame.datalen = session->enc_read_frame.buflen; + assert(session->read_codec != NULL); + assert(enc_frame != NULL); + assert(enc_frame->data != NULL); + status = switch_core_codec_encode(session->read_codec, enc_frame->codec, enc_frame->data, enc_frame->datalen, - enc_frame->codec->implementation->samples_per_second, + session->read_codec->implementation->samples_per_second, session->enc_read_frame.data, &session->enc_read_frame.datalen, &session->enc_read_frame.rate, @@ -1215,6 +1223,8 @@ status = SWITCH_STATUS_GENERR; break; } + } else { + goto top; } } } Modified: freeswitch/branches/stkn/src/switch_ivr.c ============================================================================== --- freeswitch/branches/stkn/src/switch_ivr.c (original) +++ freeswitch/branches/stkn/src/switch_ivr.c Mon Jul 3 21:47:59 2006 @@ -538,6 +538,7 @@ flags = 0; switch_sleep(200000); switch_core_speech_feed_tts(sh, text, &flags); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Speaking text: %s\n", text); write_frame.rate = sh->rate; @@ -1122,6 +1123,7 @@ switch_channel_get_name(caller_channel), switch_channel_get_name(peer_channel) ); + switch_channel_hangup(peer_channel, SWITCH_CAUSE_NO_ANSWER); } return status; Modified: freeswitch/branches/stkn/src/switch_loadable_module.c ============================================================================== --- freeswitch/branches/stkn/src/switch_loadable_module.c (original) +++ freeswitch/branches/stkn/src/switch_loadable_module.c Mon Jul 3 21:47:59 2006 @@ -109,16 +109,19 @@ for (impl = ptr->implementations; impl; impl = impl->next) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Adding Codec '%s' (%s) %dkhz %dms\n", - ptr->iananame, + impl->iananame, ptr->interface_name, impl->samples_per_second, impl->microseconds_per_frame / 1000); + if (!switch_core_hash_find(loadable_modules.codec_hash, (char *) impl->iananame)) { + switch_core_hash_insert(loadable_modules.codec_hash, (char *) impl->iananame, (void *) ptr); + } } if (switch_event_create(&event, SWITCH_EVENT_MODULE_LOAD) == SWITCH_STATUS_SUCCESS) { switch_event_add_header(event, SWITCH_STACK_BOTTOM, "type", "codec"); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "name", "%s", ptr->interface_name); switch_event_fire(&event); } - switch_core_hash_insert(loadable_modules.codec_hash, (char *) ptr->iananame, (void *) ptr); + } } Modified: freeswitch/branches/stkn/src/switch_rtp.c ============================================================================== --- freeswitch/branches/stkn/src/switch_rtp.c (original) +++ freeswitch/branches/stkn/src/switch_rtp.c Mon Jul 3 21:47:59 2006 @@ -1082,7 +1082,7 @@ } if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_VAD) && - rtp_session->recv_msg.header.pt == rtp_session->vad_data.read_codec->codec_interface->ianacode && + rtp_session->recv_msg.header.pt == rtp_session->vad_data.read_codec->implementation->ianacode && datalen == rtp_session->vad_data.read_codec->implementation->encoded_bytes_per_frame) { int16_t decoded[SWITCH_RECCOMMENDED_BUFFER_SIZE/sizeof(int16_t)]; uint32_t rate; @@ -1241,7 +1241,7 @@ memset(&rtp_session->vad_data, 0, sizeof(rtp_session->vad_data)); if (switch_core_codec_init(&rtp_session->vad_data.vad_codec, - codec->codec_interface->iananame, + codec->implementation->iananame, codec->implementation->samples_per_second, codec->implementation->microseconds_per_frame / 1000, codec->implementation->number_of_channels, Modified: freeswitch/branches/stkn/src/switch_xml.c ============================================================================== --- freeswitch/branches/stkn/src/switch_xml.c (original) +++ freeswitch/branches/stkn/src/switch_xml.c Mon Jul 3 21:47:59 2006 @@ -1001,26 +1001,32 @@ return *dst; } +#define XML_INDENT " " // Recursively converts each tag to xml appending it to *s. Reallocates *s if // its length excedes max. start is the location of the previous tag in the // parent tag's character content. Returns *s. static char *switch_xml_toxml_r(switch_xml_t xml, char **s, switch_size_t *len, switch_size_t *max, - switch_size_t start, char ***attr) + switch_size_t start, char ***attr, uint32_t *count) { int i, j; char *txt = (xml->parent) ? xml->parent->txt : ""; switch_size_t off = 0; + uint32_t lcount = 0; // parent character content up to this tag *s = switch_xml_ampencode(txt + start, xml->off - start, s, len, max, 0); - while (*len + strlen(xml->name) + 4 > *max) // reallocate s + while (*len + strlen(xml->name) + 5 + (strlen(XML_INDENT) * (*count)) > *max) // reallocate s *s = realloc(*s, *max += SWITCH_XML_BUFSIZE); + for (lcount = 0; lcount < *count; lcount++) { + *len += sprintf(*s + *len, "%s", XML_INDENT); // indent + } + *len += sprintf(*s + *len, "<%s", xml->name); // open tag for (i = 0; xml->attr[i]; i += 2) { // tag attributes if (switch_xml_attr(xml, xml->attr[i]) != xml->attr[i + 1]) continue; - while (*len + strlen(xml->attr[i]) + 7 > *max) // reallocate s + while (*len + strlen(xml->attr[i]) + 7 + (strlen(XML_INDENT) * (*count)) > *max) // reallocate s *s = realloc(*s, *max += SWITCH_XML_BUFSIZE); *len += sprintf(*s + *len, " %s=\"", xml->attr[i]); @@ -1032,26 +1038,43 @@ for (j = 1; attr[i] && attr[i][j]; j += 3) { // default attributes if (! attr[i][j + 1] || switch_xml_attr(xml, attr[i][j]) != attr[i][j + 1]) continue; // skip duplicates and non-values - while (*len + strlen(attr[i][j]) + 7 > *max) // reallocate s + while (*len + strlen(attr[i][j]) + 8 + (strlen(XML_INDENT) * (*count)) > *max) // reallocate s *s = realloc(*s, *max += SWITCH_XML_BUFSIZE); *len += sprintf(*s + *len, " %s=\"", attr[i][j]); switch_xml_ampencode(attr[i][j + 1], 0, s, len, max, 1); *len += sprintf(*s + *len, "\""); } - *len += sprintf(*s + *len, ">"); + *len += sprintf(*s + *len, xml->child ? ">\n" : "/>\n"); - *s = (xml->child) ? switch_xml_toxml_r(xml->child, s, len, max, 0, attr) //child - : switch_xml_ampencode(xml->txt, 0, s, len, max, 0); //data - - while (*len + strlen(xml->name) + 4 > *max) // reallocate s + if (xml->child) { + (*count)++; + *s = switch_xml_toxml_r(xml->child, s, len, max, 0, attr, count); + } else { + *s = switch_xml_ampencode(xml->txt, 0, s, len, max, 0); //data + } + + while (*len + strlen(xml->name) + 5 + (strlen(XML_INDENT) * (*count)) > *max) // reallocate s *s = realloc(*s, *max += SWITCH_XML_BUFSIZE); - *len += sprintf(*s + *len, "</%s>", xml->name); // close tag + if (xml->child) { + for (lcount = 0; lcount < *count; lcount++) { + *len += sprintf(*s + *len, "%s", XML_INDENT); // indent + } + *len += sprintf(*s + (*len), "</%s>\n", xml->name); // close tag + } + while (txt[off] && off < xml->off) off++; // make sure off is within bounds - return (xml->ordered) ? switch_xml_toxml_r(xml->ordered, s, len, max, off, attr) - : switch_xml_ampencode(txt + off, 0, s, len, max, 0); + + if (xml->ordered) { + return switch_xml_toxml_r(xml->ordered, s, len, max, off, attr, count); + + } else { + if (*count > 0) + (*count)--; + return switch_xml_ampencode(txt + off, 0, s, len, max, 0); + } } // converts an switch_xml structure back to xml, returning it as a string that must @@ -1063,6 +1086,7 @@ switch_size_t len = 0, max = SWITCH_XML_BUFSIZE; char *s = strcpy(malloc(max), ""), *t, *n; int i, j, k; + uint32_t count = 0; if (! xml || ! xml->name) return realloc(s, len + 1); while (root->xml.parent) root = (switch_xml_root_t)root->xml.parent; // root tag @@ -1073,12 +1097,12 @@ if (root->pi[i][k][j - 1] == '>') continue; // not pre-root while (len + strlen(t = root->pi[i][0]) + strlen(n) + 7 > max) s = realloc(s, max += SWITCH_XML_BUFSIZE); - len += sprintf(s + len, "<?%s%s%s?>\n", t, *n ? " " : "", n); + len += sprintf(s + len, "<?%s%s%s?>", t, *n ? " " : "", n); } } xml->parent = xml->ordered = NULL; - s = switch_xml_toxml_r(xml, &s, &len, &max, 0, root->attr); + s = switch_xml_toxml_r(xml, &s, &len, &max, 0, root->attr, &count); xml->parent = p; xml->ordered = o;
participants (1)
-
Freeswitch SVN