2006-03-31 19:38:09 +00:00
|
|
|
/*
|
|
|
|
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
|
|
|
* Copyright (C) 2005/2006, Anthony Minessale II <anthmct@yahoo.com>
|
|
|
|
*
|
|
|
|
* Version: MPL 1.1
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
|
|
|
*
|
|
|
|
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is
|
|
|
|
* Anthony Minessale II <anthmct@yahoo.com>
|
|
|
|
* Portions created by the Initial Developer are Copyright (C)
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
*
|
|
|
|
* Anthony Minessale II <anthmct@yahoo.com>
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* mod_dingaling.c -- Jingle Endpoint Module
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include <switch.h>
|
2007-06-20 09:02:30 +00:00
|
|
|
#include <switch_stun.h>
|
2006-03-31 19:38:09 +00:00
|
|
|
#include <libdingaling.h>
|
2007-04-04 17:32:56 +00:00
|
|
|
#ifdef SWITCH_HAVE_ODBC
|
|
|
|
#include <switch_odbc.h>
|
|
|
|
#endif
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-04-13 23:19:33 +00:00
|
|
|
#define DL_CAND_WAIT 10000000
|
2006-04-15 05:56:23 +00:00
|
|
|
#define DL_CAND_INITIAL_WAIT 2000000
|
2006-05-01 18:55:04 +00:00
|
|
|
|
|
|
|
#define DL_EVENT_LOGIN_SUCCESS "dingaling::login_success"
|
|
|
|
#define DL_EVENT_LOGIN_FAILURE "dingaling::login_failure"
|
2006-06-22 21:57:40 +00:00
|
|
|
#define DL_EVENT_CONNECTED "dingaling::connected"
|
2006-10-20 22:11:26 +00:00
|
|
|
#define MDL_CHAT_PROTO "jingle"
|
2006-05-01 18:55:04 +00:00
|
|
|
|
2007-06-13 17:06:10 +00:00
|
|
|
SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load);
|
|
|
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dingaling_shutdown);
|
|
|
|
SWITCH_MODULE_DEFINITION(mod_dingaling, mod_dingaling_load, mod_dingaling_shutdown, NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-04-29 01:00:52 +00:00
|
|
|
static switch_memory_pool_t *module_pool = NULL;
|
2007-10-29 18:10:06 +00:00
|
|
|
switch_endpoint_interface_t *dingaling_endpoint_interface;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-10-18 22:57:35 +00:00
|
|
|
static char sub_sql[] =
|
2007-04-04 17:32:56 +00:00
|
|
|
"CREATE TABLE jabber_subscriptions (\n"
|
|
|
|
" sub_from VARCHAR(255),\n"
|
|
|
|
" sub_to VARCHAR(255),\n"
|
|
|
|
" show_pres VARCHAR(255),\n"
|
|
|
|
" status VARCHAR(255)\n"
|
2007-03-30 00:15:25 +00:00
|
|
|
");\n";
|
2006-10-18 22:57:35 +00:00
|
|
|
|
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
typedef enum {
|
|
|
|
TFLAG_IO = (1 << 0),
|
|
|
|
TFLAG_INBOUND = (1 << 1),
|
|
|
|
TFLAG_OUTBOUND = (1 << 2),
|
|
|
|
TFLAG_READING = (1 << 3),
|
|
|
|
TFLAG_WRITING = (1 << 4),
|
|
|
|
TFLAG_BYE = (1 << 5),
|
|
|
|
TFLAG_VOICE = (1 << 6),
|
|
|
|
TFLAG_RTP_READY = (1 << 7),
|
|
|
|
TFLAG_CODEC_READY = (1 << 8),
|
2006-04-15 22:30:25 +00:00
|
|
|
TFLAG_TRANSPORT = (1 << 9),
|
|
|
|
TFLAG_ANSWER = (1 << 10),
|
2007-03-29 22:31:56 +00:00
|
|
|
TFLAG_VAD_IN = (1 << 11),
|
|
|
|
TFLAG_VAD_OUT = (1 << 12),
|
|
|
|
TFLAG_VAD = (1 << 13),
|
|
|
|
TFLAG_DO_CAND = (1 << 14),
|
2006-04-27 15:59:58 +00:00
|
|
|
TFLAG_DO_DESC = (1 << 15),
|
2006-05-02 16:43:13 +00:00
|
|
|
TFLAG_LANADDR = (1 << 16),
|
2006-05-04 01:08:03 +00:00
|
|
|
TFLAG_AUTO = (1 << 17),
|
2006-05-24 16:10:05 +00:00
|
|
|
TFLAG_DTMF = (1 << 18),
|
2007-03-29 22:31:56 +00:00
|
|
|
TFLAG_TIMER = (1 << 19),
|
|
|
|
TFLAG_TERM = (1 << 20),
|
2006-08-18 21:02:40 +00:00
|
|
|
TFLAG_TRANSPORT_ACCEPT = (1 << 21),
|
2006-10-10 00:11:41 +00:00
|
|
|
TFLAG_READY = (1 << 22),
|
2006-03-31 19:38:09 +00:00
|
|
|
} TFLAGS;
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
GFLAG_MY_CODEC_PREFS = (1 << 0)
|
|
|
|
} GFLAGS;
|
|
|
|
|
|
|
|
static struct {
|
|
|
|
int debug;
|
|
|
|
char *dialplan;
|
|
|
|
char *codec_string;
|
|
|
|
char *codec_order[SWITCH_MAX_CODECS];
|
|
|
|
int codec_order_last;
|
|
|
|
char *codec_rates_string;
|
|
|
|
char *codec_rates[SWITCH_MAX_CODECS];
|
|
|
|
int codec_rates_last;
|
|
|
|
unsigned int flags;
|
|
|
|
unsigned int init;
|
2006-04-29 01:00:52 +00:00
|
|
|
switch_hash_t *profile_hash;
|
2006-03-31 19:38:09 +00:00
|
|
|
int running;
|
|
|
|
int handles;
|
2007-03-29 22:31:56 +00:00
|
|
|
char guess_ip[80];
|
2006-03-31 19:38:09 +00:00
|
|
|
} globals;
|
|
|
|
|
|
|
|
struct mdl_profile {
|
2007-03-29 22:31:56 +00:00
|
|
|
char *name;
|
|
|
|
char *login;
|
|
|
|
char *password;
|
|
|
|
char *message;
|
2007-04-07 21:13:54 +00:00
|
|
|
#ifdef AUTO_REPLY
|
2006-10-12 14:06:09 +00:00
|
|
|
char *auto_reply;
|
2007-04-07 21:13:54 +00:00
|
|
|
#endif
|
2007-03-29 22:31:56 +00:00
|
|
|
char *dialplan;
|
|
|
|
char *ip;
|
|
|
|
char *extip;
|
|
|
|
char *lanaddr;
|
2006-08-11 00:24:38 +00:00
|
|
|
char *server;
|
2007-03-29 22:31:56 +00:00
|
|
|
char *exten;
|
|
|
|
char *context;
|
2006-09-12 22:23:45 +00:00
|
|
|
char *timer_name;
|
2006-10-18 22:57:35 +00:00
|
|
|
char *dbname;
|
2007-04-04 22:22:55 +00:00
|
|
|
char *avatar;
|
2007-04-04 17:32:56 +00:00
|
|
|
#ifdef SWITCH_HAVE_ODBC
|
|
|
|
char *odbc_dsn;
|
|
|
|
char *odbc_user;
|
|
|
|
char *odbc_pass;
|
|
|
|
switch_odbc_handle_t *master_odbc;
|
2007-04-04 22:22:55 +00:00
|
|
|
#else
|
|
|
|
void *filler1;
|
|
|
|
void *filler2;
|
|
|
|
void *filler3;
|
|
|
|
void *filler4;
|
2007-04-04 17:32:56 +00:00
|
|
|
#endif
|
2006-10-18 22:57:35 +00:00
|
|
|
switch_mutex_t *mutex;
|
2007-03-29 22:31:56 +00:00
|
|
|
ldl_handle_t *handle;
|
|
|
|
uint32_t flags;
|
|
|
|
uint32_t user_flags;
|
2006-03-31 19:38:09 +00:00
|
|
|
};
|
2007-04-04 17:32:56 +00:00
|
|
|
typedef struct mdl_profile mdl_profile_t;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
struct private_object {
|
|
|
|
unsigned int flags;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_codec_t read_codec;
|
|
|
|
switch_codec_t write_codec;
|
|
|
|
switch_frame_t read_frame;
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_core_session_t *session;
|
|
|
|
switch_caller_profile_t *caller_profile;
|
2006-03-31 19:38:09 +00:00
|
|
|
unsigned short samprate;
|
|
|
|
switch_mutex_t *mutex;
|
2006-07-10 22:08:02 +00:00
|
|
|
const switch_codec_implementation_t *codecs[SWITCH_MAX_CODECS];
|
2006-03-31 19:38:09 +00:00
|
|
|
unsigned int num_codecs;
|
|
|
|
int codec_index;
|
2006-04-29 01:00:52 +00:00
|
|
|
switch_rtp_t *rtp_session;
|
2006-03-31 19:38:09 +00:00
|
|
|
ldl_session_t *dlsession;
|
|
|
|
char *remote_ip;
|
2006-04-05 20:17:22 +00:00
|
|
|
switch_port_t local_port;
|
|
|
|
switch_port_t remote_port;
|
2006-04-06 23:31:01 +00:00
|
|
|
char local_user[17];
|
2006-04-15 22:30:25 +00:00
|
|
|
char local_pass[17];
|
2006-03-31 19:38:09 +00:00
|
|
|
char *remote_user;
|
2006-10-24 18:23:23 +00:00
|
|
|
char *us;
|
|
|
|
char *them;
|
2006-03-31 19:38:09 +00:00
|
|
|
unsigned int cand_id;
|
|
|
|
unsigned int desc_id;
|
|
|
|
unsigned int dc;
|
2007-03-06 01:19:41 +00:00
|
|
|
uint32_t timestamp_send;
|
2006-03-31 19:38:09 +00:00
|
|
|
int32_t timestamp_recv;
|
2006-04-13 16:19:49 +00:00
|
|
|
uint32_t last_read;
|
2006-03-31 19:38:09 +00:00
|
|
|
char *codec_name;
|
2006-04-18 16:50:34 +00:00
|
|
|
switch_payload_t codec_num;
|
2006-08-18 01:28:50 +00:00
|
|
|
switch_payload_t r_codec_num;
|
2006-08-18 16:36:26 +00:00
|
|
|
uint32_t codec_rate;
|
2006-04-15 22:30:25 +00:00
|
|
|
switch_time_t next_desc;
|
2006-04-15 16:02:31 +00:00
|
|
|
switch_time_t next_cand;
|
2006-04-13 17:15:51 +00:00
|
|
|
char *stun_ip;
|
2006-05-03 23:45:07 +00:00
|
|
|
char *recip;
|
2006-05-04 14:37:11 +00:00
|
|
|
char *dnis;
|
2006-04-14 05:53:59 +00:00
|
|
|
uint16_t stun_port;
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_mutex_t *flag_mutex;
|
2006-03-31 19:38:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct rfc2833_digit {
|
|
|
|
char digit;
|
|
|
|
int duration;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2007-10-17 14:59:17 +00:00
|
|
|
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);
|
2007-04-06 16:20:07 +00:00
|
|
|
|
2007-05-12 14:48:14 +00:00
|
|
|
static switch_status_t dl_login(const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream);
|
|
|
|
static switch_status_t dl_logout(const char *profile_name, switch_core_session_t *session, switch_stream_handle_t *stream);
|
|
|
|
static switch_status_t dl_pres(const char *profile_name, switch_core_session_t *session, switch_stream_handle_t *stream);
|
|
|
|
static switch_status_t dl_debug(const char *profile_name, switch_core_session_t *session, switch_stream_handle_t *stream);
|
2007-04-06 16:20:07 +00:00
|
|
|
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_call_cause_t channel_outgoing_channel(switch_core_session_t *session,
|
|
|
|
switch_caller_profile_t *outbound_profile,
|
2007-12-20 21:42:00 +00:00
|
|
|
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags);
|
2007-04-06 16:20:07 +00:00
|
|
|
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 dl_signal,
|
|
|
|
char *to, 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 int sin_callback(void *pArg, int argc, char **argv, char **columnNames);
|
2006-05-02 16:43:13 +00:00
|
|
|
|
2006-12-16 03:00:56 +00:00
|
|
|
#define is_special(s) (s && (strstr(s, "ext+") || strstr(s, "user+")))
|
2006-10-24 18:23:23 +00:00
|
|
|
|
2007-04-06 16:20:07 +00:00
|
|
|
static char *translate_rpid(char *in, char *ext)
|
2006-10-20 06:17:00 +00:00
|
|
|
{
|
|
|
|
char *r = NULL;
|
|
|
|
|
|
|
|
if (in && (strstr(in, "null") || strstr(in, "NULL"))) {
|
|
|
|
in = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!in) {
|
|
|
|
in = ext;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!in) {
|
|
|
|
return NULL;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-20 06:17:00 +00:00
|
|
|
if (!strcasecmp(in, "busy")) {
|
|
|
|
r = "dnd";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcasecmp(in, "unavailable")) {
|
|
|
|
r = "dnd";
|
|
|
|
}
|
|
|
|
|
2006-10-20 22:11:26 +00:00
|
|
|
if (!strcasecmp(in, "idle")) {
|
|
|
|
r = "away";
|
|
|
|
}
|
|
|
|
|
2006-10-20 06:17:00 +00:00
|
|
|
if (ext && !strcasecmp(ext, "idle")) {
|
|
|
|
r = "away";
|
|
|
|
} else if (ext && !strcasecmp(ext, "away")) {
|
|
|
|
r = "away";
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-20 06:17:00 +00:00
|
|
|
return r;
|
|
|
|
}
|
2006-08-18 16:36:26 +00:00
|
|
|
|
2007-04-04 17:32:56 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void mdl_execute_sql(mdl_profile_t *profile, char *sql, switch_mutex_t *mutex)
|
|
|
|
{
|
|
|
|
switch_core_db_t *db;
|
|
|
|
|
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_lock(mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SWITCH_HAVE_ODBC
|
|
|
|
if (profile->odbc_dsn) {
|
|
|
|
SQLHSTMT stmt;
|
|
|
|
if (switch_odbc_handle_exec(profile->master_odbc, sql, &stmt) != SWITCH_ODBC_SUCCESS) {
|
|
|
|
char *err_str;
|
|
|
|
err_str = switch_odbc_handle_get_error(profile->master_odbc, stmt);
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERR: [%s]\n[%s]\n", sql, switch_str_nil(err_str));
|
|
|
|
switch_safe_free(err_str);
|
|
|
|
}
|
|
|
|
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
|
|
|
|
} else {
|
|
|
|
#endif
|
|
|
|
if (!(db = switch_core_db_open_file(profile->dbname))) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
2007-12-18 01:12:50 +00:00
|
|
|
switch_core_db_persistant_execute(db, sql, 1);
|
2007-04-04 17:32:56 +00:00
|
|
|
switch_core_db_close(db);
|
|
|
|
|
|
|
|
#ifdef SWITCH_HAVE_ODBC
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2007-04-06 16:20:07 +00:00
|
|
|
end:
|
2007-04-04 17:32:56 +00:00
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_unlock(mutex);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static switch_bool_t mdl_execute_sql_callback(mdl_profile_t *profile,
|
|
|
|
switch_mutex_t *mutex,
|
|
|
|
char *sql,
|
|
|
|
switch_core_db_callback_func_t callback,
|
|
|
|
void *pdata)
|
|
|
|
{
|
|
|
|
switch_bool_t ret = SWITCH_FALSE;
|
|
|
|
switch_core_db_t *db;
|
|
|
|
char *errmsg = NULL;
|
|
|
|
|
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_lock(mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef SWITCH_HAVE_ODBC
|
|
|
|
if (profile->odbc_dsn) {
|
|
|
|
switch_odbc_handle_callback_exec(profile->master_odbc, sql, callback, pdata);
|
|
|
|
} else {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!(db = switch_core_db_open_file(profile->dbname))) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch_core_db_exec(db, sql, callback, pdata, &errmsg);
|
|
|
|
|
|
|
|
if (errmsg) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg);
|
|
|
|
free(errmsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (db) {
|
|
|
|
switch_core_db_close(db);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef SWITCH_HAVE_ODBC
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
end:
|
|
|
|
|
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_unlock(mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-10-18 22:57:35 +00:00
|
|
|
static int sub_callback(void *pArg, int argc, char **argv, char **columnNames)
|
|
|
|
{
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile = (mdl_profile_t *) pArg;
|
2006-10-18 22:57:35 +00:00
|
|
|
|
|
|
|
char *sub_from = argv[0];
|
|
|
|
char *sub_to = argv[1];
|
|
|
|
char *type = argv[2];
|
2006-10-20 06:17:00 +00:00
|
|
|
char *rpid = argv[3];
|
|
|
|
char *status = argv[4];
|
2006-10-20 22:11:26 +00:00
|
|
|
//char *proto = argv[5];
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-18 22:57:35 +00:00
|
|
|
if (switch_strlen_zero(type)) {
|
|
|
|
type = NULL;
|
|
|
|
} else if (!strcasecmp(type, "unavailable")) {
|
2006-10-20 06:17:00 +00:00
|
|
|
status = NULL;
|
2006-10-18 22:57:35 +00:00
|
|
|
}
|
2006-10-20 06:17:00 +00:00
|
|
|
rpid = translate_rpid(rpid, status);
|
2006-10-20 22:11:26 +00:00
|
|
|
|
2006-11-16 15:50:17 +00:00
|
|
|
//ldl_handle_send_presence(profile->handle, sub_to, sub_from, "probe", rpid, status);
|
2007-04-04 22:22:55 +00:00
|
|
|
ldl_handle_send_presence(profile->handle, sub_to, sub_from, type, rpid, status, profile->avatar);
|
2006-10-18 22:57:35 +00:00
|
|
|
|
2006-10-20 22:11:26 +00:00
|
|
|
|
2006-10-18 22:57:35 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int rost_callback(void *pArg, int argc, char **argv, char **columnNames)
|
|
|
|
{
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile = (mdl_profile_t *) pArg;
|
2006-10-18 22:57:35 +00:00
|
|
|
|
|
|
|
char *sub_from = argv[0];
|
|
|
|
char *sub_to = argv[1];
|
|
|
|
char *show = argv[2];
|
2006-10-20 06:17:00 +00:00
|
|
|
char *status = argv[3];
|
2006-10-18 22:57:35 +00:00
|
|
|
|
2006-10-20 06:17:00 +00:00
|
|
|
if (!strcasecmp(status, "n/a")) {
|
|
|
|
if (!strcasecmp(show, "dnd")) {
|
|
|
|
status = "Busy";
|
|
|
|
} else if (!strcasecmp(show, "away")) {
|
|
|
|
status = "Idle";
|
|
|
|
}
|
|
|
|
}
|
2006-10-18 22:57:35 +00:00
|
|
|
|
2007-04-04 22:22:55 +00:00
|
|
|
ldl_handle_send_presence(profile->handle, sub_to, sub_from, NULL, show, status, profile->avatar);
|
2006-10-18 22:57:35 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void pres_event_handler(switch_event_t *event)
|
|
|
|
{
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile = NULL;
|
2006-10-18 22:57:35 +00:00
|
|
|
switch_hash_index_t *hi;
|
2007-03-29 22:31:56 +00:00
|
|
|
void *val;
|
2006-10-20 22:11:26 +00:00
|
|
|
char *proto = switch_event_get_header(event, "proto");
|
2006-10-18 22:57:35 +00:00
|
|
|
char *from = switch_event_get_header(event, "from");
|
2007-03-29 22:31:56 +00:00
|
|
|
char *status = switch_event_get_header(event, "status");
|
2006-10-20 06:17:00 +00:00
|
|
|
char *rpid = switch_event_get_header(event, "rpid");
|
|
|
|
char *type = switch_event_get_header(event, "event_subtype");
|
2006-10-18 22:57:35 +00:00
|
|
|
char *sql;
|
2007-04-04 17:32:56 +00:00
|
|
|
|
2006-10-18 22:57:35 +00:00
|
|
|
|
2006-10-20 22:11:26 +00:00
|
|
|
if (!proto) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Missing 'proto' header\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!from) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Missing 'from' header\n");
|
|
|
|
return;
|
|
|
|
}
|
2006-10-18 22:57:35 +00:00
|
|
|
|
|
|
|
if (status && !strcasecmp(status, "n/a")) {
|
2006-10-20 06:17:00 +00:00
|
|
|
status = NULL;
|
2006-10-18 22:57:35 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
switch (event->event_id) {
|
|
|
|
case SWITCH_EVENT_PRESENCE_PROBE:
|
|
|
|
if (proto) {
|
2007-12-12 23:51:26 +00:00
|
|
|
char *subsql;
|
2007-03-29 22:31:56 +00:00
|
|
|
char *to = switch_event_get_header(event, "to");
|
|
|
|
char *f_host = NULL;
|
|
|
|
if (to) {
|
|
|
|
if ((f_host = strchr(to, '@'))) {
|
|
|
|
f_host++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (f_host && (profile = switch_core_hash_find(globals.profile_hash, f_host))) {
|
2007-12-12 23:51:26 +00:00
|
|
|
if (to && (subsql = switch_mprintf("select * from jabber_subscriptions where sub_to='%q' and sub_from='%q'", to, from))) {
|
|
|
|
mdl_execute_sql_callback(profile, profile->mutex, subsql, sin_callback, profile);
|
|
|
|
switch_safe_free(subsql);
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return;
|
2006-10-18 22:57:35 +00:00
|
|
|
case SWITCH_EVENT_PRESENCE_IN:
|
|
|
|
if (!status) {
|
|
|
|
status = "Available";
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case SWITCH_EVENT_PRESENCE_OUT:
|
|
|
|
type = "unavailable";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-18 22:57:35 +00:00
|
|
|
|
2006-10-20 22:11:26 +00:00
|
|
|
if (!type) {
|
|
|
|
type = "";
|
|
|
|
}
|
|
|
|
if (!rpid) {
|
|
|
|
rpid = "";
|
2006-10-18 22:57:35 +00:00
|
|
|
}
|
2006-10-20 22:11:26 +00:00
|
|
|
if (!status) {
|
|
|
|
status = "Away";
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-04-04 17:32:56 +00:00
|
|
|
sql = switch_mprintf("select sub_from, sub_to,'%q','%q','%q','%q' from jabber_subscriptions where sub_to like '%%%q'", type, rpid, status, proto, from);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
|
|
|
|
2007-09-24 19:34:25 +00:00
|
|
|
for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_hash_this(hi, NULL, NULL, &val);
|
2007-04-04 17:32:56 +00:00
|
|
|
profile = (mdl_profile_t *) val;
|
2006-10-18 22:57:35 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (!(profile->user_flags & LDL_FLAG_COMPONENT)) {
|
2006-10-18 22:57:35 +00:00
|
|
|
continue;
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-10-18 22:57:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (sql) {
|
2007-04-04 17:32:56 +00:00
|
|
|
switch_bool_t worked = mdl_execute_sql_callback(profile, profile->mutex, sql, sub_callback, profile);
|
|
|
|
|
|
|
|
if (!worked) {
|
2006-10-18 22:57:35 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-18 22:57:35 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_safe_free(sql);
|
|
|
|
}
|
|
|
|
|
2006-10-20 22:11:26 +00:00
|
|
|
static switch_status_t chat_send(char *proto, char *from, char *to, char *subject, char *body, char *hint)
|
2006-10-18 22:57:35 +00:00
|
|
|
{
|
2006-12-27 18:42:32 +00:00
|
|
|
char *user, *host, *f_user = NULL, *ffrom = NULL, *f_host = NULL, *f_resource = NULL;
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile = NULL;
|
2006-10-18 22:57:35 +00:00
|
|
|
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(proto != NULL);
|
2006-10-20 22:11:26 +00:00
|
|
|
|
2006-10-18 22:57:35 +00:00
|
|
|
if (from && (f_user = strdup(from))) {
|
|
|
|
if ((f_host = strchr(f_user, '@'))) {
|
|
|
|
*f_host++ = '\0';
|
2007-03-29 22:31:56 +00:00
|
|
|
if ((f_resource = strchr(f_host, '/'))) {
|
|
|
|
*f_resource++ = '\0';
|
|
|
|
}
|
2006-10-18 22:57:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (to && (user = strdup(to))) {
|
|
|
|
if ((host = strchr(user, '@'))) {
|
|
|
|
*host++ = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
if (f_host && (profile = switch_core_hash_find(globals.profile_hash, f_host))) {
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-20 22:11:26 +00:00
|
|
|
if (!strcmp(proto, MDL_CHAT_PROTO)) {
|
|
|
|
from = hint;
|
|
|
|
} else {
|
|
|
|
char *p;
|
|
|
|
ffrom = switch_mprintf("%s+%s", proto, from);
|
|
|
|
from = ffrom;
|
|
|
|
if ((p = strchr(from, '/'))) {
|
|
|
|
*p = '\0';
|
|
|
|
}
|
|
|
|
}
|
2006-10-18 22:57:35 +00:00
|
|
|
ldl_handle_send_msg(profile->handle, from, to, NULL, body);
|
|
|
|
} else {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile %s\n", f_host ? f_host : "NULL");
|
2006-10-19 07:13:34 +00:00
|
|
|
return SWITCH_STATUS_FALSE;
|
2006-10-18 22:57:35 +00:00
|
|
|
}
|
|
|
|
|
2006-10-20 22:11:26 +00:00
|
|
|
switch_safe_free(user);
|
|
|
|
switch_safe_free(f_user);
|
2006-10-18 22:57:35 +00:00
|
|
|
}
|
|
|
|
|
2006-10-19 07:13:34 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
2006-10-18 22:57:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void roster_event_handler(switch_event_t *event)
|
|
|
|
{
|
2007-03-29 22:31:56 +00:00
|
|
|
char *status = switch_event_get_header(event, "status");
|
|
|
|
char *from = switch_event_get_header(event, "from");
|
2006-10-18 22:57:35 +00:00
|
|
|
char *event_type = switch_event_get_header(event, "event_type");
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile = NULL;
|
2006-10-18 22:57:35 +00:00
|
|
|
switch_hash_index_t *hi;
|
2007-03-29 22:31:56 +00:00
|
|
|
void *val;
|
2006-10-18 22:57:35 +00:00
|
|
|
char *sql;
|
2007-04-04 17:32:56 +00:00
|
|
|
|
2006-10-18 22:57:35 +00:00
|
|
|
|
|
|
|
if (status && !strcasecmp(status, "n/a")) {
|
2006-10-20 06:17:00 +00:00
|
|
|
status = NULL;
|
2006-10-18 22:57:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (switch_strlen_zero(event_type)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
event_type = "presence";
|
2006-10-18 22:57:35 +00:00
|
|
|
}
|
|
|
|
|
2006-10-20 06:17:00 +00:00
|
|
|
if (from) {
|
2007-04-04 17:32:56 +00:00
|
|
|
sql = switch_mprintf("select *,'%q' from jabber_subscriptions where sub_from='%q'", status ? status : "", from);
|
2006-10-20 06:17:00 +00:00
|
|
|
} else {
|
2007-04-04 17:32:56 +00:00
|
|
|
sql = switch_mprintf("select *,'%q' from jabber_subscriptions", status ? status : "");
|
2006-10-20 06:17:00 +00:00
|
|
|
}
|
2006-10-18 22:57:35 +00:00
|
|
|
|
2007-09-24 19:34:25 +00:00
|
|
|
for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_hash_this(hi, NULL, NULL, &val);
|
2007-04-04 17:32:56 +00:00
|
|
|
profile = (mdl_profile_t *) val;
|
2006-10-18 22:57:35 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (!(profile->user_flags & LDL_FLAG_COMPONENT)) {
|
2006-10-18 22:57:35 +00:00
|
|
|
continue;
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-10-18 22:57:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (sql) {
|
2007-04-04 17:32:56 +00:00
|
|
|
switch_bool_t worked = mdl_execute_sql_callback(profile, profile->mutex, sql, rost_callback, profile);
|
|
|
|
if (!worked) {
|
2006-10-18 22:57:35 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-18 22:57:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch_safe_free(sql);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-10-20 06:44:58 +00:00
|
|
|
static int so_callback(void *pArg, int argc, char **argv, char **columnNames)
|
|
|
|
{
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile = (mdl_profile_t *) pArg;
|
2006-10-20 06:44:58 +00:00
|
|
|
|
|
|
|
char *sub_from = argv[0];
|
|
|
|
char *sub_to = argv[1];
|
|
|
|
|
|
|
|
|
2007-04-04 22:22:55 +00:00
|
|
|
ldl_handle_send_presence(profile->handle, sub_to, sub_from, "unavailable", "dnd", "Bub-Bye", profile->avatar);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-20 06:44:58 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-10-22 04:37:19 +00:00
|
|
|
|
|
|
|
static int sin_callback(void *pArg, int argc, char **argv, char **columnNames)
|
|
|
|
{
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile = (mdl_profile_t *) pArg;
|
2006-10-22 04:37:19 +00:00
|
|
|
switch_event_t *event;
|
|
|
|
|
|
|
|
//char *sub_from = argv[0];
|
|
|
|
char *sub_to = argv[1];
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-24 18:23:23 +00:00
|
|
|
if (is_special(sub_to)) {
|
2006-10-22 04:37:19 +00:00
|
|
|
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", sub_to);
|
2006-10-22 04:37:19 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "available");
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Online");
|
|
|
|
switch_event_fire(&event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-10-20 06:44:58 +00:00
|
|
|
static void sign_off(void)
|
|
|
|
{
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile = NULL;
|
2006-10-20 06:44:58 +00:00
|
|
|
switch_hash_index_t *hi;
|
2007-03-29 22:31:56 +00:00
|
|
|
void *val;
|
2006-10-20 06:44:58 +00:00
|
|
|
char *sql;
|
|
|
|
|
|
|
|
|
2007-04-04 17:32:56 +00:00
|
|
|
|
|
|
|
sql = switch_mprintf("select * from jabber_subscriptions");
|
2006-10-20 06:44:58 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-09-24 19:34:25 +00:00
|
|
|
for (hi = switch_hash_first(NULL, globals.profile_hash); hi; hi = switch_hash_next(hi)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_hash_this(hi, NULL, NULL, &val);
|
2007-04-04 17:32:56 +00:00
|
|
|
profile = (mdl_profile_t *) val;
|
2006-10-20 06:44:58 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (!(profile->user_flags & LDL_FLAG_COMPONENT)) {
|
2006-10-20 06:44:58 +00:00
|
|
|
continue;
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-10-20 06:44:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (sql) {
|
2007-04-04 17:32:56 +00:00
|
|
|
switch_bool_t worked = mdl_execute_sql_callback(profile, profile->mutex, sql, so_callback, profile);
|
|
|
|
if (!worked) {
|
2006-10-20 06:44:58 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-20 06:44:58 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-20 06:44:58 +00:00
|
|
|
switch_yield(1000000);
|
|
|
|
switch_safe_free(sql);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-04-04 17:32:56 +00:00
|
|
|
static void sign_on(mdl_profile_t *profile)
|
2006-10-22 04:37:19 +00:00
|
|
|
{
|
|
|
|
char *sql;
|
|
|
|
|
2007-04-04 17:32:56 +00:00
|
|
|
|
|
|
|
if ((sql = switch_mprintf("select * from jabber_subscriptions where sub_to like 'ext+%%' or sub_to like 'user+%%' or sub_to like 'conf+%%'"))) {
|
|
|
|
mdl_execute_sql_callback(profile, profile->mutex, sql, sin_callback, profile);
|
2006-10-22 04:37:19 +00:00
|
|
|
switch_safe_free(sql);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-09-22 15:22:31 +00:00
|
|
|
static void terminate_session(switch_core_session_t **session, int line, switch_call_cause_t cause)
|
2006-08-18 16:36:26 +00:00
|
|
|
{
|
|
|
|
if (*session) {
|
|
|
|
switch_channel_t *channel = switch_core_session_get_channel(*session);
|
|
|
|
switch_channel_state_t state = switch_channel_get_state(channel);
|
|
|
|
struct private_object *tech_pvt = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Terminate called from line %d state=%s\n", line, switch_channel_state_name(state));
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-08-18 16:36:26 +00:00
|
|
|
tech_pvt = switch_core_session_get_private(*session);
|
|
|
|
|
2007-12-20 15:41:45 +00:00
|
|
|
|
2008-01-02 02:57:56 +00:00
|
|
|
if (tech_pvt && tech_pvt->profile && tech_pvt->profile->ip && tech_pvt->local_port) {
|
2007-12-20 15:41:45 +00:00
|
|
|
switch_rtp_release_port(tech_pvt->profile->ip, tech_pvt->local_port);
|
|
|
|
}
|
|
|
|
|
2007-06-28 14:29:11 +00:00
|
|
|
if (!switch_core_session_running(*session) && (!tech_pvt || !switch_test_flag(tech_pvt, TFLAG_READY))) {
|
2006-08-18 16:36:26 +00:00
|
|
|
switch_core_session_destroy(session);
|
2006-10-10 00:11:41 +00:00
|
|
|
return;
|
|
|
|
}
|
2006-09-22 15:22:31 +00:00
|
|
|
|
2008-01-02 02:57:56 +00:00
|
|
|
if (!tech_pvt || switch_test_flag(tech_pvt, TFLAG_TERM)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
/*once is enough */
|
2006-10-10 00:11:41 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2006-09-22 15:22:31 +00:00
|
|
|
if (state < CS_HANGUP) {
|
|
|
|
switch_channel_hangup(channel, cause);
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-25 17:00:23 +00:00
|
|
|
switch_mutex_lock(tech_pvt->flag_mutex);
|
|
|
|
switch_set_flag(tech_pvt, TFLAG_TERM);
|
|
|
|
switch_set_flag(tech_pvt, TFLAG_BYE);
|
|
|
|
switch_clear_flag(tech_pvt, TFLAG_IO);
|
|
|
|
switch_mutex_unlock(tech_pvt->flag_mutex);
|
|
|
|
|
2006-09-22 15:22:31 +00:00
|
|
|
*session = NULL;
|
2006-08-18 16:36:26 +00:00
|
|
|
}
|
2006-09-22 15:22:31 +00:00
|
|
|
|
2006-08-18 16:36:26 +00:00
|
|
|
}
|
|
|
|
|
2006-05-02 16:43:13 +00:00
|
|
|
static void dl_logger(char *file, const char *func, int line, int level, char *fmt, ...)
|
2006-04-14 02:05:29 +00:00
|
|
|
{
|
2006-04-14 03:04:53 +00:00
|
|
|
va_list ap;
|
2007-04-06 20:47:09 +00:00
|
|
|
char *data = NULL;
|
|
|
|
int ret;
|
2006-04-14 03:04:53 +00:00
|
|
|
|
2006-04-14 03:12:55 +00:00
|
|
|
va_start(ap, fmt);
|
2007-04-06 20:47:09 +00:00
|
|
|
if ((ret = switch_vasprintf(&data, fmt, ap)) != -1) {
|
|
|
|
if (!strncasecmp(data, "+xml:", 5)) {
|
|
|
|
switch_xml_t xml;
|
|
|
|
char *form;
|
|
|
|
char *ll = data + 5;
|
|
|
|
char *xmltxt;
|
|
|
|
|
|
|
|
if (ll) {
|
|
|
|
if ((xmltxt = strchr(ll, ':'))) {
|
|
|
|
*xmltxt++ = '\0';
|
2007-04-07 21:13:54 +00:00
|
|
|
if (strlen(xmltxt) > 2) {
|
|
|
|
xml = switch_xml_parse_str(xmltxt, strlen(xmltxt));
|
2007-11-30 23:45:27 +00:00
|
|
|
form = switch_xml_toxml(xml, SWITCH_FALSE);
|
2007-06-20 10:46:51 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, level,
|
2007-04-07 21:13:54 +00:00
|
|
|
"%s:\n-------------------------------------------------------------------------------\n"
|
|
|
|
"%s\n", ll, form);
|
|
|
|
switch_xml_free(xml);
|
|
|
|
free(data);
|
|
|
|
}
|
2007-04-06 20:47:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2007-06-20 10:46:51 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, level, "%s\n", data);
|
2007-04-06 20:47:09 +00:00
|
|
|
}
|
|
|
|
}
|
2006-04-14 03:04:53 +00:00
|
|
|
va_end(ap);
|
2006-04-14 02:05:29 +00:00
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-08-18 16:36:26 +00:00
|
|
|
static int get_codecs(struct private_object *tech_pvt)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
|
|
|
switch_assert(tech_pvt->session != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-08-18 16:36:26 +00:00
|
|
|
if (!tech_pvt->num_codecs) {
|
|
|
|
if (globals.codec_string) {
|
|
|
|
if ((tech_pvt->num_codecs = switch_loadable_module_get_codecs_sorted(tech_pvt->codecs,
|
2007-03-30 00:13:31 +00:00
|
|
|
SWITCH_MAX_CODECS, globals.codec_order, globals.codec_order_last)) <= 0) {
|
2006-08-18 16:36:26 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO codecs?\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} else if (((tech_pvt->num_codecs =
|
2007-09-24 19:34:25 +00:00
|
|
|
switch_loadable_module_get_codecs(tech_pvt->codecs, SWITCH_MAX_CODECS))) <= 0) {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "NO codecs?\n");
|
2006-08-18 16:36:26 +00:00
|
|
|
return 0;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
}
|
2006-08-18 16:36:26 +00:00
|
|
|
|
|
|
|
return tech_pvt->num_codecs;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
static void *SWITCH_THREAD_FUNC handle_thread_run(switch_thread_t * thread, void *obj)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
|
|
|
ldl_handle_t *handle = obj;
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile = NULL;
|
2006-10-20 06:17:00 +00:00
|
|
|
|
2006-10-20 22:11:26 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
profile = ldl_handle_get_private(handle);
|
|
|
|
globals.handles++;
|
2006-05-02 16:43:13 +00:00
|
|
|
switch_set_flag(profile, TFLAG_IO);
|
2006-03-31 19:38:09 +00:00
|
|
|
ldl_handle_run(handle);
|
2006-05-02 16:43:13 +00:00
|
|
|
switch_clear_flag(profile, TFLAG_IO);
|
2006-03-31 19:38:09 +00:00
|
|
|
globals.handles--;
|
|
|
|
ldl_handle_destroy(&handle);
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Handle %s [%s] Destroyed\n", profile->name, profile->login);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static void handle_thread_launch(ldl_handle_t * handle)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2006-04-29 01:00:52 +00:00
|
|
|
switch_thread_t *thread;
|
2006-03-31 19:38:09 +00:00
|
|
|
switch_threadattr_t *thd_attr = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
switch_threadattr_create(&thd_attr, module_pool);
|
|
|
|
switch_threadattr_detach_set(thd_attr, 1);
|
2006-04-26 17:18:33 +00:00
|
|
|
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
|
2006-03-31 19:38:09 +00:00
|
|
|
switch_thread_create(&thread, thd_attr, handle_thread_run, handle, module_pool);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
static int activate_rtp(struct private_object *tech_pvt)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = switch_core_session_get_channel(tech_pvt->session);
|
2006-04-15 22:30:25 +00:00
|
|
|
const char *err;
|
2006-09-07 15:08:40 +00:00
|
|
|
int ms = 0;
|
2006-05-24 16:10:05 +00:00
|
|
|
switch_rtp_flag_t flags;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-08-28 23:05:26 +00:00
|
|
|
if (switch_rtp_ready(tech_pvt->rtp_session)) {
|
2006-08-18 01:28:50 +00:00
|
|
|
return 1;
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (!(tech_pvt->remote_ip && tech_pvt->remote_port)) {
|
2007-02-08 21:08:45 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No valid candidates received!\n");
|
2007-03-29 22:31:56 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2006-12-19 20:24:07 +00:00
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
if (switch_core_codec_init(&tech_pvt->read_codec,
|
2006-08-18 16:36:26 +00:00
|
|
|
tech_pvt->codec_name,
|
2006-10-09 02:24:43 +00:00
|
|
|
NULL,
|
2006-08-18 16:36:26 +00:00
|
|
|
tech_pvt->codec_rate,
|
|
|
|
ms,
|
|
|
|
1,
|
|
|
|
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
|
|
|
|
NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
|
2006-04-15 22:30:25 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Can't load codec?\n");
|
2006-04-22 03:05:25 +00:00
|
|
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-08-18 01:28:50 +00:00
|
|
|
return 0;
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
|
|
|
tech_pvt->read_frame.rate = tech_pvt->read_codec.implementation->samples_per_second;
|
|
|
|
tech_pvt->read_frame.codec = &tech_pvt->read_codec;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set Read Codec to %s@%d\n",
|
|
|
|
tech_pvt->codec_name, (int) tech_pvt->read_codec.implementation->samples_per_second);
|
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
if (switch_core_codec_init(&tech_pvt->write_codec,
|
2006-08-18 16:36:26 +00:00
|
|
|
tech_pvt->codec_name,
|
2006-10-09 02:24:43 +00:00
|
|
|
NULL,
|
2006-08-18 16:36:26 +00:00
|
|
|
tech_pvt->codec_rate,
|
|
|
|
ms,
|
|
|
|
1,
|
|
|
|
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
|
|
|
|
NULL, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
|
2006-04-15 22:30:25 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Can't load codec?\n");
|
2006-04-22 03:05:25 +00:00
|
|
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-08-18 01:28:50 +00:00
|
|
|
return 0;
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set Write Codec to %s@%d\n",
|
|
|
|
tech_pvt->codec_name, (int) tech_pvt->write_codec.implementation->samples_per_second);
|
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
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);
|
2006-04-15 05:56:23 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SETUP RTP %s:%d -> %s:%d\n", tech_pvt->profile->ip,
|
|
|
|
tech_pvt->local_port, tech_pvt->remote_ip, tech_pvt->remote_port);
|
2007-04-07 01:57:54 +00:00
|
|
|
|
2007-06-23 03:51:57 +00:00
|
|
|
flags = SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_GOOGLEHACK | SWITCH_RTP_FLAG_AUTOADJ | SWITCH_RTP_FLAG_RAW_WRITE | SWITCH_RTP_FLAG_AUTO_CNG;
|
2006-05-24 16:10:05 +00:00
|
|
|
|
|
|
|
if (switch_test_flag(tech_pvt->profile, TFLAG_TIMER)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
flags |= SWITCH_RTP_FLAG_USE_TIMER;
|
2006-05-24 16:10:05 +00:00
|
|
|
}
|
2006-04-15 22:30:25 +00:00
|
|
|
|
|
|
|
if (!(tech_pvt->rtp_session = switch_rtp_new(tech_pvt->profile->ip,
|
2006-07-18 18:34:42 +00:00
|
|
|
tech_pvt->local_port,
|
|
|
|
tech_pvt->remote_ip,
|
|
|
|
tech_pvt->remote_port,
|
|
|
|
tech_pvt->codec_num,
|
2007-06-28 15:00:47 +00:00
|
|
|
tech_pvt->read_codec.implementation->samples_per_frame,
|
2006-07-18 18:34:42 +00:00
|
|
|
tech_pvt->read_codec.implementation->microseconds_per_frame,
|
2008-01-16 06:01:53 +00:00
|
|
|
flags, tech_pvt->profile->timer_name, &err, switch_core_session_get_pool(tech_pvt->session)))) {
|
2006-04-15 22:30:25 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "RTP ERROR %s\n", err);
|
2006-04-22 03:05:25 +00:00
|
|
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-08-18 01:28:50 +00:00
|
|
|
return 0;
|
2006-04-21 22:31:08 +00:00
|
|
|
} else {
|
|
|
|
uint8_t vad_in = switch_test_flag(tech_pvt, TFLAG_VAD_IN) ? 1 : 0;
|
|
|
|
uint8_t vad_out = switch_test_flag(tech_pvt, TFLAG_VAD_OUT) ? 1 : 0;
|
|
|
|
uint8_t inb = switch_test_flag(tech_pvt, TFLAG_OUTBOUND) ? 0 : 1;
|
|
|
|
switch_rtp_activate_ice(tech_pvt->rtp_session, tech_pvt->remote_user, tech_pvt->local_user);
|
|
|
|
if ((vad_in && inb) || (vad_out && !inb)) {
|
2007-04-07 01:57:54 +00:00
|
|
|
if (switch_rtp_enable_vad(tech_pvt->rtp_session, tech_pvt->session, &tech_pvt->read_codec, SWITCH_VAD_FLAG_TALKING) != SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "VAD ERROR %s\n", err);
|
|
|
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
|
|
|
return 0;
|
|
|
|
}
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_VAD);
|
2006-04-21 22:31:08 +00:00
|
|
|
}
|
2007-03-17 01:52:05 +00:00
|
|
|
switch_rtp_set_cng_pt(tech_pvt->rtp_session, 13);
|
|
|
|
switch_rtp_set_telephony_event(tech_pvt->rtp_session, 101);
|
2006-04-13 17:15:51 +00:00
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-08-18 01:28:50 +00:00
|
|
|
return 1;
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
static int do_candidates(struct private_object *tech_pvt, int force)
|
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = switch_core_session_get_channel(tech_pvt->session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-04-15 16:02:31 +00:00
|
|
|
|
2006-04-22 01:49:27 +00:00
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_DO_CAND)) {
|
2006-08-18 16:36:26 +00:00
|
|
|
return 1;
|
2006-04-22 01:49:27 +00:00
|
|
|
}
|
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
tech_pvt->next_cand += DL_CAND_WAIT;
|
2006-04-22 01:21:53 +00:00
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_BYE)) {
|
2006-08-18 16:36:26 +00:00
|
|
|
return 0;
|
2006-04-22 01:21:53 +00:00
|
|
|
}
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_DO_CAND);
|
2006-04-15 16:02:31 +00:00
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
if (force || !switch_test_flag(tech_pvt, TFLAG_RTP_READY)) {
|
2006-04-27 15:59:58 +00:00
|
|
|
ldl_candidate_t cand[1];
|
|
|
|
char *advip = tech_pvt->profile->extip ? tech_pvt->profile->extip : tech_pvt->profile->ip;
|
|
|
|
char *err;
|
|
|
|
|
|
|
|
memset(cand, 0, sizeof(cand));
|
|
|
|
switch_stun_random_string(tech_pvt->local_user, 16, NULL);
|
|
|
|
switch_stun_random_string(tech_pvt->local_pass, 16, NULL);
|
2006-04-05 22:46:50 +00:00
|
|
|
|
2006-04-27 15:59:58 +00:00
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_LANADDR)) {
|
|
|
|
advip = tech_pvt->profile->ip;
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-04-05 22:46:50 +00:00
|
|
|
|
2006-04-27 15:59:58 +00:00
|
|
|
cand[0].port = tech_pvt->local_port;
|
|
|
|
cand[0].address = advip;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-04-27 15:59:58 +00:00
|
|
|
if (!strncasecmp(advip, "stun:", 5)) {
|
|
|
|
char *stun_ip = advip + 5;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-04-27 15:59:58 +00:00
|
|
|
if (tech_pvt->stun_ip) {
|
|
|
|
cand[0].address = tech_pvt->stun_ip;
|
|
|
|
cand[0].port = tech_pvt->stun_port;
|
|
|
|
} else {
|
|
|
|
if (!stun_ip) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Stun Failed! NO STUN SERVER!\n");
|
|
|
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-08-18 16:36:26 +00:00
|
|
|
return 0;
|
2006-04-05 22:46:50 +00:00
|
|
|
}
|
|
|
|
|
2006-04-27 15:59:58 +00:00
|
|
|
cand[0].address = tech_pvt->profile->ip;
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Stun Lookup Local %s:%d\n", cand[0].address, cand[0].port);
|
2007-03-29 22:31:56 +00:00
|
|
|
if (switch_stun_lookup
|
|
|
|
(&cand[0].address, &cand[0].port, stun_ip, SWITCH_STUN_DEFAULT_PORT, &err,
|
|
|
|
switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Stun Failed! %s:%d [%s]\n", stun_ip, SWITCH_STUN_DEFAULT_PORT, err);
|
2006-04-27 15:59:58 +00:00
|
|
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-08-18 16:36:26 +00:00
|
|
|
return 0;
|
2006-04-27 15:59:58 +00:00
|
|
|
}
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Stun Success %s:%d\n", cand[0].address, cand[0].port);
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2006-04-27 15:59:58 +00:00
|
|
|
cand[0].type = "stun";
|
|
|
|
tech_pvt->stun_ip = switch_core_session_strdup(tech_pvt->session, cand[0].address);
|
|
|
|
tech_pvt->stun_port = cand[0].port;
|
|
|
|
} else {
|
|
|
|
cand[0].type = "local";
|
|
|
|
}
|
|
|
|
|
|
|
|
cand[0].name = "rtp";
|
|
|
|
cand[0].username = tech_pvt->local_user;
|
|
|
|
cand[0].password = tech_pvt->local_pass;
|
|
|
|
cand[0].pref = 1;
|
|
|
|
cand[0].protocol = "udp";
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Send Candidate %s:%d [%s]\n", cand[0].address, cand[0].port, cand[0].username);
|
2006-04-27 15:59:58 +00:00
|
|
|
tech_pvt->cand_id = ldl_session_candidates(tech_pvt->dlsession, cand, 1);
|
2006-11-16 15:50:17 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_TRANSPORT);
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_RTP_READY);
|
2006-04-27 15:59:58 +00:00
|
|
|
}
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_clear_flag_locked(tech_pvt, TFLAG_DO_CAND);
|
2006-08-18 16:36:26 +00:00
|
|
|
return 1;
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
|
|
|
|
2006-04-19 20:38:02 +00:00
|
|
|
static char *lame(char *in)
|
|
|
|
{
|
|
|
|
if (!strncasecmp(in, "ilbc", 4)) {
|
|
|
|
return "iLBC";
|
|
|
|
} else {
|
|
|
|
return in;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
static int do_describe(struct private_object *tech_pvt, int force)
|
|
|
|
{
|
|
|
|
ldl_payload_t payloads[5];
|
2006-08-30 22:03:52 +00:00
|
|
|
|
|
|
|
if (!tech_pvt->session) {
|
|
|
|
return 0;
|
|
|
|
}
|
2006-04-15 22:30:25 +00:00
|
|
|
|
2006-04-22 01:49:27 +00:00
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_DO_DESC)) {
|
2006-08-18 16:36:26 +00:00
|
|
|
return 1;
|
2006-04-22 01:49:27 +00:00
|
|
|
}
|
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
tech_pvt->next_desc += DL_CAND_WAIT;
|
|
|
|
|
2006-04-22 01:21:53 +00:00
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_BYE)) {
|
2006-08-18 16:36:26 +00:00
|
|
|
return 0;
|
2006-04-22 01:21:53 +00:00
|
|
|
}
|
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
memset(payloads, 0, sizeof(payloads));
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_DO_CAND);
|
2006-08-18 16:36:26 +00:00
|
|
|
if (!get_codecs(tech_pvt)) {
|
2006-09-22 15:22:31 +00:00
|
|
|
terminate_session(&tech_pvt->session, __LINE__, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION);
|
2006-08-18 16:36:26 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_BYE);
|
|
|
|
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
|
|
|
return 0;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
2006-08-18 16:36:26 +00:00
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
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");
|
2006-07-10 22:08:02 +00:00
|
|
|
tech_pvt->codec_name = lame(tech_pvt->codecs[0]->iananame);
|
|
|
|
tech_pvt->codec_num = tech_pvt->codecs[0]->ianacode;
|
2006-08-18 16:36:26 +00:00
|
|
|
tech_pvt->codec_rate = tech_pvt->codecs[0]->samples_per_second;
|
2006-08-18 01:28:50 +00:00
|
|
|
tech_pvt->r_codec_num = tech_pvt->codecs[0]->ianacode;
|
2006-04-15 22:30:25 +00:00
|
|
|
tech_pvt->codec_index = 0;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-07-10 22:08:02 +00:00
|
|
|
payloads[0].name = lame(tech_pvt->codecs[0]->iananame);
|
|
|
|
payloads[0].id = tech_pvt->codecs[0]->ianacode;
|
2006-08-18 01:28:50 +00:00
|
|
|
payloads[0].rate = tech_pvt->codecs[0]->samples_per_second;
|
|
|
|
payloads[0].bps = tech_pvt->codecs[0]->bits_per_second;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
} else {
|
2006-07-10 22:08:02 +00:00
|
|
|
payloads[0].name = lame(tech_pvt->codecs[tech_pvt->codec_index]->iananame);
|
|
|
|
payloads[0].id = tech_pvt->codecs[tech_pvt->codec_index]->ianacode;
|
2006-08-23 21:08:28 +00:00
|
|
|
payloads[0].rate = tech_pvt->codecs[tech_pvt->codec_index]->samples_per_second;
|
|
|
|
payloads[0].bps = tech_pvt->codecs[tech_pvt->codec_index]->bits_per_second;
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Send Describe [%s@%d]\n", payloads[0].name, payloads[0].rate);
|
2007-03-29 22:31:56 +00:00
|
|
|
tech_pvt->desc_id =
|
|
|
|
ldl_session_describe(tech_pvt->dlsession, payloads, 1,
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_test_flag(tech_pvt, TFLAG_OUTBOUND) ? LDL_DESCRIPTION_INITIATE : LDL_DESCRIPTION_ACCEPT);
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_CODEC_READY);
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_clear_flag_locked(tech_pvt, TFLAG_DO_CAND);
|
2006-08-18 16:36:26 +00:00
|
|
|
return 1;
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-10-10 00:11:41 +00:00
|
|
|
static switch_status_t negotiate_media(switch_core_session_t *session)
|
2006-04-15 22:30:25 +00:00
|
|
|
{
|
2006-10-10 00:11:41 +00:00
|
|
|
switch_status_t ret = SWITCH_STATUS_FALSE;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel;
|
2006-04-15 22:30:25 +00:00
|
|
|
struct private_object *tech_pvt = NULL;
|
|
|
|
switch_time_t started;
|
|
|
|
switch_time_t now;
|
|
|
|
unsigned int elapsed;
|
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-04-15 22:30:25 +00:00
|
|
|
|
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-04-15 22:30:25 +00:00
|
|
|
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_IO);
|
2006-04-15 22:30:25 +00:00
|
|
|
|
2007-10-03 16:44:11 +00:00
|
|
|
started = switch_timestamp_now();
|
2006-04-15 22:30:25 +00:00
|
|
|
|
2007-02-13 15:47:15 +00:00
|
|
|
/* jingle has no ringing indication so we will just pretend that we got one */
|
|
|
|
switch_core_session_queue_indication(session, SWITCH_MESSAGE_INDICATE_RINGING);
|
|
|
|
switch_channel_mark_ring_ready(channel);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
|
2007-10-03 16:44:11 +00:00
|
|
|
tech_pvt->next_cand = started + DL_CAND_WAIT;
|
|
|
|
tech_pvt->next_desc = started;
|
2006-04-15 22:30:25 +00:00
|
|
|
} else {
|
2007-10-03 16:44:11 +00:00
|
|
|
tech_pvt->next_cand = started + DL_CAND_WAIT;
|
|
|
|
tech_pvt->next_desc = started + DL_CAND_WAIT;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
while (!(switch_test_flag(tech_pvt, TFLAG_CODEC_READY) &&
|
|
|
|
switch_test_flag(tech_pvt, TFLAG_RTP_READY) &&
|
2007-04-07 01:57:54 +00:00
|
|
|
switch_test_flag(tech_pvt, TFLAG_ANSWER) && switch_test_flag(tech_pvt, TFLAG_TRANSPORT_ACCEPT) &&
|
|
|
|
tech_pvt->remote_ip && tech_pvt->remote_port
|
2007-03-30 00:15:25 +00:00
|
|
|
&& switch_test_flag(tech_pvt, TFLAG_TRANSPORT))) {
|
2007-10-03 16:44:11 +00:00
|
|
|
now = switch_timestamp_now();
|
2007-03-29 22:31:56 +00:00
|
|
|
elapsed = (unsigned int) ((now - started) / 1000);
|
2006-04-15 22:30:25 +00:00
|
|
|
|
|
|
|
if (switch_channel_get_state(channel) >= CS_HANGUP || switch_test_flag(tech_pvt, TFLAG_BYE)) {
|
2006-08-18 01:28:50 +00:00
|
|
|
goto out;
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
if (now >= tech_pvt->next_desc) {
|
2006-08-18 16:36:26 +00:00
|
|
|
if (!do_describe(tech_pvt, 0)) {
|
|
|
|
goto out;
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
if (tech_pvt->next_cand && now >= tech_pvt->next_cand) {
|
2006-08-18 16:36:26 +00:00
|
|
|
if (!do_candidates(tech_pvt, 0)) {
|
|
|
|
goto out;
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (elapsed > 60000) {
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(&tech_pvt->session, __LINE__, SWITCH_CAUSE_NORMAL_CLEARING);
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_BYE);
|
|
|
|
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
2006-09-22 15:22:31 +00:00
|
|
|
goto done;
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_BYE) || !switch_test_flag(tech_pvt, TFLAG_IO)) {
|
2006-09-22 15:22:31 +00:00
|
|
|
goto done;
|
2006-04-12 20:48:47 +00:00
|
|
|
}
|
2006-04-15 22:30:25 +00:00
|
|
|
switch_yield(1000);
|
2006-04-12 20:48:47 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
if (switch_channel_get_state(channel) >= CS_HANGUP || switch_test_flag(tech_pvt, TFLAG_BYE)) {
|
2006-08-18 01:28:50 +00:00
|
|
|
goto out;
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-04-12 20:48:47 +00:00
|
|
|
|
2006-08-18 01:28:50 +00:00
|
|
|
if (!activate_rtp(tech_pvt)) {
|
|
|
|
goto out;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
|
2006-08-18 16:36:26 +00:00
|
|
|
if (!do_candidates(tech_pvt, 0)) {
|
|
|
|
goto out;
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
switch_channel_answer(channel);
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-10-10 00:11:41 +00:00
|
|
|
ret = SWITCH_STATUS_SUCCESS;
|
|
|
|
|
2006-09-22 15:22:31 +00:00
|
|
|
goto done;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-04-06 16:20:07 +00:00
|
|
|
out:
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(&session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2007-04-06 16:20:07 +00:00
|
|
|
done:
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-10-10 00:11:41 +00:00
|
|
|
return ret;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2006-04-27 15:59:58 +00:00
|
|
|
State methods they get called when the state changes to the specific state
|
|
|
|
returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
|
|
|
|
so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
|
2006-03-31 19:38:09 +00:00
|
|
|
*/
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t channel_on_init(switch_core_session_t *session)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel;
|
2006-03-31 19:38:09 +00:00
|
|
|
struct private_object *tech_pvt = NULL;
|
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-04-06 19:50:53 +00:00
|
|
|
tech_pvt->read_frame.buflen = SWITCH_RTP_MAX_BUF_LEN;
|
|
|
|
|
2006-10-10 00:11:41 +00:00
|
|
|
switch_set_flag(tech_pvt, TFLAG_READY);
|
|
|
|
|
|
|
|
if (negotiate_media(session) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
/* Move Channel's State Machine to RING */
|
|
|
|
switch_channel_set_state(channel, CS_RING);
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t channel_on_ring(switch_core_session_t *session)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
2006-03-31 19:38:09 +00:00
|
|
|
struct private_object *tech_pvt = NULL;
|
|
|
|
|
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL RING\n", switch_channel_get_name(channel));
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t channel_on_execute(switch_core_session_t *session)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
|
|
|
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
2006-03-31 19:38:09 +00:00
|
|
|
struct private_object *tech_pvt = NULL;
|
|
|
|
|
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL EXECUTE\n", switch_channel_get_name(channel));
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t channel_on_hangup(switch_core_session_t *session)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
2006-03-31 19:38:09 +00:00
|
|
|
struct private_object *tech_pvt = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-12-20 15:41:45 +00:00
|
|
|
if (tech_pvt->profile->ip && tech_pvt->local_port) {
|
|
|
|
switch_rtp_release_port(tech_pvt->profile->ip, tech_pvt->local_port);
|
|
|
|
}
|
|
|
|
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
|
|
|
|
switch_clear_flag_locked(tech_pvt, TFLAG_VOICE);
|
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_BYE);
|
2006-10-24 18:23:23 +00:00
|
|
|
|
|
|
|
/* Dunno why, but if googletalk calls us for the first time, as soon as the call ends
|
2007-03-29 22:31:56 +00:00
|
|
|
they think we are offline for no reason so we send this presence packet to stop it from happening
|
|
|
|
We should find out why.....
|
2007-04-06 16:20:07 +00:00
|
|
|
*/
|
2007-03-29 22:31:56 +00:00
|
|
|
if ((tech_pvt->profile->user_flags & LDL_FLAG_COMPONENT) && is_special(tech_pvt->them)) {
|
2007-04-04 22:22:55 +00:00
|
|
|
ldl_handle_send_presence(tech_pvt->profile->handle, tech_pvt->them, tech_pvt->us, NULL, NULL, "Click To Call", tech_pvt->profile->avatar);
|
2006-10-24 18:23:23 +00:00
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
if (tech_pvt->dlsession) {
|
2006-08-18 18:44:11 +00:00
|
|
|
if (!switch_test_flag(tech_pvt, TFLAG_TERM)) {
|
|
|
|
ldl_session_terminate(tech_pvt->dlsession);
|
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_TERM);
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
ldl_session_destroy(&tech_pvt->dlsession);
|
|
|
|
}
|
|
|
|
|
2006-08-28 23:05:26 +00:00
|
|
|
if (switch_rtp_ready(tech_pvt->rtp_session)) {
|
2006-04-03 21:00:13 +00:00
|
|
|
switch_rtp_destroy(&tech_pvt->rtp_session);
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "NUKE RTP\n");
|
2006-03-31 19:38:09 +00:00
|
|
|
tech_pvt->rtp_session = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tech_pvt->read_codec.implementation) {
|
|
|
|
switch_core_codec_destroy(&tech_pvt->read_codec);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (tech_pvt->write_codec.implementation) {
|
|
|
|
switch_core_codec_destroy(&tech_pvt->write_codec);
|
|
|
|
}
|
|
|
|
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL HANGUP\n", switch_channel_get_name(channel));
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
2006-03-31 19:38:09 +00:00
|
|
|
struct private_object *tech_pvt = NULL;
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (!(channel = switch_core_session_get_channel(session))) {
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(tech_pvt = switch_core_session_get_private(session))) {
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
switch (sig) {
|
|
|
|
case SWITCH_SIG_KILL:
|
|
|
|
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) {
|
|
|
|
if (!switch_test_flag(tech_pvt, TFLAG_TERM)) {
|
|
|
|
ldl_session_terminate(tech_pvt->dlsession);
|
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_TERM);
|
|
|
|
}
|
|
|
|
ldl_session_destroy(&tech_pvt->dlsession);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (switch_rtp_ready(tech_pvt->rtp_session)) {
|
|
|
|
switch_rtp_kill_socket(tech_pvt->rtp_session);
|
|
|
|
}
|
|
|
|
break;
|
2006-12-21 16:46:11 +00:00
|
|
|
case SWITCH_SIG_BREAK:
|
2007-03-29 22:31:56 +00:00
|
|
|
if (switch_rtp_ready(tech_pvt->rtp_session)) {
|
2007-02-23 18:04:52 +00:00
|
|
|
switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_BREAK);
|
|
|
|
}
|
2006-12-21 16:46:11 +00:00
|
|
|
break;
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2006-08-18 16:36:26 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL KILL\n", switch_channel_get_name(channel));
|
2006-08-18 16:36:26 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t channel_on_loopback(switch_core_session_t *session)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL LOOPBACK\n");
|
2006-03-31 19:38:09 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t channel_on_transmit(switch_core_session_t *session)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "CHANNEL TRANSMIT\n");
|
2006-03-31 19:38:09 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t channel_waitfor_read(switch_core_session_t *session, int ms, int stream_id)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
|
|
|
struct private_object *tech_pvt = NULL;
|
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t channel_waitfor_write(switch_core_session_t *session, int ms, int stream_id)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
|
|
|
struct private_object *tech_pvt = NULL;
|
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-12-22 01:00:10 +00:00
|
|
|
static switch_status_t channel_send_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
|
|
|
struct private_object *tech_pvt = NULL;
|
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-12-22 01:00:10 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "DTMF [%c]\n", dtmf->digit);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-12-22 00:32:20 +00:00
|
|
|
return switch_rtp_queue_rfc2833(tech_pvt->rtp_session, dtmf);
|
2006-05-04 17:51:53 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
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)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
|
|
|
struct private_object *tech_pvt = NULL;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
2007-04-07 01:57:54 +00:00
|
|
|
int payload = 0;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
tech_pvt = (struct private_object *) switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
while (!(tech_pvt->read_codec.implementation && switch_rtp_ready(tech_pvt->rtp_session))) {
|
|
|
|
if (switch_channel_ready(channel)) {
|
|
|
|
switch_yield(10000);
|
|
|
|
} else {
|
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
2006-10-25 17:00:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
tech_pvt->read_frame.datalen = 0;
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_READING);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
#if 0
|
|
|
|
if (tech_pvt->last_read) {
|
2007-10-03 16:44:11 +00:00
|
|
|
elapsed = (unsigned int) ((switch_timestamp_now() - tech_pvt->last_read) / 1000);
|
2007-04-07 01:57:54 +00:00
|
|
|
if (elapsed > 60000) {
|
|
|
|
return SWITCH_STATUS_TIMEOUT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_IO)) {
|
|
|
|
switch_status_t status;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt->rtp_session != NULL);
|
2007-04-07 01:57:54 +00:00
|
|
|
tech_pvt->read_frame.datalen = 0;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-05-05 16:03:15 +00:00
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
while (switch_test_flag(tech_pvt, TFLAG_IO) && tech_pvt->read_frame.datalen == 0) {
|
|
|
|
tech_pvt->read_frame.flags = SFF_NONE;
|
|
|
|
|
|
|
|
status = switch_rtp_zerocopy_read_frame(tech_pvt->rtp_session, &tech_pvt->read_frame);
|
|
|
|
if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
|
2006-05-03 23:45:07 +00:00
|
|
|
|
2006-04-13 23:19:33 +00:00
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
payload = tech_pvt->read_frame.payload;
|
|
|
|
|
|
|
|
#if 0
|
2007-10-03 16:44:11 +00:00
|
|
|
elapsed = (unsigned int) ((switch_timestamp_now() - started) / 1000);
|
2007-04-07 01:57:54 +00:00
|
|
|
|
|
|
|
if (timeout > -1) {
|
|
|
|
if (elapsed >= (unsigned int) timeout) {
|
|
|
|
return SWITCH_STATUS_BREAK;
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-10-03 16:44:11 +00:00
|
|
|
elapsed = (unsigned int) ((switch_timestamp_now() - last_act) / 1000);
|
2007-04-07 01:57:54 +00:00
|
|
|
if (elapsed >= hard_timeout) {
|
|
|
|
return SWITCH_STATUS_BREAK;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (switch_rtp_has_dtmf(tech_pvt->rtp_session)) {
|
2007-12-22 00:32:20 +00:00
|
|
|
switch_dtmf_t dtmf = { 0 };
|
|
|
|
switch_rtp_dequeue_dtmf(tech_pvt->rtp_session, &dtmf);
|
|
|
|
switch_channel_queue_dtmf(channel, &dtmf);
|
2007-04-07 01:57:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (tech_pvt->read_frame.datalen > 0) {
|
|
|
|
size_t bytes = 0;
|
|
|
|
int frames = 1;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
if (!switch_test_flag((&tech_pvt->read_frame), SFF_CNG)) {
|
|
|
|
if ((bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame)) {
|
|
|
|
frames = (tech_pvt->read_frame.datalen / bytes);
|
|
|
|
}
|
|
|
|
tech_pvt->read_frame.samples = (int) (frames * tech_pvt->read_codec.implementation->samples_per_frame);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_clear_flag_locked(tech_pvt, TFLAG_READING);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
if (tech_pvt->read_frame.datalen == 0) {
|
|
|
|
*frame = NULL;
|
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
*frame = &tech_pvt->read_frame;
|
2007-04-07 01:57:54 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
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)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
|
|
|
struct private_object *tech_pvt;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
2006-04-29 23:43:28 +00:00
|
|
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
2006-03-31 19:38:09 +00:00
|
|
|
int bytes = 0, samples = 0, frames = 0;
|
|
|
|
|
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
tech_pvt = (struct private_object *) switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
while (!(tech_pvt->read_codec.implementation && switch_rtp_ready(tech_pvt->rtp_session))) {
|
|
|
|
if (switch_channel_ready(channel)) {
|
|
|
|
switch_yield(10000);
|
|
|
|
} else {
|
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
2006-04-13 00:47:16 +00:00
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-12-12 23:51:26 +00:00
|
|
|
if (!tech_pvt->read_codec.implementation) {
|
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
if (!switch_test_flag(tech_pvt, TFLAG_IO)) {
|
2006-03-31 19:38:09 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_WRITING);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
if (!switch_test_flag(frame, SFF_CNG)) {
|
|
|
|
if (tech_pvt->read_codec.implementation->encoded_bytes_per_frame) {
|
|
|
|
bytes = tech_pvt->read_codec.implementation->encoded_bytes_per_frame;
|
|
|
|
frames = ((int) frame->datalen / bytes);
|
|
|
|
} else
|
|
|
|
frames = 1;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
samples = frames * tech_pvt->read_codec.implementation->samples_per_frame;
|
2006-04-15 06:06:46 +00:00
|
|
|
}
|
2007-04-07 01:57:54 +00:00
|
|
|
#if 0
|
|
|
|
printf("%s %s->%s send %d bytes %d samples in %d frames ts=%d\n",
|
|
|
|
switch_channel_get_name(channel),
|
|
|
|
tech_pvt->local_sdp_audio_ip, tech_pvt->remote_sdp_audio_ip, frame->datalen, samples, frames, tech_pvt->timestamp_send);
|
|
|
|
#endif
|
2007-03-05 20:53:54 +00:00
|
|
|
|
2007-04-07 01:57:54 +00:00
|
|
|
tech_pvt->timestamp_send += samples;
|
|
|
|
//switch_rtp_write_frame(tech_pvt->rtp_session, frame, tech_pvt->timestamp_send);
|
2008-01-11 04:23:09 +00:00
|
|
|
switch_rtp_write_frame(tech_pvt->rtp_session, frame);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_clear_flag_locked(tech_pvt, TFLAG_WRITING);
|
2006-03-31 19:38:09 +00:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t channel_answer_channel(switch_core_session_t *session)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
|
|
|
struct private_object *tech_pvt;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-04-24 14:23:06 +00:00
|
|
|
if (!switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
|
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
|
|
|
|
}
|
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-04-17 18:25:43 +00:00
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t channel_receive_message(switch_core_session_t *session, switch_core_session_message_t *msg)
|
2006-04-17 18:25:43 +00:00
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel;
|
2006-04-17 18:25:43 +00:00
|
|
|
struct private_object *tech_pvt;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-04-17 18:25:43 +00:00
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-04-17 18:25:43 +00:00
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-04-17 18:25:43 +00:00
|
|
|
|
|
|
|
switch (msg->message_id) {
|
2007-04-16 16:53:30 +00:00
|
|
|
case SWITCH_MESSAGE_INDICATE_ANSWER:
|
|
|
|
channel_answer_channel(session);
|
|
|
|
break;
|
2006-04-17 18:25:43 +00:00
|
|
|
case SWITCH_MESSAGE_INDICATE_BRIDGE:
|
2007-12-06 22:26:37 +00:00
|
|
|
/*
|
2007-03-29 22:31:56 +00:00
|
|
|
if (tech_pvt->rtp_session && switch_test_flag(tech_pvt->profile, TFLAG_TIMER)) {
|
2006-04-27 15:59:58 +00:00
|
|
|
switch_rtp_clear_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "De-activate timed RTP!\n");
|
|
|
|
//switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_TIMER_RECLOCK);
|
|
|
|
}
|
2007-12-06 22:26:37 +00:00
|
|
|
*/
|
2006-04-27 15:59:58 +00:00
|
|
|
break;
|
2006-04-17 18:25:43 +00:00
|
|
|
case SWITCH_MESSAGE_INDICATE_UNBRIDGE:
|
2007-12-06 22:26:37 +00:00
|
|
|
/*
|
2006-05-24 16:10:05 +00:00
|
|
|
if (tech_pvt->rtp_session && switch_test_flag(tech_pvt->profile, TFLAG_TIMER)) {
|
2006-04-27 15:59:58 +00:00
|
|
|
switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Re-activate timed RTP!\n");
|
|
|
|
//switch_rtp_clear_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_TIMER_RECLOCK);
|
|
|
|
}
|
2007-12-06 22:26:37 +00:00
|
|
|
*/
|
2006-04-27 15:59:58 +00:00
|
|
|
break;
|
2006-04-17 18:25:43 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
2006-08-18 01:28:50 +00:00
|
|
|
|
|
|
|
static switch_status_t channel_receive_event(switch_core_session_t *session, switch_event_t *event)
|
|
|
|
{
|
|
|
|
switch_channel_t *channel;
|
2007-03-29 22:31:56 +00:00
|
|
|
struct private_object *tech_pvt;
|
2006-08-18 01:28:50 +00:00
|
|
|
char *subject, *body;
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-08-18 01:28:50 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-08-18 01:28:50 +00:00
|
|
|
|
|
|
|
|
|
|
|
if (!(body = switch_event_get_body(event))) {
|
|
|
|
body = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(subject = switch_event_get_header(event, "subject"))) {
|
|
|
|
subject = "None";
|
|
|
|
}
|
|
|
|
|
|
|
|
ldl_session_send_msg(tech_pvt->dlsession, subject, body);
|
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-10-29 18:10:06 +00:00
|
|
|
switch_state_handler_table_t dingaling_event_handlers = {
|
2006-03-31 19:38:09 +00:00
|
|
|
/*.on_init */ channel_on_init,
|
|
|
|
/*.on_ring */ channel_on_ring,
|
|
|
|
/*.on_execute */ channel_on_execute,
|
|
|
|
/*.on_hangup */ channel_on_hangup,
|
|
|
|
/*.on_loopback */ channel_on_loopback,
|
|
|
|
/*.on_transmit */ channel_on_transmit
|
|
|
|
};
|
|
|
|
|
2007-10-29 18:10:06 +00:00
|
|
|
switch_io_routines_t dingaling_io_routines = {
|
2006-03-31 19:38:09 +00:00
|
|
|
/*.outgoing_channel */ channel_outgoing_channel,
|
|
|
|
/*.read_frame */ channel_read_frame,
|
|
|
|
/*.write_frame */ channel_write_frame,
|
|
|
|
/*.kill_channel */ channel_kill_channel,
|
|
|
|
/*.waitfor_read */ channel_waitfor_read,
|
|
|
|
/*.waitfor_write */ channel_waitfor_write,
|
2006-04-17 18:25:43 +00:00
|
|
|
/*.send_dtmf */ channel_send_dtmf,
|
2007-03-29 22:31:56 +00:00
|
|
|
/*.receive_message */ channel_receive_message,
|
|
|
|
/*.receive_event */ channel_receive_event
|
2006-03-31 19:38:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines
|
2006-04-27 15:59:58 +00:00
|
|
|
that allocate memory or you will have 1 channel with memory allocated from another channel's pool!
|
2006-03-31 19:38:09 +00:00
|
|
|
*/
|
2007-03-29 22:31:56 +00:00
|
|
|
static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *session,
|
|
|
|
switch_caller_profile_t *outbound_profile,
|
2007-12-20 21:42:00 +00:00
|
|
|
switch_core_session_t **new_session, switch_memory_pool_t **pool, switch_originate_flag_t flags)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2007-10-29 18:10:06 +00:00
|
|
|
if ((*new_session = switch_core_session_request(dingaling_endpoint_interface, pool)) != 0) {
|
2006-03-31 19:38:09 +00:00
|
|
|
struct private_object *tech_pvt;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel;
|
|
|
|
switch_caller_profile_t *caller_profile = NULL;
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *mdl_profile = NULL;
|
2006-03-31 19:38:09 +00:00
|
|
|
ldl_session_t *dlsession = NULL;
|
|
|
|
char *profile_name;
|
|
|
|
char *callto;
|
|
|
|
char idbuf[1024];
|
2007-12-22 01:00:10 +00:00
|
|
|
char *full_id = NULL;
|
2006-03-31 19:38:09 +00:00
|
|
|
char sess_id[11] = "";
|
2006-05-04 14:37:11 +00:00
|
|
|
char *dnis = NULL;
|
|
|
|
char workspace[1024] = "";
|
2007-11-01 11:28:26 +00:00
|
|
|
char *p, *u, ubuf[512] = "", *user = NULL, *f_cid_msg = NULL;
|
|
|
|
const char *cid_msg = NULL;
|
2006-03-31 19:38:09 +00:00
|
|
|
switch_copy_string(workspace, outbound_profile->destination_number, sizeof(workspace));
|
|
|
|
profile_name = workspace;
|
2007-02-01 05:23:29 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
if ((callto = strchr(profile_name, '/'))) {
|
|
|
|
*callto++ = '\0';
|
|
|
|
} else {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Invalid URL!\n");
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2007-02-09 20:03:07 +00:00
|
|
|
return SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2006-11-15 00:40:45 +00:00
|
|
|
|
2006-05-04 15:39:14 +00:00
|
|
|
if ((dnis = strchr(callto, ':'))) {
|
2006-05-04 14:37:11 +00:00
|
|
|
*dnis++ = '\0';
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
for (p = callto; p && *p; p++) {
|
|
|
|
*p = (char) tolower(*p);
|
|
|
|
}
|
2006-11-21 19:01:54 +00:00
|
|
|
|
|
|
|
if ((p = strchr(profile_name, '@'))) {
|
|
|
|
*p++ = '\0';
|
|
|
|
u = profile_name;
|
|
|
|
profile_name = p;
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(ubuf, sizeof(ubuf), "%s@%s/talk", u, profile_name);
|
2006-11-21 19:01:54 +00:00
|
|
|
user = ubuf;
|
|
|
|
}
|
2006-11-21 15:43:55 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
if ((mdl_profile = switch_core_hash_find(globals.profile_hash, profile_name))) {
|
2006-11-21 19:01:54 +00:00
|
|
|
if (!(mdl_profile->user_flags & LDL_FLAG_COMPONENT)) {
|
2006-11-15 20:21:29 +00:00
|
|
|
user = ldl_handle_get_login(mdl_profile->handle);
|
2006-11-21 19:01:54 +00:00
|
|
|
} else {
|
|
|
|
if (!user) {
|
2007-11-01 11:28:26 +00:00
|
|
|
const char *id_num;
|
2007-04-23 19:03:06 +00:00
|
|
|
|
|
|
|
if (!(id_num = outbound_profile->caller_id_number)) {
|
|
|
|
if (!(id_num = outbound_profile->caller_id_name)) {
|
|
|
|
id_num = "nobody";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strchr(id_num, '@')) {
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(ubuf, sizeof(ubuf), "%s/talk", id_num);
|
2006-11-21 19:01:54 +00:00
|
|
|
user = ubuf;
|
|
|
|
} else {
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(ubuf, sizeof(ubuf), "%s@%s/talk", id_num, profile_name);
|
2007-04-23 19:03:06 +00:00
|
|
|
user = ubuf;
|
2006-11-21 19:01:54 +00:00
|
|
|
}
|
|
|
|
}
|
2006-11-14 17:41:35 +00:00
|
|
|
}
|
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
if (!ldl_handle_ready(mdl_profile->handle)) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doh! we are not logged in yet!\n");
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2007-02-09 20:03:07 +00:00
|
|
|
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2006-10-18 22:57:35 +00:00
|
|
|
if (!(full_id = ldl_handle_probe(mdl_profile->handle, callto, user, idbuf, sizeof(idbuf)))) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unknown Recipient!\n");
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(new_session, __LINE__, SWITCH_CAUSE_NO_USER_RESPONSE);
|
2007-02-09 20:03:07 +00:00
|
|
|
return SWITCH_CAUSE_NO_USER_RESPONSE;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
} else {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Unknown Profile!\n");
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2007-02-09 20:03:07 +00:00
|
|
|
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
switch_core_session_add_stream(*new_session, NULL);
|
2007-03-30 00:13:31 +00:00
|
|
|
if ((tech_pvt = (struct private_object *) switch_core_session_alloc(*new_session, sizeof(struct private_object))) != 0) {
|
2006-03-31 19:38:09 +00:00
|
|
|
memset(tech_pvt, 0, sizeof(*tech_pvt));
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(*new_session));
|
2006-04-21 22:31:08 +00:00
|
|
|
tech_pvt->flags |= globals.flags;
|
|
|
|
tech_pvt->flags |= mdl_profile->flags;
|
2006-03-31 19:38:09 +00:00
|
|
|
channel = switch_core_session_get_channel(*new_session);
|
|
|
|
switch_core_session_set_private(*new_session, tech_pvt);
|
|
|
|
tech_pvt->session = *new_session;
|
|
|
|
tech_pvt->codec_index = -1;
|
2008-01-02 03:39:29 +00:00
|
|
|
if (!(tech_pvt->local_port = switch_rtp_request_port(mdl_profile->ip))) {
|
2007-12-11 19:15:02 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No RTP port available!\n");
|
|
|
|
terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
|
|
|
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
|
|
|
}
|
2006-05-03 23:45:07 +00:00
|
|
|
tech_pvt->recip = switch_core_session_strdup(*new_session, full_id);
|
2007-12-22 01:00:10 +00:00
|
|
|
if (dnis) {
|
|
|
|
tech_pvt->dnis = switch_core_session_strdup(*new_session, dnis);
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
} else {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2007-02-09 20:03:07 +00:00
|
|
|
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (outbound_profile) {
|
|
|
|
char name[128];
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(name, sizeof(name), "DingaLing/%s", outbound_profile->destination_number);
|
2006-03-31 19:38:09 +00:00
|
|
|
switch_channel_set_name(channel, name);
|
|
|
|
|
|
|
|
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
|
|
|
|
switch_channel_set_caller_profile(channel, caller_profile);
|
|
|
|
tech_pvt->caller_profile = caller_profile;
|
|
|
|
} else {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Doh! no caller profile\n");
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(new_session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2007-02-09 20:03:07 +00:00
|
|
|
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch_channel_set_flag(channel, CF_OUTBOUND);
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
|
2007-01-29 22:22:29 +00:00
|
|
|
|
2006-04-04 16:07:40 +00:00
|
|
|
switch_stun_random_string(sess_id, 10, "0123456789");
|
2007-01-29 22:22:29 +00:00
|
|
|
tech_pvt->us = switch_core_session_strdup(*new_session, user);
|
|
|
|
tech_pvt->them = switch_core_session_strdup(*new_session, full_id);
|
2006-11-16 16:10:39 +00:00
|
|
|
ldl_session_create(&dlsession, mdl_profile->handle, sess_id, full_id, user, LDL_FLAG_OUTBOUND);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-02-14 19:47:16 +00:00
|
|
|
if (session) {
|
|
|
|
switch_channel_t *calling_channel = switch_core_session_get_channel(session);
|
|
|
|
cid_msg = switch_channel_get_variable(calling_channel, "dl_cid_msg");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!cid_msg) {
|
2007-03-30 00:13:31 +00:00
|
|
|
f_cid_msg = switch_mprintf("Incoming Call From %s %s\n", outbound_profile->caller_id_name, outbound_profile->caller_id_number);
|
2007-02-14 19:47:16 +00:00
|
|
|
cid_msg = f_cid_msg;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cid_msg) {
|
2007-02-15 17:48:14 +00:00
|
|
|
char *them;
|
2007-02-15 16:53:44 +00:00
|
|
|
them = strdup(tech_pvt->them);
|
2007-02-15 17:48:14 +00:00
|
|
|
if (them) {
|
2007-12-12 23:51:26 +00:00
|
|
|
char *ptr;
|
|
|
|
if ((ptr = strchr(them, '/'))) {
|
|
|
|
*ptr = '\0';
|
2007-02-15 16:53:44 +00:00
|
|
|
}
|
2007-02-15 17:48:14 +00:00
|
|
|
ldl_handle_send_msg(mdl_profile->handle, tech_pvt->us, them, "", cid_msg);
|
2007-02-15 16:53:44 +00:00
|
|
|
}
|
|
|
|
switch_safe_free(them);
|
2007-02-14 15:32:02 +00:00
|
|
|
}
|
2007-02-14 19:47:16 +00:00
|
|
|
switch_safe_free(f_cid_msg);
|
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
tech_pvt->profile = mdl_profile;
|
|
|
|
ldl_session_set_private(dlsession, *new_session);
|
2007-02-01 05:23:29 +00:00
|
|
|
ldl_session_set_value(dlsession, "dnis", dnis);
|
|
|
|
ldl_session_set_value(dlsession, "caller_id_name", outbound_profile->caller_id_name);
|
|
|
|
ldl_session_set_value(dlsession, "caller_id_number", outbound_profile->caller_id_number);
|
2006-03-31 19:38:09 +00:00
|
|
|
tech_pvt->dlsession = dlsession;
|
2006-08-18 16:36:26 +00:00
|
|
|
if (!get_codecs(tech_pvt)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(new_session, __LINE__, SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL);
|
|
|
|
return SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL;
|
2006-08-18 16:36:26 +00:00
|
|
|
}
|
2006-10-10 00:11:41 +00:00
|
|
|
switch_channel_set_state(channel, CS_INIT);
|
2007-02-09 20:03:07 +00:00
|
|
|
return SWITCH_CAUSE_SUCCESS;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-02-09 20:03:07 +00:00
|
|
|
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-06-13 17:06:10 +00:00
|
|
|
SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2007-06-20 07:15:53 +00:00
|
|
|
switch_chat_interface_t *chat_interface;
|
|
|
|
switch_api_interface_t *api_interface;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-06-20 07:15:53 +00:00
|
|
|
module_pool = pool;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
load_config();
|
|
|
|
|
2006-05-01 18:55:04 +00:00
|
|
|
if (switch_event_reserve_subclass(DL_EVENT_LOGIN_SUCCESS) != SWITCH_STATUS_SUCCESS) {
|
2007-11-23 18:50:54 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", DL_EVENT_LOGIN_SUCCESS);
|
2006-05-01 18:55:04 +00:00
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (switch_event_reserve_subclass(DL_EVENT_LOGIN_FAILURE) != SWITCH_STATUS_SUCCESS) {
|
2007-11-23 18:50:54 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", DL_EVENT_LOGIN_FAILURE);
|
2006-05-01 18:55:04 +00:00
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
|
|
|
|
2006-06-22 21:57:40 +00:00
|
|
|
if (switch_event_reserve_subclass(DL_EVENT_CONNECTED) != SWITCH_STATUS_SUCCESS) {
|
2007-11-23 18:50:54 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass %s!\n", DL_EVENT_CONNECTED);
|
2006-06-22 21:57:40 +00:00
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_IN, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
2006-10-18 22:57:35 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_PROBE, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
2006-12-19 17:48:50 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
if (switch_event_bind((char *) modname, SWITCH_EVENT_PRESENCE_OUT, SWITCH_EVENT_SUBCLASS_ANY, pres_event_handler, NULL) != SWITCH_STATUS_SUCCESS) {
|
2006-10-18 22:57:35 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (switch_event_bind((char *) modname, SWITCH_EVENT_ROSTER, SWITCH_EVENT_SUBCLASS_ANY, roster_event_handler, NULL)
|
|
|
|
!= SWITCH_STATUS_SUCCESS) {
|
2006-10-18 22:57:35 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't bind!\n");
|
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
/* connect my internal structure to the blank pointer passed to me */
|
2007-06-20 07:15:53 +00:00
|
|
|
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
2007-10-29 18:10:06 +00:00
|
|
|
dingaling_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
|
|
|
|
dingaling_endpoint_interface->interface_name = "dingaling";
|
|
|
|
dingaling_endpoint_interface->io_routines = &dingaling_io_routines;
|
|
|
|
dingaling_endpoint_interface->state_handler = &dingaling_event_handlers;
|
2007-06-20 07:15:53 +00:00
|
|
|
|
|
|
|
#define PRES_SYNTAX "dl_pres <profile_name>"
|
|
|
|
#define LOGOUT_SYNTAX "dl_logout <profile_name>"
|
|
|
|
#define LOGIN_SYNTAX "dl_login <profile_name>"
|
|
|
|
#define DEBUG_SYNTAX "dl_debug [true|false]"
|
|
|
|
|
|
|
|
SWITCH_ADD_API(api_interface, "dl_debug", "DingaLing Debug", dl_debug, DEBUG_SYNTAX);
|
|
|
|
SWITCH_ADD_API(api_interface, "dl_pres", "DingaLing Presence", dl_pres, PRES_SYNTAX);
|
|
|
|
SWITCH_ADD_API(api_interface, "dl_logout", "DingaLing Logout", dl_logout, LOGOUT_SYNTAX);
|
|
|
|
SWITCH_ADD_API(api_interface, "dl_login", "DingaLing Login", dl_login, LOGIN_SYNTAX);
|
|
|
|
SWITCH_ADD_CHAT(chat_interface, MDL_CHAT_PROTO, chat_send);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
/* indicate that the module should continue to be loaded */
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static ldl_status handle_loop(ldl_handle_t * handle)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
|
|
|
if (!globals.running) {
|
|
|
|
return LDL_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
return LDL_STATUS_SUCCESS;
|
|
|
|
}
|
2006-05-02 16:43:13 +00:00
|
|
|
|
2007-04-04 17:32:56 +00:00
|
|
|
static switch_status_t init_profile(mdl_profile_t *profile, uint8_t login)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2007-12-12 23:51:26 +00:00
|
|
|
ldl_handle_t *handle;
|
|
|
|
|
|
|
|
if (!profile) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Invalid Profile\n");
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(profile->login && profile->password && profile->dialplan && profile->message && profile->ip && profile->name && profile->exten)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
2007-12-12 23:51:26 +00:00
|
|
|
"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);
|
2006-05-02 16:43:13 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_FALSE;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2006-05-02 16:43:13 +00:00
|
|
|
|
2007-12-12 23:51:26 +00:00
|
|
|
if (switch_test_flag(profile, TFLAG_TIMER) && !profile->timer_name) {
|
|
|
|
profile->timer_name = switch_core_strdup(module_pool, "soft");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!login) {
|
|
|
|
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);
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ldl_handle_init(&handle,
|
|
|
|
profile->login,
|
|
|
|
profile->password,
|
|
|
|
profile->server,
|
|
|
|
profile->user_flags, 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);
|
|
|
|
}
|
|
|
|
|
2006-05-02 16:43:13 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
2007-06-13 17:06:10 +00:00
|
|
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dingaling_shutdown)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2006-10-20 06:44:58 +00:00
|
|
|
sign_off();
|
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
if (globals.running) {
|
|
|
|
int x = 0;
|
|
|
|
globals.running = 0;
|
|
|
|
while (globals.handles > 0) {
|
|
|
|
switch_yield(100000);
|
|
|
|
x++;
|
2007-03-29 22:31:56 +00:00
|
|
|
if (x > 10) {
|
2006-03-31 19:38:09 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2007-04-07 21:23:01 +00:00
|
|
|
|
2006-05-10 03:23:05 +00:00
|
|
|
if (globals.init) {
|
|
|
|
ldl_global_destroy();
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2007-09-29 01:06:08 +00:00
|
|
|
switch_core_hash_destroy(&globals.profile_hash);
|
2006-03-31 19:38:09 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-04 17:32:56 +00:00
|
|
|
static void set_profile_val(mdl_profile_t *profile, char *var, char *val)
|
2006-05-02 16:43:13 +00:00
|
|
|
{
|
2007-12-12 23:51:26 +00:00
|
|
|
if (!var) return;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-05-02 16:43:13 +00:00
|
|
|
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);
|
2007-04-04 22:22:55 +00:00
|
|
|
} else if (!strcasecmp(var, "avatar")) {
|
|
|
|
profile->avatar = switch_core_strdup(module_pool, val);
|
2007-11-15 16:55:46 +00:00
|
|
|
} else if (!strcasecmp(var, "odbc-dsn") && !switch_strlen_zero(val)) {
|
2007-04-04 17:32:56 +00:00
|
|
|
#ifdef SWITCH_HAVE_ODBC
|
|
|
|
profile->odbc_dsn = switch_core_strdup(module_pool, val);
|
|
|
|
if ((profile->odbc_user = strchr(profile->odbc_dsn, ':'))) {
|
|
|
|
*profile->odbc_user++ = '\0';
|
2007-11-15 16:55:46 +00:00
|
|
|
if ((profile->odbc_pass = strchr(profile->odbc_user, ':'))) {
|
|
|
|
*profile->odbc_pass++ = '\0';
|
|
|
|
}
|
2007-04-04 17:32:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ODBC IS NOT AVAILABLE!\n");
|
|
|
|
#endif
|
2006-05-24 16:10:05 +00:00
|
|
|
} else if (!strcasecmp(var, "use-rtp-timer") && switch_true(val)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_set_flag(profile, TFLAG_TIMER);
|
2007-12-22 01:00:10 +00:00
|
|
|
} else if (!strcasecmp(var, "dialplan") && !switch_strlen_zero(val)) {
|
2006-05-02 16:43:13 +00:00
|
|
|
profile->dialplan = switch_core_strdup(module_pool, val);
|
2007-04-07 21:13:54 +00:00
|
|
|
#ifdef AUTO_REPLY // gotta fix looping on this
|
2006-10-12 14:06:09 +00:00
|
|
|
} else if (!strcasecmp(var, "auto-reply")) {
|
|
|
|
profile->auto_reply = switch_core_strdup(module_pool, val);
|
2007-04-07 21:13:54 +00:00
|
|
|
#endif
|
2007-12-22 01:00:10 +00:00
|
|
|
} else if (!strcasecmp(var, "name") && !switch_strlen_zero(val)) {
|
2006-05-02 16:43:13 +00:00
|
|
|
profile->name = switch_core_strdup(module_pool, val);
|
2007-12-22 01:00:10 +00:00
|
|
|
} else if (!strcasecmp(var, "message") && !switch_strlen_zero(val)) {
|
2006-05-02 16:43:13 +00:00
|
|
|
profile->message = switch_core_strdup(module_pool, val);
|
|
|
|
} else if (!strcasecmp(var, "rtp-ip")) {
|
2007-12-12 23:51:26 +00:00
|
|
|
profile->ip = switch_core_strdup(module_pool, strcasecmp(switch_str_nil(val), "auto") ? switch_str_nil(val) : globals.guess_ip);
|
2006-05-02 16:43:13 +00:00
|
|
|
} else if (!strcasecmp(var, "ext-rtp-ip")) {
|
2007-12-12 23:51:26 +00:00
|
|
|
profile->extip = switch_core_strdup(module_pool, strcasecmp(switch_str_nil(val), "auto") ? switch_str_nil(val) : globals.guess_ip);
|
2007-12-22 01:00:10 +00:00
|
|
|
} else if (!strcasecmp(var, "server") && !switch_strlen_zero(val)) {
|
2006-08-11 00:24:38 +00:00
|
|
|
profile->server = switch_core_strdup(module_pool, val);
|
2007-12-22 01:00:10 +00:00
|
|
|
} else if (!strcasecmp(var, "rtp-timer-name") && !switch_strlen_zero(val)) {
|
2006-09-12 22:23:45 +00:00
|
|
|
profile->timer_name = switch_core_strdup(module_pool, val);
|
2007-12-22 01:00:10 +00:00
|
|
|
} else if (!strcasecmp(var, "lanaddr") && !switch_strlen_zero(val)) {
|
2006-05-02 16:43:13 +00:00
|
|
|
profile->lanaddr = switch_core_strdup(module_pool, val);
|
2006-08-11 00:24:38 +00:00
|
|
|
} else if (!strcasecmp(var, "tls")) {
|
|
|
|
if (switch_true(val)) {
|
|
|
|
profile->user_flags |= LDL_FLAG_TLS;
|
|
|
|
}
|
|
|
|
} else if (!strcasecmp(var, "sasl")) {
|
2007-12-12 23:51:26 +00:00
|
|
|
if (val && !strcasecmp(val, "plain")) {
|
2006-08-11 00:24:38 +00:00
|
|
|
profile->user_flags |= LDL_FLAG_SASL_PLAIN;
|
2007-12-12 23:51:26 +00:00
|
|
|
} else if (val && !strcasecmp(val, "md5")) {
|
2006-08-11 00:24:38 +00:00
|
|
|
profile->user_flags |= LDL_FLAG_SASL_MD5;
|
|
|
|
}
|
2007-12-22 01:00:10 +00:00
|
|
|
} else if (!strcasecmp(var, "exten") && !switch_strlen_zero(val)) {
|
2006-05-02 16:43:13 +00:00
|
|
|
profile->exten = switch_core_strdup(module_pool, val);
|
2007-12-22 01:00:10 +00:00
|
|
|
} else if (!strcasecmp(var, "context") && !switch_strlen_zero(val)) {
|
2006-05-02 16:43:13 +00:00
|
|
|
profile->context = switch_core_strdup(module_pool, val);
|
2007-12-22 01:00:10 +00:00
|
|
|
} else if (!strcasecmp(var, "auto-login") && !switch_strlen_zero(val)) {
|
2006-05-02 16:43:13 +00:00
|
|
|
if (switch_true(val)) {
|
|
|
|
switch_set_flag(profile, TFLAG_AUTO);
|
|
|
|
}
|
2007-12-12 23:51:26 +00:00
|
|
|
} else if (!strcasecmp(var, "vad") && val) {
|
2006-05-02 16:43:13 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
SWITCH_STANDARD_API(dl_debug)
|
2007-04-07 15:55:07 +00:00
|
|
|
{
|
|
|
|
int on, cur;
|
|
|
|
|
|
|
|
if (session) {
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
if (cmd) {
|
|
|
|
on = switch_true(cmd);
|
2007-04-07 15:55:07 +00:00
|
|
|
cur = ldl_global_debug(on);
|
|
|
|
} else {
|
|
|
|
cur = ldl_global_debug(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
stream->write_function(stream, "DEBUG IS NOW %s\n", cur ? "ON" : "OFF");
|
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
SWITCH_STANDARD_API(dl_pres)
|
2007-04-06 16:20:07 +00:00
|
|
|
{
|
|
|
|
mdl_profile_t *profile;
|
|
|
|
|
|
|
|
if (session) {
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
if (!cmd) {
|
2007-06-20 07:15:53 +00:00
|
|
|
stream->write_function(stream, "USAGE: %s\n", PRES_SYNTAX);
|
2007-04-06 16:20:07 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
if ((profile = switch_core_hash_find(globals.profile_hash, cmd))) {
|
2007-04-06 16:20:07 +00:00
|
|
|
if (profile->user_flags & LDL_FLAG_COMPONENT) {
|
|
|
|
sign_on(profile);
|
|
|
|
stream->write_function(stream, "OK\n");
|
|
|
|
} else {
|
2007-05-12 21:36:15 +00:00
|
|
|
stream->write_function(stream, "NO PROFILE %s NOT A COMPONENT\n", cmd);
|
2007-04-06 16:20:07 +00:00
|
|
|
}
|
|
|
|
} else {
|
2007-05-12 21:36:15 +00:00
|
|
|
stream->write_function(stream, "NO SUCH PROFILE %s\n", cmd);
|
2007-04-06 16:20:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
SWITCH_STANDARD_API(dl_logout)
|
2006-05-02 16:43:13 +00:00
|
|
|
{
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile;
|
2006-06-07 14:53:13 +00:00
|
|
|
|
2006-07-26 20:12:49 +00:00
|
|
|
if (session) {
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
if (!cmd) {
|
2007-06-20 07:15:53 +00:00
|
|
|
stream->write_function(stream, "USAGE: %s\n", LOGOUT_SYNTAX);
|
2006-06-07 14:53:13 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
if ((profile = switch_core_hash_find(globals.profile_hash, cmd))) {
|
2006-05-02 16:43:13 +00:00
|
|
|
ldl_handle_stop(profile->handle);
|
2006-05-10 15:47:54 +00:00
|
|
|
stream->write_function(stream, "OK\n");
|
2006-05-02 16:43:13 +00:00
|
|
|
} else {
|
2007-05-12 21:36:15 +00:00
|
|
|
stream->write_function(stream, "NO SUCH PROFILE %s\n", cmd);
|
2006-05-02 16:43:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
SWITCH_STANDARD_API(dl_login)
|
2006-05-02 16:43:13 +00:00
|
|
|
{
|
2007-03-29 22:31:56 +00:00
|
|
|
char *argv[10] = { 0 };
|
2006-05-02 16:43:13 +00:00
|
|
|
int argc = 0;
|
|
|
|
char *var, *val, *myarg;
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile = NULL;
|
2006-05-02 16:43:13 +00:00
|
|
|
int x;
|
|
|
|
|
2006-07-26 20:12:49 +00:00
|
|
|
if (session) {
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
if (switch_strlen_zero(cmd)) {
|
2007-06-20 07:15:53 +00:00
|
|
|
stream->write_function(stream, "USAGE: %s\n", LOGIN_SYNTAX);
|
2007-03-29 22:31:56 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
2007-01-04 22:08:41 +00:00
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
myarg = strdup(cmd);
|
2006-05-02 16:43:13 +00:00
|
|
|
|
|
|
|
argc = switch_separate_string(myarg, ';', argv, (sizeof(argv) / sizeof(argv[0])));
|
|
|
|
|
2007-05-12 21:36:15 +00:00
|
|
|
if (switch_strlen_zero(cmd) || argc != 1) {
|
2007-06-20 07:15:53 +00:00
|
|
|
stream->write_function(stream, "USAGE: %s\n", LOGIN_SYNTAX);
|
2006-10-08 07:11:42 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-12-12 23:51:26 +00:00
|
|
|
if (argv[0] && !strncasecmp(argv[0], "profile=", 8)) {
|
2006-05-02 16:43:13 +00:00
|
|
|
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)) {
|
2007-11-23 18:50:54 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Profile already exists.\n");
|
2006-05-10 15:47:54 +00:00
|
|
|
stream->write_function(stream, "Profile already exists\n");
|
2006-05-02 16:43:13 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
profile = switch_core_alloc(module_pool, sizeof(*profile));
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
for (x = 0; x < argc; x++) {
|
2006-05-02 16:43:13 +00:00
|
|
|
var = argv[x];
|
2007-12-12 23:51:26 +00:00
|
|
|
if (var && (val = strchr(var, '='))) {
|
2006-05-02 16:43:13 +00:00
|
|
|
*val++ = '\0';
|
|
|
|
set_profile_val(profile, var, val);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-20 06:17:00 +00:00
|
|
|
|
2006-05-02 16:43:13 +00:00
|
|
|
if (profile && init_profile(profile, 1) == SWITCH_STATUS_SUCCESS) {
|
2006-05-10 15:47:54 +00:00
|
|
|
stream->write_function(stream, "OK\n");
|
2006-05-02 16:43:13 +00:00
|
|
|
} else {
|
2006-05-10 15:47:54 +00:00
|
|
|
stream->write_function(stream, "FAIL\n");
|
2006-05-02 16:43:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-04-29 23:43:28 +00:00
|
|
|
static switch_status_t load_config(void)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
|
|
|
char *cf = "dingaling.conf";
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile = NULL;
|
2006-05-10 03:23:05 +00:00
|
|
|
switch_xml_t cfg, xml, settings, param, xmlint;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
memset(&globals, 0, sizeof(globals));
|
|
|
|
globals.running = 1;
|
2006-05-02 16:43:13 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_find_local_ip(globals.guess_ip, sizeof(globals.guess_ip), AF_INET);
|
|
|
|
|
|
|
|
switch_core_hash_init(&globals.profile_hash, module_pool);
|
2006-05-10 03:23:05 +00:00
|
|
|
|
2006-05-10 15:47:54 +00:00
|
|
|
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
2006-05-10 03:23:05 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
|
2006-03-31 19:38:09 +00:00
|
|
|
return SWITCH_STATUS_TERM;
|
|
|
|
}
|
|
|
|
|
2006-05-10 03:23:05 +00:00
|
|
|
if ((settings = switch_xml_child(cfg, "settings"))) {
|
|
|
|
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
|
2006-05-17 00:58:21 +00:00
|
|
|
char *var = (char *) switch_xml_attr_soft(param, "name");
|
|
|
|
char *val = (char *) switch_xml_attr_soft(param, "value");
|
2006-05-10 03:23:05 +00:00
|
|
|
|
2006-05-02 16:43:13 +00:00
|
|
|
if (!strcasecmp(var, "debug")) {
|
2006-03-31 19:38:09 +00:00
|
|
|
globals.debug = atoi(val);
|
2006-05-16 17:08:21 +00:00
|
|
|
} else if (!strcasecmp(var, "codec-prefs")) {
|
2006-03-31 19:38:09 +00:00
|
|
|
set_global_codec_string(val);
|
2007-03-30 00:13:31 +00:00
|
|
|
globals.codec_order_last = switch_separate_string(globals.codec_string, ',', globals.codec_order, SWITCH_MAX_CODECS);
|
2006-05-16 17:08:21 +00:00
|
|
|
} else if (!strcasecmp(var, "codec-rates")) {
|
2006-03-31 19:38:09 +00:00
|
|
|
set_global_codec_rates_string(val);
|
2007-03-30 00:13:31 +00:00
|
|
|
globals.codec_rates_last = switch_separate_string(globals.codec_rates_string, ',', globals.codec_rates, SWITCH_MAX_CODECS);
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2006-05-10 03:23:05 +00:00
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-20 06:17:00 +00:00
|
|
|
if (!(xmlint = switch_xml_child(cfg, "profile"))) {
|
|
|
|
if ((xmlint = switch_xml_child(cfg, "interface"))) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "!!!!!!! DEPRICATION WARNING 'interface' is now 'profile' !!!!!!!\n");
|
2006-10-20 06:17:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (; xmlint; xmlint = xmlint->next) {
|
|
|
|
char *type = (char *) switch_xml_attr_soft(xmlint, "type");
|
2006-05-10 03:23:05 +00:00
|
|
|
for (param = switch_xml_child(xmlint, "param"); param; param = param->next) {
|
2006-05-17 00:58:21 +00:00
|
|
|
char *var = (char *) switch_xml_attr_soft(param, "name");
|
|
|
|
char *val = (char *) switch_xml_attr_soft(param, "value");
|
2006-05-02 16:43:13 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
if (!globals.init) {
|
|
|
|
ldl_global_init(globals.debug);
|
2006-04-14 02:05:29 +00:00
|
|
|
ldl_global_set_logger(dl_logger);
|
2006-03-31 19:38:09 +00:00
|
|
|
globals.init = 1;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (!profile) {
|
2006-03-31 19:38:09 +00:00
|
|
|
profile = switch_core_alloc(module_pool, sizeof(*profile));
|
|
|
|
}
|
2007-12-12 23:51:26 +00:00
|
|
|
|
2006-05-02 16:43:13 +00:00
|
|
|
set_profile_val(profile, var, val);
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2006-05-10 03:23:05 +00:00
|
|
|
|
2006-10-20 06:17:00 +00:00
|
|
|
|
2007-12-12 23:51:26 +00:00
|
|
|
if (profile && type && !strcasecmp(type, "component")) {
|
2006-10-20 06:17:00 +00:00
|
|
|
char dbname[256];
|
|
|
|
switch_core_db_t *db;
|
|
|
|
|
|
|
|
if (!profile->login && profile->name) {
|
|
|
|
profile->login = switch_core_strdup(module_pool, profile->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_set_flag(profile, TFLAG_AUTO);
|
|
|
|
profile->message = "";
|
|
|
|
profile->user_flags |= LDL_FLAG_COMPONENT;
|
|
|
|
switch_mutex_init(&profile->mutex, SWITCH_MUTEX_NESTED, module_pool);
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(dbname, sizeof(dbname), "dingaling_%s", profile->name);
|
2006-10-20 06:17:00 +00:00
|
|
|
profile->dbname = switch_core_strdup(module_pool, dbname);
|
|
|
|
|
2007-04-04 17:32:56 +00:00
|
|
|
|
|
|
|
#ifdef SWITCH_HAVE_ODBC
|
|
|
|
if (profile->odbc_dsn) {
|
|
|
|
if (!(profile->master_odbc = switch_odbc_handle_new(profile->odbc_dsn, profile->odbc_user, profile->odbc_pass))) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n");
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
if (switch_odbc_handle_connect(profile->master_odbc) != SWITCH_ODBC_SUCCESS) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected ODBC DSN: %s\n", profile->odbc_dsn);
|
|
|
|
switch_odbc_handle_exec(profile->master_odbc, sub_sql, NULL);
|
|
|
|
//mdl_execute_sql(profile, sub_sql, NULL);
|
2006-10-20 06:17:00 +00:00
|
|
|
} else {
|
2007-04-04 17:32:56 +00:00
|
|
|
#endif
|
|
|
|
if ((db = switch_core_db_open_file(profile->dbname))) {
|
2007-10-18 16:17:42 +00:00
|
|
|
switch_core_db_test_reactive(db, "select * from jabber_subscriptions", NULL, sub_sql);
|
2007-04-04 17:32:56 +00:00
|
|
|
} else {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
switch_core_db_close(db);
|
|
|
|
#ifdef SWITCH_HAVE_ODBC
|
2006-10-20 06:17:00 +00:00
|
|
|
}
|
2007-04-04 17:32:56 +00:00
|
|
|
#endif
|
2006-10-20 06:17:00 +00:00
|
|
|
}
|
|
|
|
|
2006-05-10 03:23:05 +00:00
|
|
|
if (profile) {
|
|
|
|
init_profile(profile, switch_test_flag(profile, TFLAG_AUTO) ? 1 : 0);
|
|
|
|
profile = NULL;
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (profile) {
|
2006-05-02 16:43:13 +00:00
|
|
|
init_profile(profile, switch_test_flag(profile, TFLAG_AUTO) ? 1 : 0);
|
2006-03-31 19:38:09 +00:00
|
|
|
profile = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!globals.dialplan) {
|
|
|
|
set_global_dialplan("default");
|
|
|
|
}
|
|
|
|
|
2006-05-02 16:43:13 +00:00
|
|
|
if (!globals.init) {
|
|
|
|
ldl_global_init(globals.debug);
|
|
|
|
ldl_global_set_logger(dl_logger);
|
|
|
|
globals.init = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-05-10 03:23:05 +00:00
|
|
|
switch_xml_free(xml);
|
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-04 22:22:55 +00:00
|
|
|
static void do_vcard(ldl_handle_t *handle, char *to, char *from, char *id)
|
2006-10-22 04:37:19 +00:00
|
|
|
{
|
|
|
|
char *params = NULL, *real_to, *to_user, *xmlstr = NULL, *to_host = NULL;
|
2006-10-22 15:46:23 +00:00
|
|
|
switch_xml_t domain, xml = NULL, user, vcard;
|
2007-04-04 22:22:55 +00:00
|
|
|
int sent = 0;
|
2006-10-22 04:37:19 +00:00
|
|
|
|
|
|
|
if (!strncasecmp(to, "user+", 5)) {
|
|
|
|
real_to = to + 5;
|
|
|
|
} else {
|
|
|
|
real_to = to;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ((to_user = strdup(real_to))) {
|
|
|
|
if ((to_host = strchr(to_user, '@'))) {
|
|
|
|
*to_host++ = '\0';
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
|
|
|
|
goto end;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-22 04:37:19 +00:00
|
|
|
if (!to_host) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Missing Host!\n");
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (!(params = switch_mprintf("to=%s@%s&from=%s&object=vcard", to_user, to_host, from))) {
|
2006-10-22 04:37:19 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-22 04:37:19 +00:00
|
|
|
if (switch_xml_locate("directory", "domain", "name", to_host, &xml, &domain, params) != SWITCH_STATUS_SUCCESS) {
|
2007-04-04 22:22:55 +00:00
|
|
|
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "can't find domain for [%s@%s]\n", to_user, to_host);
|
2006-10-22 04:37:19 +00:00
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(user = switch_xml_find_child(domain, "user", "id", to_user))) {
|
2007-04-04 22:22:55 +00:00
|
|
|
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", to_user, to_host);
|
2006-10-22 04:37:19 +00:00
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(vcard = switch_xml_child(user, "vcard"))) {
|
2007-04-04 22:22:55 +00:00
|
|
|
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find <vcard> tag for user [%s@%s]\n", to_user, to_host);
|
2006-10-22 04:37:19 +00:00
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_xml_set_attr(vcard, "xmlns", "vcard-tmp");
|
|
|
|
|
2007-11-30 23:45:27 +00:00
|
|
|
if ((xmlstr = switch_xml_toxml(vcard, SWITCH_FALSE))) {
|
2006-10-22 04:37:19 +00:00
|
|
|
ldl_handle_send_vcard(handle, to, from, id, xmlstr);
|
2007-04-04 22:22:55 +00:00
|
|
|
sent = 1;
|
2006-10-22 04:37:19 +00:00
|
|
|
} else {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
|
|
|
|
}
|
|
|
|
|
2007-04-06 16:20:07 +00:00
|
|
|
end:
|
2007-04-04 22:22:55 +00:00
|
|
|
|
|
|
|
if (!sent) {
|
|
|
|
ldl_handle_send_vcard(handle, to, from, id, NULL);
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (xml)
|
|
|
|
switch_xml_free(xml);
|
2006-10-22 04:37:19 +00:00
|
|
|
switch_safe_free(to_user);
|
|
|
|
switch_safe_free(params);
|
|
|
|
switch_safe_free(xmlstr);
|
|
|
|
}
|
|
|
|
|
2007-03-30 00:15:25 +00:00
|
|
|
static ldl_status handle_signalling(ldl_handle_t * handle, ldl_session_t * dlsession, ldl_signal_t dl_signal, char *to, char *from, char *subject,
|
|
|
|
char *msg)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
2007-04-04 17:32:56 +00:00
|
|
|
mdl_profile_t *profile = NULL;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_core_session_t *session = NULL;
|
|
|
|
switch_channel_t *channel = NULL;
|
2007-03-29 22:31:56 +00:00
|
|
|
struct private_object *tech_pvt = NULL;
|
2006-05-01 18:55:04 +00:00
|
|
|
switch_event_t *event;
|
2006-09-22 15:22:31 +00:00
|
|
|
ldl_status status = LDL_STATUS_SUCCESS;
|
2006-10-18 22:57:35 +00:00
|
|
|
char *sql;
|
|
|
|
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(handle != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
if (!(profile = ldl_handle_get_private(handle))) {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR NO PROFILE!\n");
|
2006-09-22 15:22:31 +00:00
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
2006-05-01 18:55:04 +00:00
|
|
|
if (!dlsession) {
|
2006-10-20 22:26:06 +00:00
|
|
|
if (profile->user_flags & LDL_FLAG_COMPONENT) {
|
2007-03-29 22:31:56 +00:00
|
|
|
switch (dl_signal) {
|
2006-10-22 04:37:19 +00:00
|
|
|
case LDL_SIGNAL_VCARD:
|
|
|
|
do_vcard(handle, to, from, subject);
|
|
|
|
break;
|
2006-10-20 22:26:06 +00:00
|
|
|
case LDL_SIGNAL_UNSUBSCRIBE:
|
2006-10-18 22:57:35 +00:00
|
|
|
|
2007-04-04 17:32:56 +00:00
|
|
|
if ((sql = switch_mprintf("delete from jabber_subscriptions where sub_from='%q' and sub_to='%q';", from, to))) {
|
|
|
|
mdl_execute_sql(profile, sql, profile->mutex);
|
2006-10-18 22:57:35 +00:00
|
|
|
switch_core_db_free(sql);
|
|
|
|
}
|
|
|
|
|
2006-10-20 22:26:06 +00:00
|
|
|
break;
|
2006-10-18 22:57:35 +00:00
|
|
|
|
2006-10-20 22:26:06 +00:00
|
|
|
case LDL_SIGNAL_SUBSCRIBE:
|
2007-03-30 16:41:12 +00:00
|
|
|
if (profile->user_flags & LDL_FLAG_COMPONENT && ldl_jid_domcmp(from, to)) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Attempt to add presence from/to our own domain [%s][%s]\n", from, to);
|
|
|
|
} else {
|
2007-04-04 17:32:56 +00:00
|
|
|
switch_mutex_lock(profile->mutex);
|
|
|
|
if ((sql = switch_mprintf("delete from jabber_subscriptions where sub_from='%q' and sub_to='%q'", from, to))) {
|
|
|
|
mdl_execute_sql(profile, sql, NULL);
|
2007-03-30 16:41:12 +00:00
|
|
|
switch_core_db_free(sql);
|
|
|
|
}
|
2007-04-04 17:32:56 +00:00
|
|
|
if ((sql = switch_mprintf("insert into jabber_subscriptions values('%q','%q','%q','%q');\n",
|
|
|
|
switch_str_nil(from),
|
|
|
|
switch_str_nil(to),
|
|
|
|
switch_str_nil(msg),
|
|
|
|
switch_str_nil(subject)))) {
|
|
|
|
mdl_execute_sql(profile, sql, NULL);
|
|
|
|
switch_core_db_free(sql);
|
|
|
|
}
|
|
|
|
switch_mutex_unlock(profile->mutex);
|
2007-03-30 16:41:12 +00:00
|
|
|
if (is_special(to)) {
|
2007-04-04 22:22:55 +00:00
|
|
|
ldl_handle_send_presence(profile->handle, to, from, NULL, NULL, "Click To Call", profile->avatar);
|
2007-04-07 21:13:54 +00:00
|
|
|
} else {
|
|
|
|
ldl_handle_send_presence(profile->handle, to, from, NULL, NULL, "Authenticated.\nCome to ClueCon!\nhttp://www.cluecon.com", profile->avatar);
|
2007-03-30 16:41:12 +00:00
|
|
|
}
|
2006-11-16 15:50:17 +00:00
|
|
|
#if 0
|
2007-03-30 16:41:12 +00:00
|
|
|
if (is_special(to)) {
|
|
|
|
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", to);
|
|
|
|
//switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Click To Call");
|
|
|
|
switch_event_fire(&event);
|
|
|
|
}
|
2006-10-22 04:37:19 +00:00
|
|
|
}
|
2006-11-16 15:50:17 +00:00
|
|
|
#endif
|
2007-03-30 16:41:12 +00:00
|
|
|
}
|
2006-10-20 22:26:06 +00:00
|
|
|
break;
|
|
|
|
case LDL_SIGNAL_ROSTER:
|
|
|
|
if (switch_event_create(&event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
|
|
|
|
switch_event_fire(&event);
|
|
|
|
}
|
|
|
|
break;
|
2006-12-12 17:44:59 +00:00
|
|
|
case LDL_SIGNAL_PRESENCE_PROBE:
|
|
|
|
if (is_special(to)) {
|
2007-04-04 22:22:55 +00:00
|
|
|
ldl_handle_send_presence(profile->handle, to, from, NULL, NULL, "Click To Call", profile->avatar);
|
2007-03-29 22:31:56 +00:00
|
|
|
} else {
|
2006-12-16 03:00:56 +00:00
|
|
|
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to);
|
2006-12-16 03:00:56 +00:00
|
|
|
switch_event_fire(&event);
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
|
|
|
break;
|
2006-10-20 22:26:06 +00:00
|
|
|
case LDL_SIGNAL_PRESENCE_IN:
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-04-04 17:32:56 +00:00
|
|
|
if ((sql = switch_mprintf("update jabber_subscriptions set show_pres='%q', status='%q' where sub_from='%q'",
|
|
|
|
switch_str_nil(msg), switch_str_nil(subject), switch_str_nil(from)))) {
|
|
|
|
mdl_execute_sql(profile, sql, profile->mutex);
|
2006-10-20 22:26:06 +00:00
|
|
|
switch_core_db_free(sql);
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-10-20 22:26:06 +00:00
|
|
|
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
|
2006-10-20 22:26:06 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", msg);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", subject);
|
|
|
|
switch_event_fire(&event);
|
|
|
|
}
|
2006-10-18 22:57:35 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-16 15:50:17 +00:00
|
|
|
if (is_special(to)) {
|
2007-04-04 22:22:55 +00:00
|
|
|
ldl_handle_send_presence(profile->handle, to, from, NULL, NULL, "Click To Call", profile->avatar);
|
2006-11-16 15:50:17 +00:00
|
|
|
}
|
|
|
|
#if 0
|
2006-10-24 18:23:23 +00:00
|
|
|
if (is_special(to)) {
|
2006-10-22 04:37:19 +00:00
|
|
|
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", to);
|
2006-12-12 17:44:59 +00:00
|
|
|
//switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "unknown");
|
2006-10-22 04:37:19 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Click To Call");
|
|
|
|
switch_event_fire(&event);
|
|
|
|
}
|
|
|
|
}
|
2006-11-16 15:50:17 +00:00
|
|
|
#endif
|
2006-12-19 17:29:33 +00:00
|
|
|
break;
|
2006-12-12 17:44:59 +00:00
|
|
|
|
2006-10-20 22:26:06 +00:00
|
|
|
case LDL_SIGNAL_PRESENCE_OUT:
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-04-04 17:32:56 +00:00
|
|
|
if ((sql = switch_mprintf("update jabber_subscriptions set show_pres='%q', status='%q' where sub_from='%q'",
|
|
|
|
switch_str_nil(msg), switch_str_nil(subject), switch_str_nil(from)))) {
|
|
|
|
mdl_execute_sql(profile, sql, profile->mutex);
|
2006-10-20 22:26:06 +00:00
|
|
|
switch_core_db_free(sql);
|
|
|
|
}
|
|
|
|
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
|
|
|
|
switch_event_fire(&event);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2006-10-20 06:17:00 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (dl_signal) {
|
|
|
|
case LDL_SIGNAL_MSG:{
|
2007-04-06 16:20:07 +00:00
|
|
|
switch_chat_interface_t *ci;
|
|
|
|
char *proto = MDL_CHAT_PROTO;
|
|
|
|
char *pproto = NULL, *ffrom = NULL;
|
|
|
|
char *hint;
|
2007-04-07 21:13:54 +00:00
|
|
|
#ifdef AUTO_REPLY
|
2007-04-06 16:20:07 +00:00
|
|
|
if (profile->auto_reply) {
|
|
|
|
ldl_handle_send_msg(handle,
|
|
|
|
(profile->user_flags & LDL_FLAG_COMPONENT) ? to : ldl_handle_get_login(profile->handle), from, "",
|
|
|
|
profile->auto_reply);
|
|
|
|
}
|
2007-04-07 21:13:54 +00:00
|
|
|
#endif
|
2006-10-23 17:34:03 +00:00
|
|
|
|
2007-04-06 16:20:07 +00:00
|
|
|
if (strchr(to, '+')) {
|
|
|
|
pproto = strdup(to);
|
|
|
|
if ((to = strchr(pproto, '+'))) {
|
|
|
|
*to++ = '\0';
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2007-04-06 16:20:07 +00:00
|
|
|
proto = pproto;
|
|
|
|
}
|
2006-10-23 17:34:03 +00:00
|
|
|
|
2007-04-06 16:20:07 +00:00
|
|
|
hint = from;
|
2006-10-20 22:11:26 +00:00
|
|
|
|
2007-04-06 16:20:07 +00:00
|
|
|
if (strchr(from, '/') && (ffrom = strdup(from))) {
|
|
|
|
char *p;
|
|
|
|
if ((p = strchr(ffrom, '/'))) {
|
|
|
|
*p = '\0';
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2007-04-06 16:20:07 +00:00
|
|
|
from = ffrom;
|
|
|
|
}
|
2006-10-19 07:13:34 +00:00
|
|
|
|
2007-04-06 16:20:07 +00:00
|
|
|
if ((ci = switch_loadable_module_get_chat_interface(proto))) {
|
|
|
|
ci->chat_send(MDL_CHAT_PROTO, from, to, subject, msg, hint);
|
|
|
|
} else {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Chat Interface [%s]!\n", proto);
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
2007-04-06 16:20:07 +00:00
|
|
|
|
|
|
|
switch_safe_free(pproto);
|
|
|
|
switch_safe_free(ffrom);
|
|
|
|
}
|
2006-05-01 18:55:04 +00:00
|
|
|
break;
|
|
|
|
case LDL_SIGNAL_LOGIN_SUCCESS:
|
2007-03-30 00:13:31 +00:00
|
|
|
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, DL_EVENT_LOGIN_SUCCESS) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", ldl_handle_get_login(profile->handle));
|
2006-05-01 18:55:04 +00:00
|
|
|
switch_event_fire(&event);
|
|
|
|
}
|
2006-10-22 04:37:19 +00:00
|
|
|
if (profile->user_flags & LDL_FLAG_COMPONENT) {
|
|
|
|
sign_on(profile);
|
|
|
|
}
|
|
|
|
|
2006-05-01 18:55:04 +00:00
|
|
|
break;
|
|
|
|
case LDL_SIGNAL_LOGIN_FAILURE:
|
2007-03-30 00:13:31 +00:00
|
|
|
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, DL_EVENT_LOGIN_FAILURE) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", ldl_handle_get_login(profile->handle));
|
2006-05-01 18:55:04 +00:00
|
|
|
switch_event_fire(&event);
|
|
|
|
}
|
|
|
|
break;
|
2006-06-22 21:57:40 +00:00
|
|
|
case LDL_SIGNAL_CONNECTED:
|
|
|
|
if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, DL_EVENT_CONNECTED) == SWITCH_STATUS_SUCCESS) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", ldl_handle_get_login(profile->handle));
|
2006-06-22 21:57:40 +00:00
|
|
|
switch_event_fire(&event);
|
|
|
|
}
|
|
|
|
break;
|
2006-05-01 18:55:04 +00:00
|
|
|
default:
|
|
|
|
break;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-05-01 18:55:04 +00:00
|
|
|
}
|
2006-09-22 15:22:31 +00:00
|
|
|
status = LDL_STATUS_SUCCESS;
|
|
|
|
goto done;
|
2006-05-01 18:55:04 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-05-01 18:55:04 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
if ((session = ldl_session_get_private(dlsession))) {
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "using Existing session for %s\n", ldl_session_get_id(dlsession));
|
2006-03-31 19:38:09 +00:00
|
|
|
|
|
|
|
if (switch_channel_get_state(channel) >= CS_HANGUP) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call %s is already over\n", switch_channel_get_name(channel));
|
2006-09-22 15:22:31 +00:00
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
2007-04-07 02:10:17 +00:00
|
|
|
if (dl_signal != LDL_SIGNAL_INITIATE && !msg) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Session is already dead\n");
|
2006-09-22 15:22:31 +00:00
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2007-10-29 18:10:06 +00:00
|
|
|
if ((session = switch_core_session_request(dingaling_endpoint_interface, NULL)) != 0) {
|
2006-03-31 19:38:09 +00:00
|
|
|
switch_core_session_add_stream(session, NULL);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-04-07 02:10:17 +00:00
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object))) != 0) {
|
2007-04-16 15:39:06 +00:00
|
|
|
char *exten;
|
|
|
|
char *context;
|
|
|
|
char *cid_name;
|
|
|
|
char *cid_num;
|
|
|
|
char *tmp, *t, *them = NULL;
|
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
memset(tech_pvt, 0, sizeof(*tech_pvt));
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
2006-04-21 22:31:08 +00:00
|
|
|
tech_pvt->flags |= globals.flags;
|
|
|
|
tech_pvt->flags |= profile->flags;
|
2006-03-31 19:38:09 +00:00
|
|
|
channel = switch_core_session_get_channel(session);
|
|
|
|
switch_core_session_set_private(session, tech_pvt);
|
|
|
|
tech_pvt->session = session;
|
|
|
|
tech_pvt->codec_index = -1;
|
|
|
|
tech_pvt->profile = profile;
|
2007-12-11 19:15:02 +00:00
|
|
|
if (!(tech_pvt->local_port = switch_rtp_request_port(profile->ip))) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No RTP port available!\n");
|
|
|
|
terminate_session(&session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
|
|
|
}
|
2007-04-27 22:28:25 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
|
2006-05-03 23:45:07 +00:00
|
|
|
tech_pvt->recip = switch_core_session_strdup(session, from);
|
2007-04-16 15:39:06 +00:00
|
|
|
if (!(exten = ldl_session_get_value(dlsession, "dnis"))) {
|
|
|
|
exten = profile->exten;
|
|
|
|
/* if it's _auto_ set the extension to match the username portion of the called address */
|
|
|
|
if (!strcmp(exten, "_auto_")) {
|
|
|
|
if ((t = ldl_session_get_callee(dlsession))) {
|
|
|
|
if ((them = strdup(t))) {
|
|
|
|
char *a, *b, *p;
|
|
|
|
if ((p = strchr(them, '/'))) {
|
|
|
|
*p = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((a = strchr(them, '+')) && (b = strrchr(them, '+')) && a != b) {
|
|
|
|
*b++ = '\0';
|
|
|
|
switch_channel_set_variable(channel, "dl_user", them);
|
|
|
|
switch_channel_set_variable(channel, "dl_host", b);
|
|
|
|
}
|
|
|
|
exten = them;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(context = ldl_session_get_value(dlsession, "context"))) {
|
|
|
|
context = profile->context;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(cid_name = ldl_session_get_value(dlsession, "caller_id_name"))) {
|
|
|
|
cid_name = tech_pvt->recip;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(cid_num = ldl_session_get_value(dlsession, "caller_id_number"))) {
|
|
|
|
cid_num = tech_pvt->recip;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* context of "_auto_" means set it to the domain */
|
|
|
|
if (profile->context && !strcmp(profile->context, "_auto_")) {
|
|
|
|
context = profile->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
tech_pvt->them = switch_core_session_strdup(session, ldl_session_get_callee(dlsession));
|
|
|
|
tech_pvt->us = switch_core_session_strdup(session, ldl_session_get_caller(dlsession));
|
|
|
|
|
|
|
|
if ((tmp = strdup(tech_pvt->us))) {
|
|
|
|
char *p, *q;
|
|
|
|
|
|
|
|
if ((p = strchr(tmp, '@'))) {
|
|
|
|
*p++ = '\0';
|
|
|
|
if ((q = strchr(p, '/'))) {
|
|
|
|
*q = '\0';
|
|
|
|
}
|
|
|
|
switch_channel_set_variable(channel, "dl_from_user", tmp);
|
|
|
|
switch_channel_set_variable(channel, "dl_from_host", p);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_safe_free(tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!tech_pvt->caller_profile) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
|
|
|
|
"Creating an identity for %s %s <%s> %s\n", ldl_session_get_id(dlsession), cid_name, cid_num, exten);
|
|
|
|
|
|
|
|
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
|
|
|
|
ldl_handle_get_login(profile->handle),
|
|
|
|
profile->dialplan,
|
|
|
|
cid_name,
|
|
|
|
cid_num,
|
|
|
|
ldl_session_get_ip(dlsession),
|
2007-08-28 22:44:02 +00:00
|
|
|
ldl_session_get_value(dlsession, "ani"),
|
|
|
|
ldl_session_get_value(dlsession, "aniii"),
|
|
|
|
ldl_session_get_value(dlsession, "rdnis"),
|
|
|
|
modname,
|
|
|
|
context,
|
2007-04-16 15:39:06 +00:00
|
|
|
exten)) != 0) {
|
|
|
|
char name[128];
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(name, sizeof(name), "DingaLing/%s", tech_pvt->caller_profile->destination_number);
|
2007-04-16 15:39:06 +00:00
|
|
|
switch_channel_set_name(channel, name);
|
|
|
|
switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_safe_free(them);
|
|
|
|
|
2006-08-18 21:02:40 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_TRANSPORT_ACCEPT);
|
2006-03-31 19:38:09 +00:00
|
|
|
} else {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Hey where is my memory pool?\n");
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(&session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-09-22 15:22:31 +00:00
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Creating a session for %s\n", ldl_session_get_id(dlsession));
|
2006-03-31 19:38:09 +00:00
|
|
|
ldl_session_set_private(dlsession, session);
|
|
|
|
tech_pvt->dlsession = dlsession;
|
2006-11-16 15:50:17 +00:00
|
|
|
switch_channel_set_name(channel, "DingaLing/new");
|
2006-10-10 00:11:41 +00:00
|
|
|
switch_channel_set_state(channel, CS_INIT);
|
2007-05-11 00:27:55 +00:00
|
|
|
if (switch_core_session_thread_launch(session) != SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error spawning thread\n");
|
|
|
|
terminate_session(&session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
|
|
|
}
|
2006-09-22 15:22:31 +00:00
|
|
|
} else {
|
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2006-09-22 15:22:31 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2006-05-03 23:59:54 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
switch (dl_signal) {
|
2006-03-31 19:38:09 +00:00
|
|
|
case LDL_SIGNAL_MSG:
|
2007-03-29 22:31:56 +00:00
|
|
|
if (msg) {
|
2006-03-31 19:38:09 +00:00
|
|
|
if (*msg == '+') {
|
2007-12-22 00:32:20 +00:00
|
|
|
char *p = msg + 1;
|
|
|
|
switch_dtmf_t dtmf = { 0, SWITCH_DEFAULT_DTMF_DURATION };
|
|
|
|
while (p && *p) {
|
|
|
|
dtmf.digit = *p;
|
|
|
|
switch_channel_queue_dtmf(channel, &dtmf);
|
|
|
|
p++;
|
|
|
|
}
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_DTMF);
|
2006-08-28 23:05:26 +00:00
|
|
|
if (switch_rtp_ready(tech_pvt->rtp_session)) {
|
2006-08-18 01:28:50 +00:00
|
|
|
switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_BREAK);
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2006-10-20 22:11:26 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "SESSION MSG [%s]\n", msg);
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
2006-10-12 00:59:09 +00:00
|
|
|
if (switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
|
2006-10-23 17:34:03 +00:00
|
|
|
char *hint = NULL, *p, *freeme = NULL;
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
hint = from;
|
2006-10-20 22:11:26 +00:00
|
|
|
if (strchr(from, '/')) {
|
|
|
|
freeme = strdup(from);
|
|
|
|
p = strchr(freeme, '/');
|
|
|
|
*p = '\0';
|
2007-03-29 22:31:56 +00:00
|
|
|
from = freeme;
|
2006-10-20 22:11:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_PROTO);
|
2006-11-15 20:21:29 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", ldl_handle_get_login(profile->handle));
|
2006-10-23 17:34:03 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "hint", "%s", hint);
|
2006-10-15 04:44:33 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
|
2006-10-20 22:11:26 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", to);
|
2006-10-15 04:44:33 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "subject", "%s", subject);
|
2006-10-12 00:59:09 +00:00
|
|
|
if (msg) {
|
2007-02-14 03:45:10 +00:00
|
|
|
switch_event_add_body(event, "%s", msg);
|
2006-10-12 00:59:09 +00:00
|
|
|
}
|
2006-07-12 18:39:19 +00:00
|
|
|
if (switch_core_session_queue_event(tech_pvt->session, &event) != SWITCH_STATUS_SUCCESS) {
|
2006-07-17 14:12:07 +00:00
|
|
|
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
|
2006-07-12 18:39:19 +00:00
|
|
|
switch_event_fire(&event);
|
|
|
|
}
|
2006-07-17 14:12:07 +00:00
|
|
|
|
2006-10-20 22:11:26 +00:00
|
|
|
switch_safe_free(freeme);
|
2006-05-01 18:55:04 +00:00
|
|
|
}
|
|
|
|
break;
|
2006-08-18 21:02:40 +00:00
|
|
|
case LDL_SIGNAL_TRANSPORT_ACCEPT:
|
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_TRANSPORT_ACCEPT);
|
2006-03-31 19:38:09 +00:00
|
|
|
break;
|
|
|
|
case LDL_SIGNAL_INITIATE:
|
2006-12-19 17:29:33 +00:00
|
|
|
if (dl_signal) {
|
2006-03-31 19:38:09 +00:00
|
|
|
ldl_payload_t *payloads;
|
|
|
|
unsigned int len = 0;
|
2006-05-12 22:01:31 +00:00
|
|
|
int match = 0;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-04-15 22:30:25 +00:00
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
|
|
|
|
if (!strcasecmp(msg, "accept")) {
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
|
2006-08-18 16:36:26 +00:00
|
|
|
if (!do_candidates(tech_pvt, 0)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(&session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-09-22 15:22:31 +00:00
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
2006-08-18 16:36:26 +00:00
|
|
|
}
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
|
|
|
}
|
2006-04-15 05:16:24 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
if (tech_pvt->codec_index > -1) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Already decided on a codec\n");
|
2006-03-31 19:38:09 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2006-08-18 16:36:26 +00:00
|
|
|
|
|
|
|
if (!get_codecs(tech_pvt)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(&session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-09-22 15:22:31 +00:00
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
if (ldl_session_get_payloads(dlsession, &payloads, &len) == LDL_STATUS_SUCCESS) {
|
2007-03-29 22:31:56 +00:00
|
|
|
unsigned int x, y;
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%u payloads\n", len);
|
|
|
|
for (x = 0; x < len; x++) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Available Payload %s %u\n", payloads[x].name, payloads[x].id);
|
2007-03-29 22:31:56 +00:00
|
|
|
for (y = 0; y < tech_pvt->num_codecs; y++) {
|
2006-07-10 22:08:02 +00:00
|
|
|
char *name = tech_pvt->codecs[y]->iananame;
|
2006-04-19 21:40:15 +00:00
|
|
|
|
|
|
|
if (!strncasecmp(name, "ilbc", 4)) {
|
|
|
|
name = "ilbc";
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "compare %s %d/%d to %s %d/%d\n",
|
|
|
|
payloads[x].name, payloads[x].id, payloads[x].rate,
|
|
|
|
name, tech_pvt->codecs[y]->ianacode, tech_pvt->codecs[y]->samples_per_second);
|
2006-10-09 02:24:43 +00:00
|
|
|
if (tech_pvt->codecs[y]->ianacode > 95) {
|
2006-04-19 21:40:15 +00:00
|
|
|
match = strcasecmp(name, payloads[x].name) ? 0 : 1;
|
2006-04-19 21:28:28 +00:00
|
|
|
} else {
|
2006-07-10 22:08:02 +00:00
|
|
|
match = (payloads[x].id == tech_pvt->codecs[y]->ianacode) ? 1 : 0;
|
2006-04-19 21:28:28 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-08-18 01:28:50 +00:00
|
|
|
if (match && payloads[x].rate == tech_pvt->codecs[y]->samples_per_second) {
|
2006-03-31 19:38:09 +00:00
|
|
|
tech_pvt->codec_index = y;
|
2007-03-30 00:15:25 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Choosing Payload index %u %s %u\n", y, payloads[x].name,
|
|
|
|
payloads[x].id);
|
2006-07-10 22:08:02 +00:00
|
|
|
tech_pvt->codec_name = tech_pvt->codecs[y]->iananame;
|
|
|
|
tech_pvt->codec_num = tech_pvt->codecs[y]->ianacode;
|
2007-03-29 22:31:56 +00:00
|
|
|
tech_pvt->r_codec_num = (switch_payload_t) (payloads[x].id);
|
2006-08-18 16:36:26 +00:00
|
|
|
tech_pvt->codec_rate = payloads[x].rate;
|
2006-04-15 22:30:25 +00:00
|
|
|
if (!switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
|
2006-08-18 16:36:26 +00:00
|
|
|
if (!do_describe(tech_pvt, 0)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(&session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-09-22 15:22:31 +00:00
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
2006-08-18 16:36:26 +00:00
|
|
|
}
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
2006-09-22 15:22:31 +00:00
|
|
|
status = LDL_STATUS_SUCCESS;
|
|
|
|
goto done;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-05-12 22:01:31 +00:00
|
|
|
if (!match && !switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
|
2006-08-18 16:36:26 +00:00
|
|
|
if (!do_describe(tech_pvt, 0)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(&session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-09-22 15:22:31 +00:00
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
2006-08-18 16:36:26 +00:00
|
|
|
}
|
2006-05-12 22:01:31 +00:00
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-03-31 19:38:09 +00:00
|
|
|
break;
|
|
|
|
case LDL_SIGNAL_CANDIDATES:
|
2006-12-19 17:29:33 +00:00
|
|
|
if (dl_signal) {
|
2006-03-31 19:38:09 +00:00
|
|
|
ldl_candidate_t *candidates;
|
|
|
|
unsigned int len = 0;
|
2006-11-16 15:50:17 +00:00
|
|
|
unsigned int x;
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-11-16 15:50:17 +00:00
|
|
|
if (ldl_session_get_candidates(dlsession, &candidates, &len) != LDL_STATUS_SUCCESS) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Candidate Error!\n");
|
|
|
|
switch_set_flag(tech_pvt, TFLAG_BYE);
|
|
|
|
switch_clear_flag(tech_pvt, TFLAG_IO);
|
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-16 15:50:17 +00:00
|
|
|
if (tech_pvt->remote_ip) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Already picked an IP [%s]\n", tech_pvt->remote_ip);
|
2006-11-16 15:50:17 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
|
2006-11-16 15:50:17 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%u candidates\n", len);
|
2007-03-29 22:31:56 +00:00
|
|
|
for (x = 0; x < len; x++) {
|
2006-11-16 15:50:17 +00:00
|
|
|
uint8_t lanaddr = 0;
|
2006-04-27 21:25:47 +00:00
|
|
|
|
2006-11-16 15:50:17 +00:00
|
|
|
if (profile->lanaddr) {
|
|
|
|
lanaddr = strncasecmp(candidates[x].address, profile->lanaddr, strlen(profile->lanaddr)) ? 0 : 1;
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "candidates %s:%d\n", candidates[x].address, candidates[x].port);
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2007-04-23 19:03:06 +00:00
|
|
|
// 192.0.0.0 - 192.0.127.255 is marked as reserved, should we filter all of them?
|
|
|
|
if (!strcasecmp(candidates[x].protocol, "udp") &&
|
|
|
|
(!strcasecmp(candidates[x].type, "local") || !strcasecmp(candidates[x].type, "stun")) &&
|
|
|
|
((profile->lanaddr &&
|
|
|
|
lanaddr) || (strncasecmp(candidates[x].address, "10.", 3) &&
|
|
|
|
strncasecmp(candidates[x].address, "192.168.", 8) &&
|
|
|
|
strncasecmp(candidates[x].address, "127.", 4) &&
|
|
|
|
strncasecmp(candidates[x].address, "255.", 4) &&
|
|
|
|
strncasecmp(candidates[x].address, "0.", 2) &&
|
|
|
|
strncasecmp(candidates[x].address, "1.", 2) &&
|
|
|
|
strncasecmp(candidates[x].address, "2.", 2) &&
|
|
|
|
strncasecmp(candidates[x].address, "172.16.", 7) &&
|
|
|
|
strncasecmp(candidates[x].address, "172.17.", 7) &&
|
|
|
|
strncasecmp(candidates[x].address, "172.18.", 7) &&
|
|
|
|
strncasecmp(candidates[x].address, "172.19.", 7) &&
|
|
|
|
strncasecmp(candidates[x].address, "172.2", 5) &&
|
|
|
|
strncasecmp(candidates[x].address, "172.30.", 7) &&
|
|
|
|
strncasecmp(candidates[x].address, "172.31.", 7) &&
|
|
|
|
strncasecmp(candidates[x].address, "192.0.2.", 8) &&
|
|
|
|
strncasecmp(candidates[x].address, "169.254.", 8)
|
|
|
|
))) {
|
2006-11-16 15:50:17 +00:00
|
|
|
ldl_payload_t payloads[5];
|
|
|
|
|
|
|
|
memset(payloads, 0, sizeof(payloads));
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Acceptable Candidate %s:%d\n", candidates[x].address, candidates[x].port);
|
2006-11-16 15:50:17 +00:00
|
|
|
|
|
|
|
if (!switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
|
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_TRANSPORT_ACCEPT);
|
|
|
|
ldl_session_accept_candidate(dlsession, &candidates[x]);
|
|
|
|
}
|
|
|
|
|
2007-04-23 19:03:06 +00:00
|
|
|
if (!strcasecmp(subject, "candidates")) {
|
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_TRANSPORT_ACCEPT);
|
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
|
|
|
|
}
|
|
|
|
|
2006-11-16 15:50:17 +00:00
|
|
|
if (lanaddr) {
|
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_LANADDR);
|
|
|
|
}
|
2006-04-27 15:59:58 +00:00
|
|
|
|
2006-11-16 15:50:17 +00:00
|
|
|
if (!get_codecs(tech_pvt)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(&session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-11-16 15:50:17 +00:00
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
|
|
|
}
|
2006-08-18 16:36:26 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-16 15:50:17 +00:00
|
|
|
tech_pvt->remote_ip = switch_core_session_strdup(session, candidates[x].address);
|
|
|
|
ldl_session_set_ip(dlsession, tech_pvt->remote_ip);
|
|
|
|
tech_pvt->remote_port = candidates[x].port;
|
|
|
|
tech_pvt->remote_user = switch_core_session_strdup(session, candidates[x].username);
|
2006-08-18 01:28:50 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-16 15:50:17 +00:00
|
|
|
if (!switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
|
|
|
|
if (!do_candidates(tech_pvt, 0)) {
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(&session, __LINE__, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-11-16 15:50:17 +00:00
|
|
|
status = LDL_STATUS_FALSE;
|
|
|
|
goto done;
|
2006-04-15 22:30:25 +00:00
|
|
|
}
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-11-16 15:50:17 +00:00
|
|
|
status = LDL_STATUS_SUCCESS;
|
|
|
|
goto done;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2007-01-29 22:22:29 +00:00
|
|
|
case LDL_SIGNAL_REJECT:
|
2007-03-29 22:31:56 +00:00
|
|
|
if (channel) {
|
2007-01-29 22:22:29 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "reject %s\n", switch_channel_get_name(channel));
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(&session, __LINE__, SWITCH_CAUSE_CALL_REJECTED);
|
2007-01-29 22:22:29 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "End Call (Rejected)\n");
|
|
|
|
goto done;
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
break;
|
2006-03-31 19:38:09 +00:00
|
|
|
case LDL_SIGNAL_ERROR:
|
|
|
|
case LDL_SIGNAL_TERMINATE:
|
|
|
|
if (channel) {
|
2007-03-09 23:51:52 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hungup %s\n", switch_channel_get_name(channel));
|
2007-03-29 22:31:56 +00:00
|
|
|
terminate_session(&session, __LINE__, SWITCH_CAUSE_NORMAL_CLEARING);
|
2006-09-22 15:22:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "End Call\n");
|
|
|
|
goto done;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
break;
|
2006-05-01 18:55:04 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR\n");
|
|
|
|
break;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
2007-04-06 16:20:07 +00:00
|
|
|
done:
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-09-22 15:22:31 +00:00
|
|
|
return status;
|
2006-03-31 19:38:09 +00:00
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
static ldl_status handle_response(ldl_handle_t * handle, char *id)
|
2006-03-31 19:38:09 +00:00
|
|
|
{
|
|
|
|
return LDL_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-11-27 22:30:48 +00:00
|
|
|
/* For Emacs:
|
|
|
|
* Local Variables:
|
|
|
|
* mode:c
|
2007-02-09 02:36:03 +00:00
|
|
|
* indent-tabs-mode:t
|
2006-11-27 22:30:48 +00:00
|
|
|
* tab-width:4
|
|
|
|
* c-basic-offset:4
|
|
|
|
* End:
|
|
|
|
* For VIM:
|
|
|
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
|
|
|
|
*/
|