From 397bf1bffc073bca2deb1d68414b5515d1aca377 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 2 May 2006 16:43:13 +0000 Subject: [PATCH] change dingaling to break everybody git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@1318 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- conf/freeswitch.conf | 2 + libs/libdingaling/src/libdingaling.c | 5 + libs/libdingaling/src/libdingaling.h | 7 + .../endpoints/mod_dingaling/mod_dingaling.c | 310 +++++++++++++----- 4 files changed, 233 insertions(+), 91 deletions(-) diff --git a/conf/freeswitch.conf b/conf/freeswitch.conf index f94f5864c2..037943d158 100644 --- a/conf/freeswitch.conf +++ b/conf/freeswitch.conf @@ -254,6 +254,7 @@ debug => 0 codec_prefs => PCMU ; *NOTE* your resource (after the /) MUST contain the string "talk" (upper or lower case is ok) +; *NOTE* as of May 2 2006 you must set auto-login => true if you want to be able to auto-login on startup [interface] name => google @@ -262,6 +263,7 @@ codec_prefs => PCMU dialplan => demo message => Jingle all the way rtp-ip => 0.0.0.0 + auto-login => true ; or ; ;rtp-ip => my_lan_ip ;ext-rtp-ip => stun:stun.server.com diff --git a/libs/libdingaling/src/libdingaling.c b/libs/libdingaling/src/libdingaling.c index ed83486cca..827a40bd59 100644 --- a/libs/libdingaling/src/libdingaling.c +++ b/libs/libdingaling/src/libdingaling.c @@ -1186,6 +1186,11 @@ void ldl_handle_run(ldl_handle_t *handle) ldl_clear_flag(handle, LDL_FLAG_RUNNING); } +void ldl_handle_stop(ldl_handle_t *handle) +{ + ldl_clear_flag(handle, LDL_FLAG_RUNNING); +} + ldl_status ldl_handle_destroy(ldl_handle_t **handle) { apr_pool_t *pool = (*handle)->pool; diff --git a/libs/libdingaling/src/libdingaling.h b/libs/libdingaling/src/libdingaling.h index 687e1841cc..6ef4b5e3e7 100644 --- a/libs/libdingaling/src/libdingaling.h +++ b/libs/libdingaling/src/libdingaling.h @@ -383,6 +383,13 @@ ldl_status ldl_handle_init(ldl_handle_t **handle, */ void ldl_handle_run(ldl_handle_t *handle); +/*! + \brief Stop a libDingaLing handle + \param handle the Dingaling handle to stop +*/ +void ldl_handle_stop(ldl_handle_t *handle); + + /*! \brief Destroy a libDingaLing handle \param handle the Dingaling handle to destroy diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 1b95b64bf4..89ebe41b05 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -61,7 +61,8 @@ typedef enum { TFLAG_VAD = ( 1 << 13), TFLAG_DO_CAND = ( 1 << 14), TFLAG_DO_DESC = (1 << 15), - TFLAG_LANADDR = (1 << 16) + TFLAG_LANADDR = (1 << 16), + TFLAG_AUTO = (1 << 17) } TFLAGS; typedef enum { @@ -85,18 +86,18 @@ static struct { } globals; struct mdl_profile { - char *name; - char *login; - char *password; - char *message; - char *dialplan; - char *ip; - char *extip; - char *lanaddr; - char *exten; - char *context; - ldl_handle_t *handle; - unsigned int flags; + char *name; + char *login; + char *password; + char *message; + char *dialplan; + char *ip; + char *extip; + char *lanaddr; + char *exten; + char *context; + ldl_handle_t *handle; + unsigned int flags; }; struct private_object { @@ -149,28 +150,29 @@ struct rfc2833_digit { }; -SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan) - SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string) - SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_rates_string, globals.codec_rates_string) +SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_dialplan, globals.dialplan); +SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_string, globals.codec_string); +SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_global_codec_rates_string, globals.codec_rates_string); +static switch_status_t dl_login(char *arg, char *out, size_t outlen); +static switch_status_t dl_logout(char *profile_name, char *out, size_t outlen); +static switch_status_t channel_on_init(switch_core_session_t *session); +static switch_status_t channel_on_hangup(switch_core_session_t *session); +static switch_status_t channel_on_ring(switch_core_session_t *session); +static switch_status_t channel_on_loopback(switch_core_session_t *session); +static switch_status_t channel_on_transmit(switch_core_session_t *session); +static switch_status_t channel_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, + switch_core_session_t **new_session, switch_memory_pool_t *pool); +static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, + switch_io_flag_t flags, int stream_id); +static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, + switch_io_flag_t flags, int stream_id); +static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); +static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t signal, char *from, char *subject, char *msg); +static ldl_status handle_response(ldl_handle_t *handle, char *id); +static switch_status_t load_config(void); - static switch_status_t channel_on_init(switch_core_session_t *session); - static switch_status_t channel_on_hangup(switch_core_session_t *session); - static switch_status_t channel_on_ring(switch_core_session_t *session); - static switch_status_t channel_on_loopback(switch_core_session_t *session); - static switch_status_t channel_on_transmit(switch_core_session_t *session); - static switch_status_t channel_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t *pool); - static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, - switch_io_flag_t flags, int stream_id); - static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, - switch_io_flag_t flags, int stream_id); - static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig); - static ldl_status handle_signalling(ldl_handle_t *handle, ldl_session_t *dlsession, ldl_signal_t signal, char *from, char *subject, char *msg); - static ldl_status handle_response(ldl_handle_t *handle, char *id); - static switch_status_t load_config(void); - - static void dl_logger(char *file, const char *func, int line, int level, char *fmt, ...) +static void dl_logger(char *file, const char *func, int line, int level, char *fmt, ...) { va_list ap; char data[1024]; @@ -212,7 +214,9 @@ static void *SWITCH_THREAD_FUNC handle_thread_run(switch_thread_t *thread, void profile = ldl_handle_get_private(handle); globals.handles++; + switch_set_flag(profile, TFLAG_IO); ldl_handle_run(handle); + switch_clear_flag(profile, TFLAG_IO); globals.handles--; ldl_handle_destroy(&handle); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Handle %s [%s] Destroyed\n", profile->name, profile->login); @@ -715,7 +719,7 @@ static switch_status_t channel_send_dtmf(switch_core_session_t *session, char *d } static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, - switch_io_flag_t flags, int stream_id) + switch_io_flag_t flags, int stream_id) { struct private_object *tech_pvt = NULL; uint32_t bytes = 0; @@ -812,7 +816,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch } static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, - switch_io_flag_t flags, int stream_id) + switch_io_flag_t flags, int stream_id) { struct private_object *tech_pvt; switch_channel_t *channel = NULL; @@ -1000,13 +1004,32 @@ static const switch_endpoint_interface_t channel_endpoint_interface = { /*.next */ NULL }; + + +static switch_api_interface_t logout_api_interface = { + /*.interface_name */ "dl_logout", + /*.desc */ "DingaLing Logout", + /*.function */ dl_logout, + /*.next */ NULL +}; + +static switch_api_interface_t login_api_interface = { + /*.interface_name */ "dl_login", + /*.desc */ "DingaLing Login", + /*.function */ dl_login, + /*.next */ &logout_api_interface +}; + + + static const switch_loadable_module_interface_t channel_module_interface = { /*.module_name */ modname, /*.endpoint_interface */ &channel_endpoint_interface, /*.timer_interface */ NULL, /*.dialplan_interface */ NULL, /*.codec_interface */ NULL, - /*.application_interface */ NULL + /*.application_interface */ NULL, + /*.api_interface */ &login_api_interface }; @@ -1014,7 +1037,7 @@ static const switch_loadable_module_interface_t channel_module_interface = { that allocate memory or you will have 1 channel with memory allocated from another channel's pool! */ static switch_status_t channel_outgoing_channel(switch_core_session_t *session, switch_caller_profile_t *outbound_profile, - switch_core_session_t **new_session, switch_memory_pool_t *pool) + switch_core_session_t **new_session, switch_memory_pool_t *pool) { if ((*new_session = switch_core_session_request(&channel_endpoint_interface, pool)) != 0) { struct private_object *tech_pvt; @@ -1149,7 +1172,8 @@ static ldl_status handle_loop(ldl_handle_t *handle) } return LDL_STATUS_SUCCESS; } -static void init_profile(struct mdl_profile *profile) + +static switch_status_t init_profile(struct mdl_profile *profile, uint8_t login) { if (profile && profile->login && @@ -1161,23 +1185,46 @@ static void init_profile(struct mdl_profile *profile) profile->exten) { ldl_handle_t *handle; - - if (ldl_handle_init(&handle, - profile->login, - profile->password, - profile->message, - handle_loop, - handle_signalling, - handle_response, - profile) == LDL_STATUS_SUCCESS) { - profile->handle = handle; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Started Thread for %s@%s\n", profile->login, profile->dialplan); + if (login) { + if (ldl_handle_init(&handle, + profile->login, + profile->password, + profile->message, + handle_loop, + handle_signalling, + handle_response, + profile) == LDL_STATUS_SUCCESS) { + profile->handle = handle; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Started Thread for %s@%s\n", profile->login, profile->dialplan); + switch_core_hash_insert(globals.profile_hash, profile->name, profile); + handle_thread_launch(handle); + } + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Created Profile for %s@%s\n", profile->login, profile->dialplan); switch_core_hash_insert(globals.profile_hash, profile->name, profile); - handle_thread_launch(handle); - } + } } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Invalid Profile\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, + "Invalid Profile\n" + "login[%s]\n" + "pass[%s]\n" + "dialplan[%s]\n" + "message[%s]\n" + "rtp-ip[%s]\n" + "name[%s]\n" + "exten[%s]\n", + profile->login, + profile->password, + profile->dialplan, + profile->message, + profile->ip, + profile->name, + profile->exten); + + return SWITCH_STATUS_FALSE; } + + return SWITCH_STATUS_SUCCESS; } @@ -1199,6 +1246,111 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void) } +static void set_profile_val(struct mdl_profile *profile, char *var, char *val) +{ + + if (!strcasecmp(var, "login")) { + profile->login = switch_core_strdup(module_pool, val); + } else if (!strcasecmp(var, "password")) { + profile->password = switch_core_strdup(module_pool, val); + } else if (!strcasecmp(var, "dialplan")) { + profile->dialplan = switch_core_strdup(module_pool, val); + } else if (!strcasecmp(var, "name")) { + profile->name = switch_core_strdup(module_pool, val); + } else if (!strcasecmp(var, "message")) { + profile->message = switch_core_strdup(module_pool, val); + } else if (!strcasecmp(var, "rtp-ip")) { + profile->ip = switch_core_strdup(module_pool, val); + } else if (!strcasecmp(var, "ext-rtp-ip")) { + profile->extip = switch_core_strdup(module_pool, val); + } else if (!strcasecmp(var, "lanaddr")) { + profile->lanaddr = switch_core_strdup(module_pool, val); + } else if (!strcasecmp(var, "exten")) { + profile->exten = switch_core_strdup(module_pool, val); + } else if (!strcasecmp(var, "context")) { + profile->context = switch_core_strdup(module_pool, val); + } else if (!strcasecmp(var, "auto-login")) { + if (switch_true(val)) { + switch_set_flag(profile, TFLAG_AUTO); + } + } else if (!strcasecmp(var, "vad")) { + if (!strcasecmp(val, "in")) { + switch_set_flag(profile, TFLAG_VAD_IN); + } else if (!strcasecmp(val, "out")) { + switch_set_flag(profile, TFLAG_VAD_OUT); + } else if (!strcasecmp(val, "both")) { + switch_set_flag(profile, TFLAG_VAD_IN); + switch_set_flag(profile, TFLAG_VAD_OUT); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invald option %s for VAD\n", val); + } + } +} + +static switch_status_t dl_logout(char *profile_name, char *out, size_t outlen) +{ + struct mdl_profile *profile; + if ((profile = switch_core_hash_find(globals.profile_hash, profile_name))) { + ldl_handle_stop(profile->handle); + snprintf(out, outlen, "OK\n"); + } else { + snprintf(out, outlen, "NO SUCH PROFILE %s\n", profile_name); + } + + return SWITCH_STATUS_SUCCESS; +} + +static switch_status_t dl_login(char *arg, char *out, size_t outlen) +{ + char *argv[10] = {0}; + int argc = 0; + char *var, *val, *myarg; + struct mdl_profile *profile = NULL; + int x; + + if (switch_strlen_zero(arg)) { + snprintf(out, outlen, "FAIL\n"); + return SWITCH_STATUS_SUCCESS; + } + + myarg = strdup(arg); + + argc = switch_separate_string(myarg, ';', argv, (sizeof(argv) / sizeof(argv[0]))); + + if (!strncasecmp(argv[0], "profile=", 8)) { + char *profile_name = argv[0] + 8; + profile = switch_core_hash_find(globals.profile_hash, profile_name); + + if (profile) { + if (switch_test_flag(profile, TFLAG_IO)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile already exists."); + snprintf(out, outlen, "Profile already exists\n"); + return SWITCH_STATUS_SUCCESS; + } + + } + } else { + profile = switch_core_alloc(module_pool, sizeof(*profile)); + + for(x = 0; x < argc; x++) { + var = argv[x]; + if ((val = strchr(var, '='))) { + *val++ = '\0'; + set_profile_val(profile, var, val); + } + } + } + + if (profile && init_profile(profile, 1) == SWITCH_STATUS_SUCCESS) { + snprintf(out, outlen, "OK\n"); + } else { + snprintf(out, outlen, "FAIL\n"); + } + + return SWITCH_STATUS_SUCCESS; + +} + static switch_status_t load_config(void) { switch_config_t cfg; @@ -1210,6 +1362,7 @@ static switch_status_t load_config(void) memset(&globals, 0, sizeof(globals)); globals.running = 1; + switch_core_hash_init(&globals.profile_hash, module_pool); if (!switch_config_open_file(&cfg, cf)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "open of %s failed\n", cf); @@ -1218,28 +1371,28 @@ static switch_status_t load_config(void) while (switch_config_next_pair(&cfg, &var, &val)) { if (!strcasecmp(cfg.category, "settings")) { - if (!strcmp(var, "debug")) { + if (!strcasecmp(var, "debug")) { globals.debug = atoi(val); - } else if (!strcmp(var, "codec_prefs")) { + } else if (!strcasecmp(var, "codec_prefs")) { set_global_codec_string(val); globals.codec_order_last = switch_separate_string(globals.codec_string, ',', globals.codec_order, SWITCH_MAX_CODECS); - } else if (!strcmp(var, "codec_rates")) { + } else if (!strcasecmp(var, "codec_rates")) { set_global_codec_rates_string(val); globals.codec_rates_last = switch_separate_string(globals.codec_rates_string, ',', globals.codec_rates, SWITCH_MAX_CODECS); } } else if (!strcasecmp(cfg.category, "interface")) { + if (!globals.init) { ldl_global_init(globals.debug); ldl_global_set_logger(dl_logger); globals.init = 1; } - if (cfg.catno != lastcat) { if (profile) { - init_profile(profile); + init_profile(profile, switch_test_flag(profile, TFLAG_AUTO) ? 1 : 0); profile = NULL; } lastcat = cfg.catno; @@ -1248,44 +1401,12 @@ static switch_status_t load_config(void) if(!profile) { profile = switch_core_alloc(module_pool, sizeof(*profile)); } - - if (!strcmp(var, "login")) { - profile->login = switch_core_strdup(module_pool, val); - } else if (!strcmp(var, "password")) { - profile->password = switch_core_strdup(module_pool, val); - } else if (!strcmp(var, "dialplan")) { - profile->dialplan = switch_core_strdup(module_pool, val); - } else if (!strcmp(var, "name")) { - profile->name = switch_core_strdup(module_pool, val); - } else if (!strcmp(var, "message")) { - profile->message = switch_core_strdup(module_pool, val); - } else if (!strcmp(var, "rtp-ip")) { - profile->ip = switch_core_strdup(module_pool, val); - } else if (!strcmp(var, "ext-rtp-ip")) { - profile->extip = switch_core_strdup(module_pool, val); - } else if (!strcmp(var, "lanaddr")) { - profile->lanaddr = switch_core_strdup(module_pool, val); - } else if (!strcmp(var, "exten")) { - profile->exten = switch_core_strdup(module_pool, val); - } else if (!strcmp(var, "context")) { - profile->context = switch_core_strdup(module_pool, val); - } else if (!strcmp(var, "vad")) { - if (!strcasecmp(val, "in")) { - switch_set_flag(profile, TFLAG_VAD_IN); - } else if (!strcasecmp(val, "out")) { - switch_set_flag(profile, TFLAG_VAD_OUT); - } else if (!strcasecmp(val, "both")) { - switch_set_flag(profile, TFLAG_VAD_IN); - switch_set_flag(profile, TFLAG_VAD_OUT); - } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invald option %s for VAD\n", val); - } - } + set_profile_val(profile, var, val); } } if (profile) { - init_profile(profile); + init_profile(profile, switch_test_flag(profile, TFLAG_AUTO) ? 1 : 0); profile = NULL; } @@ -1293,6 +1414,13 @@ static switch_status_t load_config(void) set_global_dialplan("default"); } + if (!globals.init) { + ldl_global_init(globals.debug); + ldl_global_set_logger(dl_logger); + globals.init = 1; + } + + switch_config_close_file(&cfg); return SWITCH_STATUS_SUCCESS; }