2006-01-03 22:13:59 +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>
|
|
|
|
*
|
|
|
|
*
|
2007-01-05 15:50:10 +00:00
|
|
|
* mod_woomera.c -- Woomera Endpoint Module
|
2006-01-03 22:13:59 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
#include <switch.h>
|
|
|
|
|
|
|
|
#define WOOMERA_STRLEN 256
|
2007-12-16 01:50:45 +00:00
|
|
|
#define WOOMERA_ARRAY_LEN 25
|
2006-01-03 22:13:59 +00:00
|
|
|
#define WOOMERA_MIN_PORT 9900
|
|
|
|
#define WOOMERA_MAX_PORT 9999
|
|
|
|
#define WOOMERA_BODYLEN 2048
|
|
|
|
#define WOOMERA_LINE_SEPERATOR "\r\n"
|
|
|
|
#define WOOMERA_RECORD_SEPERATOR "\r\n\r\n"
|
|
|
|
#define WOOMERA_DEBUG_PREFIX "**[DEBUG]** "
|
2006-01-20 15:05:05 +00:00
|
|
|
#define WOOMERA_DEBUG_LINE "--------------------------------------------------------------------------------"
|
2006-01-03 22:13:59 +00:00
|
|
|
#define WOOMERA_HARD_TIMEOUT -10000
|
|
|
|
#define WOOMERA_QLEN 10
|
|
|
|
#define WOOMERA_RECONNECT_TIME 5000000
|
|
|
|
#define MEDIA_ANSWER "ANSWER"
|
|
|
|
// THE ONE ABOVE OR THE 2 BELOW BUT NOT BOTH
|
|
|
|
//#define MEDIA_ANSWER "ANSWER"
|
|
|
|
//#define USE_ANSWER 1
|
|
|
|
|
2007-06-13 17:06:10 +00:00
|
|
|
SWITCH_MODULE_LOAD_FUNCTION(mod_woomera_load);
|
|
|
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_woomera_shutdown);
|
|
|
|
SWITCH_MODULE_RUNTIME_FUNCTION(mod_woomera_runtime);
|
|
|
|
SWITCH_MODULE_DEFINITION(mod_woomera, mod_woomera_load, mod_woomera_shutdown, mod_woomera_runtime);
|
2006-01-03 22:13:59 +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 *woomera_endpoint_interface;
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
#define STRLEN 15
|
|
|
|
#define FRAME_LEN 480
|
|
|
|
//static int WFORMAT = AST_FORMAT_SLINEAR;
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
WFLAG_EXISTS = (1 << 0),
|
|
|
|
WFLAG_EVENT = (1 << 1),
|
|
|
|
WFLAG_CONTENT = (1 << 2),
|
|
|
|
} WFLAGS;
|
|
|
|
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
WCFLAG_NOWAIT = (1 << 0)
|
|
|
|
} WCFLAGS;
|
|
|
|
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
PFLAG_INBOUND = (1 << 0),
|
|
|
|
PFLAG_OUTBOUND = (1 << 1),
|
|
|
|
PFLAG_DYNAMIC = (1 << 2),
|
|
|
|
PFLAG_DISABLED = (1 << 3)
|
|
|
|
} PFLAGS;
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
TFLAG_MEDIA = (1 << 0),
|
|
|
|
TFLAG_INBOUND = (1 << 1),
|
|
|
|
TFLAG_OUTBOUND = (1 << 2),
|
|
|
|
TFLAG_INCOMING = (1 << 3),
|
|
|
|
TFLAG_PARSE_INCOMING = (1 << 4),
|
|
|
|
TFLAG_ACTIVATE = (1 << 5),
|
|
|
|
TFLAG_DTMF = (1 << 6),
|
|
|
|
TFLAG_DESTROY = (1 << 7),
|
|
|
|
TFLAG_ABORT = (1 << 8),
|
|
|
|
TFLAG_SWITCH = (1 << 9),
|
2007-11-19 16:38:31 +00:00
|
|
|
TFLAG_ANSWER = (1 << 10)
|
2006-01-03 22:13:59 +00:00
|
|
|
} TFLAGS;
|
|
|
|
|
|
|
|
struct woomera_message {
|
|
|
|
char callid[WOOMERA_STRLEN];
|
|
|
|
int mval;
|
|
|
|
char command[WOOMERA_STRLEN];
|
|
|
|
char command_args[WOOMERA_STRLEN];
|
|
|
|
char names[WOOMERA_STRLEN][WOOMERA_ARRAY_LEN];
|
|
|
|
char values[WOOMERA_STRLEN][WOOMERA_ARRAY_LEN];
|
|
|
|
char body[WOOMERA_BODYLEN];
|
|
|
|
unsigned int flags;
|
|
|
|
int last;
|
|
|
|
struct woomera_message *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
static struct {
|
2006-02-20 06:13:56 +00:00
|
|
|
switch_port_t next_woomera_port;
|
2006-01-03 22:13:59 +00:00
|
|
|
int debug;
|
|
|
|
int panic;
|
|
|
|
int rtpmode;
|
|
|
|
} globals;
|
|
|
|
|
|
|
|
struct woomera_event_queue {
|
|
|
|
struct woomera_message *head;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct woomera_profile {
|
|
|
|
char *name;
|
|
|
|
switch_socket_t *woomera_socket;
|
2007-03-09 20:44:13 +00:00
|
|
|
switch_mutex_t *iolock;
|
2006-01-03 22:13:59 +00:00
|
|
|
char woomera_host[WOOMERA_STRLEN];
|
2006-02-20 06:13:56 +00:00
|
|
|
switch_port_t woomera_port;
|
2006-01-03 22:13:59 +00:00
|
|
|
char audio_ip[WOOMERA_STRLEN];
|
|
|
|
char dialplan[WOOMERA_STRLEN];
|
|
|
|
unsigned int flags;
|
|
|
|
int thread_running;
|
|
|
|
struct woomera_event_queue event_queue;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct private_object {
|
|
|
|
char *name;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_frame_t frame;
|
|
|
|
switch_codec_t read_codec;
|
|
|
|
switch_codec_t write_codec;
|
|
|
|
switch_core_session_t *session;
|
2007-03-09 20:44:13 +00:00
|
|
|
switch_pollfd_t *read_poll;
|
|
|
|
switch_pollfd_t *write_poll;
|
|
|
|
switch_pollfd_t *command_poll;
|
2007-03-09 23:51:52 +00:00
|
|
|
char databuf[SWITCH_RECOMMENDED_BUFFER_SIZE];
|
2006-01-03 22:13:59 +00:00
|
|
|
switch_mutex_t *iolock;
|
|
|
|
switch_sockaddr_t *udpread;
|
|
|
|
switch_sockaddr_t *udpwrite;
|
|
|
|
switch_socket_t *command_channel;
|
|
|
|
switch_socket_t *udp_socket;
|
|
|
|
unsigned int flags;
|
|
|
|
short fdata[FRAME_LEN];
|
|
|
|
struct woomera_message call_info;
|
|
|
|
struct woomera_profile *profile;
|
|
|
|
char dest[WOOMERA_STRLEN];
|
2006-02-20 06:13:56 +00:00
|
|
|
switch_port_t port;
|
2006-01-03 22:13:59 +00:00
|
|
|
switch_time_t started;
|
|
|
|
int timeout;
|
|
|
|
char dtmfbuf[WOOMERA_STRLEN];
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_caller_profile_t *caller_profile;
|
2006-01-03 22:13:59 +00:00
|
|
|
struct woomera_event_queue event_queue;
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_mutex_t *flag_mutex;
|
2006-01-03 22:13:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct private_object private_object;
|
|
|
|
typedef struct woomera_message woomera_message;
|
|
|
|
typedef struct woomera_profile woomera_profile;
|
|
|
|
typedef struct woomera_event_queue woomera_event_queue;
|
|
|
|
|
|
|
|
static woomera_profile default_profile;
|
|
|
|
|
2007-01-05 15:50:10 +00:00
|
|
|
static switch_status_t woomera_on_init(switch_core_session_t *session);
|
|
|
|
static switch_status_t woomera_on_hangup(switch_core_session_t *session);
|
|
|
|
static switch_status_t woomera_on_ring(switch_core_session_t *session);
|
|
|
|
static switch_status_t woomera_on_loopback(switch_core_session_t *session);
|
|
|
|
static switch_status_t woomera_on_transmit(switch_core_session_t *session);
|
2007-03-29 22:31:56 +00:00
|
|
|
static switch_call_cause_t woomera_outgoing_channel(switch_core_session_t *session,
|
|
|
|
switch_caller_profile_t *outbound_profile,
|
2007-03-30 00:15:25 +00:00
|
|
|
switch_core_session_t **new_session, switch_memory_pool_t **pool);
|
2007-03-30 00:13:31 +00:00
|
|
|
static switch_status_t woomera_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 woomera_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id);
|
2007-01-05 15:50:10 +00:00
|
|
|
static switch_status_t woomera_kill_channel(switch_core_session_t *session, int sig);
|
2006-01-20 15:05:05 +00:00
|
|
|
static void tech_destroy(private_object * tech_pvt);
|
2007-03-30 00:13:31 +00:00
|
|
|
static void woomera_printf(woomera_profile * profile, switch_socket_t * socket, char *fmt, ...);
|
2006-01-20 15:05:05 +00:00
|
|
|
static char *woomera_message_header(woomera_message * wmsg, char *key);
|
|
|
|
static int woomera_enqueue_event(woomera_event_queue * event_queue, woomera_message * wmsg);
|
|
|
|
static int woomera_dequeue_event(woomera_event_queue * event_queue, woomera_message * wmsg);
|
2007-03-30 00:13:31 +00:00
|
|
|
static int woomera_message_parse(switch_socket_t * fd, woomera_message * wmsg, int timeout, woomera_profile * profile, woomera_event_queue * event_queue);
|
|
|
|
static int connect_woomera(switch_socket_t ** new_sock, woomera_profile * profile, int flags);
|
2006-01-20 15:05:05 +00:00
|
|
|
static int woomera_profile_thread_running(woomera_profile * profile, int set, int new);
|
2007-03-30 00:13:31 +00:00
|
|
|
static int woomera_locate_socket(woomera_profile * profile, switch_socket_t ** woomera_socket);
|
2006-01-20 15:05:05 +00:00
|
|
|
static int tech_create_read_socket(private_object * tech_pvt);
|
2007-03-30 00:13:31 +00:00
|
|
|
static void *woomera_channel_thread_run(switch_thread_t * thread, void *obj);
|
2006-01-03 22:13:59 +00:00
|
|
|
static void *woomera_thread_run(void *obj);
|
2006-01-20 15:05:05 +00:00
|
|
|
static int tech_activate(private_object * tech_pvt);
|
2006-01-03 22:13:59 +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.
|
|
|
|
*/
|
2007-01-05 15:50:10 +00:00
|
|
|
static switch_status_t woomera_on_init(switch_core_session_t *session)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel;
|
2006-01-03 22:13:59 +00:00
|
|
|
struct private_object *tech_pvt = NULL;
|
|
|
|
int rate = 8000;
|
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
tech_pvt->frame.data = tech_pvt->databuf;
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
if (switch_core_codec_init
|
2006-10-09 02:24:43 +00:00
|
|
|
(&tech_pvt->read_codec, "L16", NULL, rate, 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
|
2006-01-20 15:05:05 +00:00
|
|
|
switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set read codec\n", switch_channel_get_name(channel));
|
2006-04-22 03:05:25 +00:00
|
|
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-01-03 22:13:59 +00:00
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
if (switch_core_codec_init
|
2006-10-09 02:24:43 +00:00
|
|
|
(&tech_pvt->write_codec, "L16", NULL, rate, 30, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
|
2006-01-20 15:05:05 +00:00
|
|
|
switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set read codec\n", switch_channel_get_name(channel));
|
2006-04-22 03:05:25 +00:00
|
|
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
2006-01-03 22:13:59 +00:00
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
tech_pvt->frame.rate = rate;
|
|
|
|
tech_pvt->frame.codec = &tech_pvt->read_codec;
|
|
|
|
switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
|
|
|
|
switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
|
|
|
|
|
|
|
|
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_ACTIVATE);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
switch_core_session_launch_thread(session, woomera_channel_thread_run, session);
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2007-01-05 15:50:10 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s WOOMERA INIT\n", switch_channel_get_name(channel));
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-01-05 15:50:10 +00:00
|
|
|
static switch_status_t woomera_on_ring(switch_core_session_t *session)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
2006-01-03 22:13:59 +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-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
2007-01-05 15:50:10 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s WOOMERA RING\n", switch_channel_get_name(channel));
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-01-05 15:50:10 +00:00
|
|
|
static switch_status_t woomera_on_execute(switch_core_session_t *session)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
2006-01-03 22:13:59 +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-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2007-01-05 15:50:10 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s WOOMERA EXECUTE\n", switch_channel_get_name(channel));
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-01-05 15:50:10 +00:00
|
|
|
static switch_status_t woomera_on_hangup(switch_core_session_t *session)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
2006-01-03 22:13:59 +00:00
|
|
|
struct private_object *tech_pvt = NULL;
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
2006-02-10 22:26:00 +00:00
|
|
|
switch_core_codec_destroy(&tech_pvt->read_codec);
|
|
|
|
switch_core_codec_destroy(&tech_pvt->write_codec);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
2007-01-05 15:50:10 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s WOOMERA HANGUP\n", switch_channel_get_name(channel));
|
2006-01-03 22:13:59 +00:00
|
|
|
tech_destroy(tech_pvt);
|
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
static void woomera_socket_close(switch_socket_t ** socket)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
if (*socket) {
|
|
|
|
switch_socket_close(*socket);
|
|
|
|
*socket = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
static void udp_socket_close(struct private_object *tech_pvt)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
if (tech_pvt->udp_socket) {
|
2007-03-09 20:44:13 +00:00
|
|
|
switch_socket_shutdown(tech_pvt->udp_socket, SWITCH_SHUTDOWN_READWRITE);
|
2006-01-03 22:13:59 +00:00
|
|
|
woomera_socket_close(&tech_pvt->udp_socket);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-01-05 15:50:10 +00:00
|
|
|
static switch_status_t woomera_kill_channel(switch_core_session_t *session, int sig)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
2006-01-03 22:13:59 +00:00
|
|
|
struct private_object *tech_pvt = NULL;
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
if (!tech_pvt->udp_socket) {
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
switch (sig) {
|
|
|
|
case SWITCH_SIG_KILL:
|
|
|
|
udp_socket_close(tech_pvt);
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s WOOMERA KILL\n", switch_channel_get_name(channel));
|
|
|
|
break;
|
|
|
|
case SWITCH_SIG_BREAK:
|
|
|
|
{
|
|
|
|
const char p = 0;
|
|
|
|
switch_size_t len = sizeof(p);
|
2007-05-17 14:29:49 +00:00
|
|
|
if (tech_pvt->udp_socket && tech_pvt->udpwrite) {
|
|
|
|
switch_socket_sendto(tech_pvt->udp_socket, tech_pvt->udpwrite, 0, &p, &len);
|
|
|
|
}
|
2007-03-29 22:31:56 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-01-05 15:50:10 +00:00
|
|
|
static switch_status_t woomera_on_loopback(switch_core_session_t *session)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
2007-01-05 15:50:10 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "WOOMERA LOOPBACK\n");
|
2006-01-03 22:13:59 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-01-05 15:50:10 +00:00
|
|
|
static switch_status_t woomera_on_transmit(switch_core_session_t *session)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
2007-01-05 15:50:10 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "WOOMERA TRANSMIT\n");
|
2006-01-03 22:13:59 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-01-05 15:50:10 +00:00
|
|
|
static switch_status_t woomera_waitfor_read(switch_core_session_t *session, int ms, int stream_id)
|
2006-01-03 22:13:59 +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-01-03 22:13:59 +00:00
|
|
|
|
2007-03-09 20:44:13 +00:00
|
|
|
return switch_socket_waitfor(tech_pvt->read_poll, ms) ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS;
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
2007-01-05 15:50:10 +00:00
|
|
|
static switch_status_t woomera_waitfor_write(switch_core_session_t *session, int ms, int stream_id)
|
2006-01-03 22:13:59 +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-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
2007-03-29 22:31:56 +00:00
|
|
|
// return switch_socket_waitfor(tech_pvt->write_poll, ms);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
static switch_status_t woomera_read_frame(switch_core_session_t *session, switch_frame_t **frame, int timeout, switch_io_flag_t flags, int stream_id)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
2006-01-03 22:13:59 +00:00
|
|
|
struct private_object *tech_pvt = NULL;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_frame_t *pframe;
|
2006-04-21 22:31:08 +00:00
|
|
|
switch_size_t len;
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
2007-11-19 16:38:31 +00:00
|
|
|
for(;;) {
|
2007-11-19 17:19:32 +00:00
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_ABORT) || !tech_pvt->udp_socket) {
|
2007-11-19 16:38:31 +00:00
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_MEDIA)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch_yield(1000);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
if (!tech_pvt->udp_socket) {
|
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
|
|
|
/*
|
2007-01-05 15:50:10 +00:00
|
|
|
if ((status = woomera_waitfor_read(session, -1)) != SWITCH_STATUS_SUCCESS) {
|
2006-01-20 15:05:05 +00:00
|
|
|
return status;
|
|
|
|
}1<
|
|
|
|
*/
|
2006-01-03 22:13:59 +00:00
|
|
|
pframe = &tech_pvt->frame;
|
2006-01-20 15:05:05 +00:00
|
|
|
*frame = pframe;
|
|
|
|
|
2006-04-21 22:31:08 +00:00
|
|
|
len = sizeof(tech_pvt->databuf);
|
2007-03-30 00:13:31 +00:00
|
|
|
if (switch_socket_recvfrom(tech_pvt->udpread, tech_pvt->udp_socket, 0, tech_pvt->databuf, &len) == SWITCH_STATUS_SUCCESS) {
|
2007-03-29 22:31:56 +00:00
|
|
|
pframe->datalen = (uint32_t) len;
|
2006-01-20 15:05:05 +00:00
|
|
|
pframe->samples = (int) pframe->datalen / 2;
|
2006-03-30 23:02:50 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
2006-03-30 23:02:50 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_FALSE;
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
static switch_status_t woomera_write_frame(switch_core_session_t *session, switch_frame_t *frame, int timeout, switch_io_flag_t flags, int stream_id)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel = NULL;
|
2006-01-03 22:13:59 +00:00
|
|
|
struct private_object *tech_pvt = NULL;
|
2006-04-21 22:31:08 +00:00
|
|
|
switch_size_t len;
|
2006-04-29 06:05:03 +00:00
|
|
|
//switch_frame_t *pframe;
|
2007-03-29 22:31:56 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2007-11-19 16:38:31 +00:00
|
|
|
|
2007-11-19 17:19:32 +00:00
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_ABORT) || !tech_pvt->udp_socket) {
|
2006-01-03 22:13:59 +00:00
|
|
|
return SWITCH_STATUS_GENERR;
|
|
|
|
}
|
2007-11-19 16:38:31 +00:00
|
|
|
|
|
|
|
if (!switch_test_flag(tech_pvt, TFLAG_MEDIA)) {
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2006-03-30 23:02:50 +00:00
|
|
|
//pframe = &tech_pvt->frame;
|
2006-04-21 22:31:08 +00:00
|
|
|
len = frame->datalen;
|
|
|
|
if (switch_socket_sendto(tech_pvt->udp_socket, tech_pvt->udpwrite, 0, frame->data, &len) == SWITCH_STATUS_SUCCESS) {
|
2007-03-29 22:31:56 +00:00
|
|
|
frame->datalen = (uint32_t) len;
|
2006-03-30 23:02:50 +00:00
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-03-30 23:02:50 +00:00
|
|
|
return SWITCH_STATUS_GENERR;
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
2007-06-13 20:40:06 +00:00
|
|
|
static switch_state_handler_table_t woomera_event_handlers = {
|
2007-01-05 15:50:10 +00:00
|
|
|
/*.on_init */ woomera_on_init,
|
|
|
|
/*.on_ring */ woomera_on_ring,
|
|
|
|
/*.on_execute */ woomera_on_execute,
|
|
|
|
/*.on_hangup */ woomera_on_hangup,
|
|
|
|
/*.on_loopback */ woomera_on_loopback,
|
|
|
|
/*.on_transmit */ woomera_on_transmit
|
2006-01-03 22:13:59 +00:00
|
|
|
};
|
|
|
|
|
2007-06-13 20:40:06 +00:00
|
|
|
static switch_io_routines_t woomera_io_routines = {
|
2007-01-05 15:50:10 +00:00
|
|
|
/*.outgoing_channel */ woomera_outgoing_channel,
|
|
|
|
/*.read_frame */ woomera_read_frame,
|
|
|
|
/*.write_frame */ woomera_write_frame,
|
|
|
|
/*.kill_channel */ woomera_kill_channel,
|
|
|
|
/*.waitfor_read */ woomera_waitfor_read,
|
|
|
|
/*.waitfor_write */ woomera_waitfor_write
|
2006-01-03 22:13:59 +00:00
|
|
|
};
|
|
|
|
|
2006-02-20 06:13:56 +00:00
|
|
|
/* Make sure when you have 2 sessions in the same scope that you pass the appropriate one to the routines
|
|
|
|
that allocate memory or you will have 1 channel with memory allocated from another channel's pool!
|
|
|
|
*/
|
2007-03-29 22:31:56 +00:00
|
|
|
static switch_call_cause_t woomera_outgoing_channel(switch_core_session_t *session,
|
|
|
|
switch_caller_profile_t *outbound_profile,
|
2007-03-30 00:15:25 +00:00
|
|
|
switch_core_session_t **new_session, switch_memory_pool_t **pool)
|
2006-02-20 06:13:56 +00:00
|
|
|
{
|
2007-06-20 07:15:53 +00:00
|
|
|
if ((*new_session = switch_core_session_request(woomera_endpoint_interface, pool)) != 0) {
|
2006-02-20 06:13:56 +00:00
|
|
|
struct private_object *tech_pvt;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel;
|
2006-02-20 06:13:56 +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-02-20 06:13:56 +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-02-20 06:13:56 +00:00
|
|
|
tech_pvt->profile = &default_profile;
|
|
|
|
channel = switch_core_session_get_channel(*new_session);
|
|
|
|
switch_core_session_set_private(*new_session, tech_pvt);
|
|
|
|
tech_pvt->session = *new_session;
|
|
|
|
} 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");
|
2006-02-20 06:13:56 +00:00
|
|
|
switch_core_session_destroy(new_session);
|
2007-02-09 20:03:07 +00:00
|
|
|
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
2006-02-20 06:13:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (outbound_profile) {
|
|
|
|
char name[128];
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_caller_profile_t *caller_profile;
|
2006-02-20 06:13:56 +00:00
|
|
|
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(name, sizeof(name), "Woomera/%s-%04x", outbound_profile->destination_number, rand() & 0xffff);
|
2006-02-22 02:50:33 +00:00
|
|
|
switch_channel_set_name(channel, name);
|
|
|
|
|
2006-02-20 06:13:56 +00:00
|
|
|
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-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Doh! no caller profile\n");
|
2006-02-20 06:13:56 +00:00
|
|
|
switch_core_session_destroy(new_session);
|
2007-02-09 20:03:07 +00:00
|
|
|
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
2006-02-20 06:13:56 +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);
|
2006-02-20 06:13:56 +00:00
|
|
|
switch_channel_set_state(channel, CS_INIT);
|
2007-02-09 20:03:07 +00:00
|
|
|
return SWITCH_CAUSE_SUCCESS;
|
2006-02-20 06:13:56 +00:00
|
|
|
}
|
|
|
|
|
2007-02-09 20:03:07 +00:00
|
|
|
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
|
2006-02-20 06:13:56 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
static void tech_destroy(private_object * tech_pvt)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
woomera_message wmsg;
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
if (globals.debug > 1) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, WOOMERA_DEBUG_PREFIX "+++DESTROY\n");
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
woomera_printf(tech_pvt->profile, tech_pvt->command_channel, "hangup %s%s", tech_pvt->call_info.callid, WOOMERA_RECORD_SEPERATOR);
|
|
|
|
if (woomera_message_parse(tech_pvt->command_channel, &wmsg, WOOMERA_HARD_TIMEOUT, tech_pvt->profile, &tech_pvt->event_queue) < 0) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "{%s} Already Disconnected\n", tech_pvt->profile->name);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
woomera_printf(tech_pvt->profile, tech_pvt->command_channel, "bye%s", WOOMERA_RECORD_SEPERATOR);
|
|
|
|
woomera_socket_close(&tech_pvt->command_channel);
|
|
|
|
udp_socket_close(tech_pvt);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
static void woomera_printf(woomera_profile * profile, switch_socket_t * socket, char *fmt, ...)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
char *stuff;
|
|
|
|
size_t res = 0, len = 0;
|
|
|
|
|
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
#ifndef vasprintf
|
2006-01-20 15:05:05 +00:00
|
|
|
stuff = (char *) malloc(10240);
|
2007-12-15 20:50:15 +00:00
|
|
|
switch_assert(stuff);
|
2006-01-03 22:13:59 +00:00
|
|
|
vsnprintf(stuff, 10240, fmt, ap);
|
|
|
|
#else
|
|
|
|
res = vasprintf(&stuff, fmt, ap);
|
2007-12-15 20:50:15 +00:00
|
|
|
switch_assert(stuff);
|
2006-01-03 22:13:59 +00:00
|
|
|
#endif
|
|
|
|
va_end(ap);
|
|
|
|
if (res == -1) {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Out of memory\n");
|
2006-01-03 22:13:59 +00:00
|
|
|
} else {
|
|
|
|
if (profile && globals.debug) {
|
2007-11-23 18:50:54 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Send Message: {%s} [%s/%d]\n%s\n%s\n", profile->name,
|
2007-03-29 22:31:56 +00:00
|
|
|
profile->woomera_host, profile->woomera_port, WOOMERA_DEBUG_LINE, stuff);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
len = strlen(stuff);
|
|
|
|
switch_socket_send(socket, stuff, &len);
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
free(stuff);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
static char *woomera_message_header(woomera_message * wmsg, char *key)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
int x = 0;
|
|
|
|
char *value = NULL;
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
for (x = 0; x < wmsg->last; x++) {
|
2006-01-03 22:13:59 +00:00
|
|
|
if (!strcasecmp(wmsg->names[x], key)) {
|
|
|
|
value = wmsg->values[x];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
static int woomera_enqueue_event(woomera_event_queue * event_queue, woomera_message * wmsg)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
woomera_message *new, *mptr;
|
|
|
|
|
2006-02-20 06:13:56 +00:00
|
|
|
if ((new = malloc(sizeof(woomera_message))) != 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
memcpy(new, wmsg, sizeof(woomera_message));
|
|
|
|
new->next = NULL;
|
|
|
|
|
|
|
|
if (!event_queue->head) {
|
|
|
|
event_queue->head = new;
|
|
|
|
} else {
|
2006-01-20 15:05:05 +00:00
|
|
|
for (mptr = event_queue->head; mptr && mptr->next; mptr = mptr->next);
|
2006-01-03 22:13:59 +00:00
|
|
|
mptr->next = new;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
} else {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Allocation Error!\n");
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
static int woomera_dequeue_event(woomera_event_queue * event_queue, woomera_message * wmsg)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
woomera_message *mptr = NULL;
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
if (event_queue->head) {
|
|
|
|
mptr = event_queue->head;
|
|
|
|
event_queue->head = mptr->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mptr) {
|
|
|
|
memcpy(wmsg, mptr, sizeof(woomera_message));
|
|
|
|
free(mptr);
|
|
|
|
return 1;
|
|
|
|
} else {
|
|
|
|
memset(wmsg, 0, sizeof(woomera_message));
|
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
static int woomera_message_parse(switch_socket_t * fd, woomera_message * wmsg, int timeout, woomera_profile * profile, woomera_event_queue * event_queue)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
2006-03-30 23:02:50 +00:00
|
|
|
char *cur, *cr, *next = NULL;
|
2006-01-03 22:13:59 +00:00
|
|
|
char buf[2048] = "", *ptr;
|
|
|
|
int bytes = 0;
|
|
|
|
|
|
|
|
memset(wmsg, 0, sizeof(woomera_message));
|
|
|
|
|
2007-02-14 19:31:58 +00:00
|
|
|
if (!fd) {
|
2006-01-03 22:13:59 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (timeout < 0) {
|
|
|
|
timeout = abs(timeout);
|
|
|
|
} else if (timeout == 0) {
|
|
|
|
timeout = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ptr = buf;
|
|
|
|
bytes = 0;
|
2006-03-30 23:02:50 +00:00
|
|
|
while (!strstr(buf, WOOMERA_RECORD_SEPERATOR)) {
|
2006-01-03 22:13:59 +00:00
|
|
|
size_t len = 1;
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_status_t status;
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
if (!profile->thread_running) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2006-12-28 20:05:54 +00:00
|
|
|
status = switch_socket_recv(fd, ptr, &len);
|
2007-01-04 18:02:05 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
if (status == 70007) {
|
|
|
|
char bbuf = '\n';
|
|
|
|
switch_size_t blen = sizeof(bbuf);
|
|
|
|
switch_socket_send(fd, &bbuf, &blen);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (status != SWITCH_STATUS_SUCCESS) {
|
|
|
|
return -1;
|
|
|
|
}
|
2006-12-28 20:05:54 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
ptr++;
|
|
|
|
bytes++;
|
|
|
|
}
|
|
|
|
//*eor = '\0';
|
|
|
|
next = buf;
|
|
|
|
|
|
|
|
if (globals.debug) {
|
2007-11-23 18:50:54 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Receive Message: {%s} [%s/%d]\n%s\n%s\n", profile->name,
|
2007-03-29 22:31:56 +00:00
|
|
|
profile->woomera_host, profile->woomera_port, WOOMERA_DEBUG_LINE, buf);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
2006-02-20 06:13:56 +00:00
|
|
|
while ((cur = next) != 0) {
|
|
|
|
if ((cr = strstr(cur, WOOMERA_LINE_SEPERATOR)) != 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
*cr = '\0';
|
|
|
|
next = cr + (sizeof(WOOMERA_LINE_SEPERATOR) - 1);
|
|
|
|
if (!strcmp(next, WOOMERA_RECORD_SEPERATOR)) {
|
|
|
|
break;
|
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
}
|
2007-12-15 20:50:15 +00:00
|
|
|
if (wmsg->last > WOOMERA_ARRAY_LEN) {
|
|
|
|
break;
|
|
|
|
}
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
if (!cur || !cur[0]) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!wmsg->last) {
|
|
|
|
switch_set_flag(wmsg, WFLAG_EXISTS);
|
|
|
|
if (!strncasecmp(cur, "EVENT", 5)) {
|
|
|
|
cur += 6;
|
|
|
|
switch_set_flag(wmsg, WFLAG_EVENT);
|
|
|
|
|
2006-02-20 06:13:56 +00:00
|
|
|
if (cur && (cr = strchr(cur, ' ')) != 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
char *id;
|
|
|
|
|
|
|
|
*cr = '\0';
|
|
|
|
cr++;
|
|
|
|
id = cr;
|
2006-02-20 06:13:56 +00:00
|
|
|
if (cr && (cr = strchr(cr, ' ')) != 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
*cr = '\0';
|
|
|
|
cr++;
|
2007-12-15 20:55:10 +00:00
|
|
|
switch_copy_string(wmsg->command_args, cr, WOOMERA_STRLEN);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
if (id) {
|
2007-12-15 20:55:10 +00:00
|
|
|
switch_copy_string(wmsg->callid, id, sizeof(wmsg->callid) - 1);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2006-02-20 06:13:56 +00:00
|
|
|
if (cur && (cur = strchr(cur, ' ')) != 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
*cur = '\0';
|
|
|
|
cur++;
|
|
|
|
wmsg->mval = atoi(buf);
|
|
|
|
} else {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Malformed Message!\n");
|
2006-01-03 22:13:59 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (cur) {
|
2007-12-15 20:55:10 +00:00
|
|
|
switch_copy_string(wmsg->command, cur, WOOMERA_STRLEN);
|
2006-01-03 22:13:59 +00:00
|
|
|
} else {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Malformed Message!\n");
|
2006-01-03 22:13:59 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
char *name, *val;
|
|
|
|
name = cur;
|
2006-02-20 06:13:56 +00:00
|
|
|
if ((val = strchr(name, ':')) != 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
*val = '\0';
|
|
|
|
val++;
|
|
|
|
while (*val == ' ') {
|
|
|
|
*val = '\0';
|
|
|
|
val++;
|
|
|
|
}
|
2007-12-15 20:55:10 +00:00
|
|
|
switch_copy_string(wmsg->values[wmsg->last - 1], val, WOOMERA_STRLEN);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
2007-12-15 20:55:10 +00:00
|
|
|
switch_copy_string(wmsg->names[wmsg->last - 1], name, WOOMERA_STRLEN);
|
2006-01-03 22:13:59 +00:00
|
|
|
if (name && val && !strcasecmp(name, "content-type")) {
|
|
|
|
switch_set_flag(wmsg, WFLAG_CONTENT);
|
|
|
|
bytes = atoi(val);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
wmsg->last++;
|
|
|
|
}
|
|
|
|
|
|
|
|
wmsg->last--;
|
|
|
|
|
|
|
|
if (bytes && switch_test_flag(wmsg, WFLAG_CONTENT)) {
|
|
|
|
size_t len = (bytes > sizeof(wmsg->body)) ? sizeof(wmsg->body) : bytes;
|
|
|
|
switch_socket_recv(fd, wmsg->body, &len);
|
|
|
|
|
|
|
|
if (globals.debug) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s\n", wmsg->body);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (event_queue && switch_test_flag(wmsg, WFLAG_EVENT)) {
|
|
|
|
if (globals.debug) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Queue Event: {%s} [%s]\n", profile->name, wmsg->command);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
/* we don't want events we want a reply so we will stash them for later */
|
|
|
|
woomera_enqueue_event(event_queue, wmsg);
|
|
|
|
|
|
|
|
/* call ourself recursively to find the reply. we'll keep doing this as long we get events.
|
|
|
|
* wmsg will be overwritten but it's ok we just queued it.
|
|
|
|
*/
|
|
|
|
return woomera_message_parse(fd, wmsg, timeout, profile, event_queue);
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
} else if (wmsg->mval > 99 && wmsg->mval < 200) {
|
|
|
|
/* reply in the 100's are nice but we need to wait for another reply
|
|
|
|
call ourself recursively to find the reply > 199 and forget this reply.
|
2006-01-20 15:05:05 +00:00
|
|
|
*/
|
2006-01-03 22:13:59 +00:00
|
|
|
return woomera_message_parse(fd, wmsg, timeout, profile, event_queue);
|
|
|
|
} else {
|
|
|
|
return switch_test_flag(wmsg, WFLAG_EXISTS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
static int connect_woomera(switch_socket_t ** new_sock, woomera_profile * profile, int flags)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
switch_sockaddr_t *sa;
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
if (switch_sockaddr_info_get(&sa, profile->woomera_host, AF_INET, profile->woomera_port, 0, module_pool) != SWITCH_STATUS_SUCCESS) {
|
2006-01-03 22:13:59 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2006-03-30 23:02:50 +00:00
|
|
|
|
|
|
|
if (switch_socket_create(new_sock, AF_INET, SOCK_STREAM, 0, module_pool) != SWITCH_STATUS_SUCCESS) {
|
2006-01-03 22:13:59 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2007-01-04 18:02:05 +00:00
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
switch_socket_timeout_set((*new_sock), 10000000);
|
|
|
|
switch_socket_opt_set((*new_sock), SWITCH_SO_KEEPALIVE, 1);
|
2007-01-05 15:52:23 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
/*
|
2006-01-20 15:05:05 +00:00
|
|
|
status = switch_socket_bind((*new_sock), sa);
|
|
|
|
if (0 && status != SWITCH_STATUS_SUCCESS) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Can't Bind to %s:%d!\n", profile->woomera_host, profile->woomera_port);
|
2006-01-20 15:05:05 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*/
|
2006-03-30 23:02:50 +00:00
|
|
|
if (switch_socket_connect((*new_sock), sa) != SWITCH_STATUS_SUCCESS) {
|
2006-01-03 22:13:59 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2007-01-04 18:02:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
static int woomera_profile_thread_running(woomera_profile * profile, int set, int new)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
int running = 0;
|
|
|
|
|
|
|
|
switch_mutex_lock(profile->iolock);
|
|
|
|
if (set) {
|
|
|
|
profile->thread_running = new;
|
|
|
|
}
|
|
|
|
running = profile->thread_running;
|
|
|
|
switch_mutex_unlock(profile->iolock);
|
|
|
|
return running;
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
static int woomera_locate_socket(woomera_profile * profile, switch_socket_t ** woomera_socket)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
woomera_message wmsg;
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
for (;;) {
|
|
|
|
|
|
|
|
while (connect_woomera(woomera_socket, profile, 0) < 0) {
|
|
|
|
if (!woomera_profile_thread_running(profile, 0, 0)) {
|
|
|
|
break;
|
|
|
|
}
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "{%s} Cannot Reconnect to Woomera! retry in 5 seconds\n", profile->name);
|
2006-01-03 22:13:59 +00:00
|
|
|
switch_sleep(WOOMERA_RECONNECT_TIME);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*woomera_socket) {
|
|
|
|
if (switch_test_flag(profile, PFLAG_INBOUND)) {
|
|
|
|
woomera_printf(profile, *woomera_socket, "LISTEN%s", WOOMERA_RECORD_SEPERATOR);
|
2007-03-30 00:13:31 +00:00
|
|
|
if (woomera_message_parse(*woomera_socket, &wmsg, WOOMERA_HARD_TIMEOUT, profile, &profile->event_queue) < 0) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "{%s} HELP! Woomera is broken!\n", profile->name);
|
2006-01-03 22:13:59 +00:00
|
|
|
globals.panic = 1;
|
|
|
|
woomera_profile_thread_running(&default_profile, 1, 0);
|
|
|
|
switch_sleep(WOOMERA_RECONNECT_TIME);
|
|
|
|
if (*woomera_socket) {
|
|
|
|
woomera_socket_close(woomera_socket);
|
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
switch_sleep(100);
|
|
|
|
break;
|
2006-01-20 15:05:05 +00:00
|
|
|
}
|
2006-01-03 22:13:59 +00:00
|
|
|
return *woomera_socket ? 1 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
static int tech_create_read_socket(private_object * tech_pvt)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
2006-04-29 01:00:52 +00:00
|
|
|
switch_memory_pool_t *pool = switch_core_session_get_pool(tech_pvt->session);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
if ((tech_pvt->port = globals.next_woomera_port++) >= WOOMERA_MAX_PORT) {
|
|
|
|
tech_pvt->port = globals.next_woomera_port = WOOMERA_MIN_PORT;
|
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "connect %s:%d\n", tech_pvt->profile->audio_ip, tech_pvt->port);
|
2006-01-03 22:13:59 +00:00
|
|
|
//tech_pvt->udp_socket = create_udp_socket(tech_pvt->profile->audio_ip, tech_pvt->port, &tech_pvt->udpread, 0);
|
|
|
|
|
|
|
|
switch_sockaddr_info_get(&tech_pvt->udpread, tech_pvt->profile->audio_ip, SWITCH_UNSPEC, tech_pvt->port, 0, pool);
|
|
|
|
if (switch_socket_create(&tech_pvt->udp_socket, AF_INET, SOCK_DGRAM, 0, pool) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_socket_bind(tech_pvt->udp_socket, tech_pvt->udpread);
|
2006-01-20 15:05:05 +00:00
|
|
|
switch_socket_create_pollfd(&tech_pvt->read_poll, tech_pvt->udp_socket, SWITCH_POLLIN | SWITCH_POLLERR, pool);
|
|
|
|
switch_socket_create_pollfd(&tech_pvt->write_poll, tech_pvt->udp_socket, SWITCH_POLLOUT | SWITCH_POLLERR, pool);
|
2007-11-19 16:38:31 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_MEDIA);
|
|
|
|
} else {
|
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_ABORT);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
2007-11-19 16:38:31 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
static int tech_activate(private_object * tech_pvt)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
woomera_message wmsg;
|
|
|
|
|
|
|
|
if (tech_pvt) {
|
2006-01-20 15:05:05 +00:00
|
|
|
if ((connect_woomera(&tech_pvt->command_channel, tech_pvt->profile, 0))) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "connected to woomera!\n");
|
2006-01-03 22:13:59 +00:00
|
|
|
} else {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Can't connect to woomera!\n");
|
2006-01-03 22:13:59 +00:00
|
|
|
switch_sleep(WOOMERA_RECONNECT_TIME);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
|
|
|
|
|
|
|
|
woomera_printf(tech_pvt->profile,
|
2006-01-20 15:05:05 +00:00
|
|
|
tech_pvt->command_channel,
|
|
|
|
"CALL %s%sRaw-Audio: %s/%d%sLocal-Name: %s!%s%s",
|
2006-01-03 22:13:59 +00:00
|
|
|
tech_pvt->caller_profile->destination_number,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
|
|
|
tech_pvt->profile->audio_ip,
|
|
|
|
tech_pvt->port,
|
|
|
|
WOOMERA_LINE_SEPERATOR,
|
2007-03-30 00:13:31 +00:00
|
|
|
tech_pvt->caller_profile->caller_id_name, tech_pvt->caller_profile->caller_id_number, WOOMERA_RECORD_SEPERATOR);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
woomera_message_parse(tech_pvt->command_channel, &wmsg, WOOMERA_HARD_TIMEOUT, tech_pvt->profile, &tech_pvt->event_queue);
|
2006-01-03 22:13:59 +00:00
|
|
|
} else {
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_PARSE_INCOMING);
|
2006-01-03 22:13:59 +00:00
|
|
|
woomera_printf(tech_pvt->profile, tech_pvt->command_channel, "LISTEN%s", WOOMERA_RECORD_SEPERATOR);
|
2007-03-30 00:13:31 +00:00
|
|
|
if (woomera_message_parse(tech_pvt->command_channel, &wmsg, WOOMERA_HARD_TIMEOUT, tech_pvt->profile, &tech_pvt->event_queue) < 0) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "{%s} HELP! Woomera is broken!\n", tech_pvt->profile->name);
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_ABORT);
|
2006-01-03 22:13:59 +00:00
|
|
|
globals.panic = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Where's my tech_pvt?\n");
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
static void *woomera_channel_thread_run(switch_thread_t * thread, void *obj)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_core_session_t *session = obj;
|
|
|
|
switch_channel_t *channel = NULL;
|
2006-01-03 22:13:59 +00:00
|
|
|
struct private_object *tech_pvt = NULL;
|
|
|
|
woomera_message wmsg;
|
|
|
|
int res = 0;
|
|
|
|
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(session != NULL);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
channel = switch_core_session_get_channel(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(channel != NULL);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
tech_pvt = switch_core_session_get_private(session);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
if (!tech_pvt->udp_socket) {
|
|
|
|
tech_create_read_socket(tech_pvt);
|
|
|
|
}
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
|
|
|
|
for (;;) {
|
2006-01-03 22:13:59 +00:00
|
|
|
if (globals.panic) {
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_ABORT);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_ABORT)) {
|
2006-05-12 01:12:40 +00:00
|
|
|
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
|
2006-01-03 22:13:59 +00:00
|
|
|
udp_socket_close(tech_pvt);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_ACTIVATE)) {
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_clear_flag_locked(tech_pvt, TFLAG_ACTIVATE);
|
2006-01-03 22:13:59 +00:00
|
|
|
tech_activate(tech_pvt);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_ANSWER)) {
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_clear_flag_locked(tech_pvt, TFLAG_ANSWER);
|
2006-01-03 22:13:59 +00:00
|
|
|
#ifdef USE_ANSWER
|
2007-03-30 00:13:31 +00:00
|
|
|
woomera_printf(tech_pvt->profile, tech_pvt->command_channel, "ANSWER %s%s", tech_pvt->call_info.callid, WOOMERA_RECORD_SEPERATOR);
|
|
|
|
if (woomera_message_parse(tech_pvt->command_channel, &wmsg, WOOMERA_HARD_TIMEOUT, tech_pvt->profile, &tech_pvt->event_queue) < 0) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "{%s} HELP! Woomera is broken!\n", tech_pvt->profile->name);
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_ABORT);
|
2006-01-03 22:13:59 +00:00
|
|
|
globals.panic = 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
if (switch_test_flag(tech_pvt, TFLAG_DTMF)) {
|
|
|
|
switch_mutex_lock(tech_pvt->iolock);
|
2006-01-20 15:05:05 +00:00
|
|
|
woomera_printf(tech_pvt->profile, tech_pvt->command_channel, "DTMF %s %s%s", tech_pvt->call_info.callid,
|
|
|
|
tech_pvt->dtmfbuf, WOOMERA_RECORD_SEPERATOR);
|
2007-03-30 00:13:31 +00:00
|
|
|
if (woomera_message_parse(tech_pvt->command_channel, &wmsg, WOOMERA_HARD_TIMEOUT, tech_pvt->profile, &tech_pvt->event_queue) < 0) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "{%s} HELP! Woomera is broken!\n", tech_pvt->profile->name);
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_ABORT);
|
2006-01-03 22:13:59 +00:00
|
|
|
globals.panic = 1;
|
|
|
|
continue;
|
|
|
|
}
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_clear_flag_locked(tech_pvt, TFLAG_DTMF);
|
2006-01-03 22:13:59 +00:00
|
|
|
memset(tech_pvt->dtmfbuf, 0, sizeof(tech_pvt->dtmfbuf));
|
|
|
|
switch_mutex_unlock(tech_pvt->iolock);
|
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
#if 1==0 /*convert to use switch_time_now */
|
|
|
|
if (tech_pvt->timeout) {
|
2006-01-03 22:13:59 +00:00
|
|
|
struct timeval now;
|
|
|
|
int elapsed;
|
|
|
|
gettimeofday(&now, NULL);
|
2007-03-30 00:13:31 +00:00
|
|
|
elapsed = (((now.tv_sec * 1000) + now.tv_usec / 1000) - ((tech_pvt->started.tv_sec * 1000) + tech_pvt->started.tv_usec / 1000));
|
2006-01-03 22:13:59 +00:00
|
|
|
if (elapsed > tech_pvt->timeout) {
|
|
|
|
/* call timed out! */
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_ABORT);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!tech_pvt->command_channel) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* Check for events */
|
2006-02-20 06:13:56 +00:00
|
|
|
if ((res = woomera_dequeue_event(&tech_pvt->event_queue, &wmsg)) != 0 ||
|
|
|
|
(res = woomera_message_parse(tech_pvt->command_channel, &wmsg, 100, tech_pvt->profile, NULL)) != 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
if (res < 0 || !strcasecmp(wmsg.command, "HANGUP")) {
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_ABORT);
|
2006-01-03 22:13:59 +00:00
|
|
|
continue;
|
|
|
|
} else if (!strcasecmp(wmsg.command, "DTMF")) {
|
|
|
|
/*
|
2006-01-20 15:05:05 +00:00
|
|
|
struct ast_frame dtmf_frame = {AST_FRAME_DTMF};
|
|
|
|
int x = 0;
|
|
|
|
for (x = 0; x < strlen(wmsg.command_args); x++) {
|
|
|
|
dtmf_frame.subclass = wmsg.command_args[x];
|
|
|
|
ast_queue_frame(tech_pvt->owner, ast_frdup(&dtmf_frame));
|
|
|
|
if (globals.debug > 1) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, WOOMERA_DEBUG_PREFIX "SEND DTMF [%c] to %s\n", dtmf_frame.subclass, tech_pvt->owner->name);
|
2006-01-20 15:05:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
*/
|
2006-01-03 22:13:59 +00:00
|
|
|
} else if (!strcasecmp(wmsg.command, "PROCEED")) {
|
|
|
|
/* This packet has lots of info so well keep it */
|
|
|
|
tech_pvt->call_info = wmsg;
|
2007-02-13 15:47:15 +00:00
|
|
|
switch_core_session_queue_indication(tech_pvt->session, SWITCH_MESSAGE_INDICATE_RINGING);
|
|
|
|
switch_channel_mark_ring_ready(channel);
|
2006-01-03 22:13:59 +00:00
|
|
|
} else if (switch_test_flag(tech_pvt, TFLAG_PARSE_INCOMING) && !strcasecmp(wmsg.command, "INCOMING")) {
|
|
|
|
char *exten;
|
2007-12-15 20:56:56 +00:00
|
|
|
char cid_name[512] = "";
|
2006-01-03 22:13:59 +00:00
|
|
|
char *cid_num;
|
|
|
|
char *ip;
|
|
|
|
char *p;
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_clear_flag_locked(tech_pvt, TFLAG_PARSE_INCOMING);
|
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_INCOMING);
|
2006-01-03 22:13:59 +00:00
|
|
|
tech_pvt->call_info = wmsg;
|
|
|
|
|
|
|
|
exten = woomera_message_header(&wmsg, "Local-Number");
|
|
|
|
if (switch_strlen_zero(exten)) {
|
|
|
|
exten = "s";
|
|
|
|
}
|
|
|
|
|
2006-02-20 06:13:56 +00:00
|
|
|
if ((p = woomera_message_header(&wmsg, "Remote-Name")) != 0) {
|
2007-12-15 20:55:10 +00:00
|
|
|
switch_copy_string(cid_name, p, sizeof(cid_name));
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-02-20 06:13:56 +00:00
|
|
|
if ((cid_num = strchr(cid_name, '!')) != 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
*cid_num = '\0';
|
|
|
|
cid_num++;
|
|
|
|
} else {
|
|
|
|
cid_num = woomera_message_header(&wmsg, "Remote-Number");
|
|
|
|
}
|
|
|
|
ip = woomera_message_header(&wmsg, "Remote-Address");
|
|
|
|
|
2006-03-01 22:55:28 +00:00
|
|
|
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
|
2006-05-26 16:00:08 +00:00
|
|
|
NULL,
|
2006-01-03 22:13:59 +00:00
|
|
|
tech_pvt->profile->dialplan,
|
2007-08-28 22:44:02 +00:00
|
|
|
cid_name,
|
|
|
|
cid_num,
|
|
|
|
ip,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
modname,
|
|
|
|
NULL,
|
|
|
|
exten)) != 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
char name[128];
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(name, sizeof(name), "Woomera/%s-%04x", tech_pvt->caller_profile->destination_number, rand() & 0xffff);
|
2006-01-03 22:13:59 +00:00
|
|
|
switch_channel_set_name(channel, name);
|
2006-02-22 02:50:33 +00:00
|
|
|
switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
|
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
woomera_printf(tech_pvt->profile, tech_pvt->command_channel,
|
2006-01-03 22:13:59 +00:00
|
|
|
"%s %s%s"
|
|
|
|
"Raw-Audio: %s/%d%s",
|
2007-03-30 00:13:31 +00:00
|
|
|
MEDIA_ANSWER, wmsg.callid, WOOMERA_LINE_SEPERATOR, tech_pvt->profile->audio_ip, tech_pvt->port, WOOMERA_RECORD_SEPERATOR);
|
|
|
|
|
|
|
|
if (woomera_message_parse(tech_pvt->command_channel, &wmsg, WOOMERA_HARD_TIMEOUT, tech_pvt->profile, &tech_pvt->event_queue) < 0) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "{%s} HELP! Woomera is broken!\n", tech_pvt->profile->name);
|
2006-06-23 16:59:47 +00:00
|
|
|
switch_set_flag_locked(tech_pvt, TFLAG_ABORT);
|
2006-01-03 22:13:59 +00:00
|
|
|
globals.panic = 1;
|
|
|
|
continue;
|
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
} else if (!strcasecmp(wmsg.command, "CONNECT")) {
|
|
|
|
|
|
|
|
} else if (!strcasecmp(wmsg.command, "MEDIA")) {
|
|
|
|
char *raw_audio_header;
|
|
|
|
|
2006-02-20 06:13:56 +00:00
|
|
|
if ((raw_audio_header = woomera_message_header(&wmsg, "Raw-Audio")) != 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
char ip[25];
|
|
|
|
char *ptr;
|
2006-02-20 06:13:56 +00:00
|
|
|
switch_port_t port = 0;
|
2006-01-03 22:13:59 +00:00
|
|
|
|
2007-12-15 20:55:10 +00:00
|
|
|
switch_copy_string(ip, raw_audio_header, sizeof(ip) - 1);
|
2006-02-20 06:13:56 +00:00
|
|
|
if ((ptr = strchr(ip, '/')) != 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
*ptr = '\0';
|
|
|
|
ptr++;
|
2007-03-29 22:31:56 +00:00
|
|
|
port = (switch_port_t) atoi(ptr);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
/* Move Channel's State Machine to RING */
|
|
|
|
switch_channel_answer(channel);
|
|
|
|
switch_channel_set_state(channel, CS_RING);
|
|
|
|
|
|
|
|
if (switch_sockaddr_info_get(&tech_pvt->udpwrite,
|
2007-03-30 00:13:31 +00:00
|
|
|
ip, SWITCH_UNSPEC, port, 0, switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
|
2006-01-03 22:13:59 +00:00
|
|
|
if (globals.debug) {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
2007-03-30 00:13:31 +00:00
|
|
|
WOOMERA_DEBUG_PREFIX "{%s} Cannot resolve %s\n", tech_pvt->profile->name, ip);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
2006-04-22 03:05:25 +00:00
|
|
|
switch_channel_hangup(channel, SWITCH_CAUSE_NETWORK_OUT_OF_ORDER);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (globals.debug > 2) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, WOOMERA_DEBUG_PREFIX "CHECK {%s}(%d)\n", tech_pvt->profile->name, res);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (globals.debug > 1) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, WOOMERA_DEBUG_PREFIX "Monitor thread for %s done.\n", tech_pvt->profile->name);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
|
|
|
|
static void *woomera_thread_run(void *obj)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
int res = 0;
|
|
|
|
woomera_message wmsg;
|
|
|
|
woomera_profile *profile;
|
|
|
|
|
|
|
|
profile = obj;
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Started Woomera Thread {%s}.\n", profile->name);
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
profile->thread_running = 1;
|
|
|
|
profile->woomera_socket = NULL;
|
|
|
|
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
while (woomera_profile_thread_running(profile, 0, 0)) {
|
2006-01-03 22:13:59 +00:00
|
|
|
/* listen on socket and handle events */
|
|
|
|
if (globals.panic == 2) {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Woomera is disabled!\n");
|
2006-01-03 22:13:59 +00:00
|
|
|
switch_sleep(WOOMERA_RECONNECT_TIME);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2006-01-20 15:05:05 +00:00
|
|
|
if (!profile->woomera_socket) {
|
2006-01-03 22:13:59 +00:00
|
|
|
if (woomera_locate_socket(profile, &profile->woomera_socket)) {
|
|
|
|
globals.panic = 0;
|
|
|
|
}
|
|
|
|
if (!woomera_profile_thread_running(profile, 0, 0)) {
|
|
|
|
break;
|
|
|
|
}
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Woomera Thread Up {%s} %s/%d\n", profile->name,
|
2007-03-29 22:31:56 +00:00
|
|
|
profile->woomera_host, profile->woomera_port);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (globals.panic) {
|
|
|
|
if (globals.panic != 2) {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "Help I'm in a state of panic!\n");
|
2006-01-20 15:05:05 +00:00
|
|
|
globals.panic = 0; //fix
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
woomera_socket_close(&profile->woomera_socket);
|
|
|
|
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
if ((((res = woomera_dequeue_event(&profile->event_queue, &wmsg)) != 0) || ((res = woomera_message_parse(profile->woomera_socket, &wmsg,
|
|
|
|
/* if we are not stingy with threads we can block forever */
|
|
|
|
0, profile, NULL))) != 0)) {
|
2006-01-03 22:13:59 +00:00
|
|
|
if (res < 0) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ALERT, "{%s} HELP! I lost my connection to woomera!\n", profile->name);
|
2006-01-03 22:13:59 +00:00
|
|
|
woomera_socket_close(&profile->woomera_socket);
|
|
|
|
|
|
|
|
//global_set_flag(TFLAG_ABORT);
|
|
|
|
globals.panic = 1;
|
|
|
|
continue;
|
|
|
|
|
2007-03-29 22:31:56 +00:00
|
|
|
/* Can't get to the following code --Commented out for now. */
|
2006-02-20 06:13:56 +00:00
|
|
|
/* if (profile->woomera_socket)
|
2006-01-03 22:13:59 +00:00
|
|
|
if (switch_test_flag(profile, PFLAG_INBOUND)) {
|
|
|
|
woomera_printf(profile, profile->woomera_socket, "LISTEN%s", WOOMERA_RECORD_SEPERATOR);
|
|
|
|
if (woomera_message_parse(profile->woomera_socket,
|
2006-01-20 15:05:05 +00:00
|
|
|
&wmsg, WOOMERA_HARD_TIMEOUT, profile, &profile->event_queue) < 0) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "{%s} HELP! Woomera is broken!\n",
|
2006-01-20 15:05:05 +00:00
|
|
|
profile->name);
|
2006-01-03 22:13:59 +00:00
|
|
|
globals.panic = 1;
|
|
|
|
woomera_socket_close(&profile->woomera_socket);
|
2006-01-20 15:05:05 +00:00
|
|
|
}
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
if (profile->woomera_socket) {
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Woomera Thread Up {%s} %s/%d\n", profile->name,
|
2006-01-20 15:05:05 +00:00
|
|
|
profile->woomera_host, profile->woomera_port);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
2006-02-20 06:13:56 +00:00
|
|
|
}*/
|
2006-03-30 23:02:50 +00:00
|
|
|
//continue;
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcasecmp(wmsg.command, "INCOMING")) {
|
|
|
|
char *name;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_core_session_t *session;
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-02-20 06:13:56 +00:00
|
|
|
if ((name = woomera_message_header(&wmsg, "Remote-Address")) == 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
name = woomera_message_header(&wmsg, "Channel-Name");
|
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "New Inbound Channel %s!\n", name);
|
2007-06-20 07:15:53 +00:00
|
|
|
if ((session = switch_core_session_request(woomera_endpoint_interface, NULL)) != 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
struct private_object *tech_pvt;
|
2006-04-29 06:05:03 +00:00
|
|
|
switch_channel_t *channel;
|
2006-01-03 22:13:59 +00:00
|
|
|
|
2006-01-09 18:40:56 +00:00
|
|
|
switch_core_session_add_stream(session, NULL);
|
|
|
|
|
2007-03-30 00:13:31 +00:00
|
|
|
if ((tech_pvt = (struct private_object *) switch_core_session_alloc(session, sizeof(struct private_object))) != 0) {
|
2006-01-03 22:13:59 +00:00
|
|
|
memset(tech_pvt, 0, sizeof(*tech_pvt));
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
2006-01-03 22:13:59 +00:00
|
|
|
tech_pvt->profile = &default_profile;
|
|
|
|
channel = switch_core_session_get_channel(session);
|
|
|
|
switch_core_session_set_private(session, tech_pvt);
|
|
|
|
tech_pvt->session = session;
|
|
|
|
} 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");
|
2006-01-03 22:13:59 +00:00
|
|
|
switch_core_session_destroy(&session);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
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");
|
|
|
|
switch_core_session_destroy(&session);
|
|
|
|
break;
|
|
|
|
}
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
if (globals.debug > 2) {
|
2007-03-30 00:13:31 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Main Thread {%s} Select Return %d\n", profile->name, res);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch_yield(100);
|
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
if (profile->woomera_socket) {
|
|
|
|
woomera_printf(profile, profile->woomera_socket, "BYE%s", WOOMERA_RECORD_SEPERATOR);
|
|
|
|
woomera_socket_close(&profile->woomera_socket);
|
|
|
|
}
|
|
|
|
|
2006-04-11 21:13:44 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ended Woomera Thread {%s}.\n", profile->name);
|
2006-01-03 22:13:59 +00:00
|
|
|
woomera_profile_thread_running(profile, 1, -1);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-06-13 17:06:10 +00:00
|
|
|
SWITCH_MODULE_RUNTIME_FUNCTION(mod_woomera_runtime)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
woomera_thread_run(&default_profile);
|
|
|
|
|
|
|
|
return SWITCH_STATUS_TERM;
|
|
|
|
}
|
|
|
|
|
2007-06-13 17:06:10 +00:00
|
|
|
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_woomera_shutdown)
|
2006-01-03 22:13:59 +00:00
|
|
|
{
|
|
|
|
int x = 0;
|
|
|
|
woomera_profile_thread_running(&default_profile, 1, 0);
|
|
|
|
while (!woomera_profile_thread_running(&default_profile, 0, 0)) {
|
|
|
|
woomera_socket_close(&default_profile.woomera_socket);
|
|
|
|
if (x++ > 10) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch_yield(1);
|
|
|
|
}
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2007-06-20 07:15:53 +00:00
|
|
|
|
2007-06-13 17:06:10 +00:00
|
|
|
SWITCH_MODULE_LOAD_FUNCTION(mod_woomera_load)
|
2006-01-20 15:05:05 +00:00
|
|
|
{
|
2006-01-03 22:13:59 +00:00
|
|
|
struct woomera_profile *profile = &default_profile;
|
|
|
|
char *cf = "woomera.conf";
|
2006-05-10 03:23:05 +00:00
|
|
|
switch_xml_t cfg, xml, settings, param, xmlp;
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
memset(&globals, 0, sizeof(globals));
|
|
|
|
globals.next_woomera_port = WOOMERA_MIN_PORT;
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-05-10 15:47:54 +00:00
|
|
|
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of %s failed\n", cf);
|
2006-01-03 22:13:59 +00:00
|
|
|
return SWITCH_STATUS_TERM;
|
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +00:00
|
|
|
switch_set_flag(profile, PFLAG_INBOUND | PFLAG_OUTBOUND);
|
|
|
|
profile->name = "main";
|
2007-12-15 20:55:10 +00:00
|
|
|
switch_copy_string(profile->dialplan, "default", sizeof(profile->dialplan) - 1);
|
|
|
|
switch_copy_string(profile->audio_ip, "127.0.0.1", sizeof(profile->audio_ip) - 1);
|
|
|
|
switch_copy_string(profile->woomera_host, "127.0.0.1", sizeof(profile->woomera_host) - 1);
|
2007-03-29 22:31:56 +00:00
|
|
|
profile->woomera_port = (switch_port_t) 42420;
|
2006-01-20 15:05:05 +00:00
|
|
|
|
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-01-20 15:05:05 +00:00
|
|
|
if (!strcmp(var, "noload") && atoi(val)) {
|
|
|
|
return SWITCH_STATUS_TERM;
|
|
|
|
}
|
2006-01-03 22:13:59 +00:00
|
|
|
if (!strcmp(var, "debug")) {
|
|
|
|
globals.debug = atoi(val);
|
|
|
|
}
|
2006-05-10 03:23:05 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (xmlp = switch_xml_child(cfg, "interface"); xmlp; xmlp = xmlp->next) {
|
|
|
|
for (param = switch_xml_child(xmlp, "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-09-13 13:41:35 +00:00
|
|
|
if (!strcmp(var, "audio-ip")) {
|
2007-12-15 20:55:10 +00:00
|
|
|
switch_copy_string(profile->audio_ip, val, sizeof(profile->audio_ip) - 1);
|
2006-01-03 22:13:59 +00:00
|
|
|
} else if (!strcmp(var, "host")) {
|
2007-12-15 20:55:10 +00:00
|
|
|
switch_copy_string(profile->woomera_host, val, sizeof(profile->woomera_host) - 1);
|
2006-01-03 22:13:59 +00:00
|
|
|
} else if (!strcmp(var, "port")) {
|
2007-03-29 22:31:56 +00:00
|
|
|
profile->woomera_port = (switch_port_t) atoi(val);
|
2006-01-03 22:13:59 +00:00
|
|
|
} else if (!strcmp(var, "disabled")) {
|
|
|
|
if (atoi(val) > 0) {
|
|
|
|
switch_set_flag(profile, PFLAG_DISABLED);
|
|
|
|
}
|
|
|
|
} else if (!strcmp(var, "inbound")) {
|
|
|
|
if (atoi(val) < 1) {
|
|
|
|
switch_clear_flag(profile, PFLAG_INBOUND);
|
|
|
|
}
|
|
|
|
} else if (!strcmp(var, "outbound")) {
|
|
|
|
if (atoi(val) < 1) {
|
|
|
|
switch_clear_flag(profile, PFLAG_OUTBOUND);
|
|
|
|
}
|
|
|
|
} else if (!strcmp(var, "dialplan")) {
|
2007-12-15 20:55:10 +00:00
|
|
|
switch_copy_string(profile->dialplan, val, sizeof(profile->dialplan) - 1);
|
2006-01-03 22:13:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-05-10 03:23:05 +00:00
|
|
|
switch_xml_free(xml);
|
2006-01-03 22:13:59 +00:00
|
|
|
|
2007-06-20 07:15:53 +00:00
|
|
|
module_pool = pool;
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
if (switch_mutex_init(&default_profile.iolock, SWITCH_MUTEX_NESTED, module_pool) != SWITCH_STATUS_SUCCESS) {
|
2006-04-16 06:05:53 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "OH OH no lock\n");
|
2006-01-03 22:13:59 +00:00
|
|
|
return SWITCH_STATUS_TERM;
|
|
|
|
}
|
2006-01-20 15:05:05 +00:00
|
|
|
|
2006-01-03 22:13:59 +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);
|
|
|
|
woomera_endpoint_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_ENDPOINT_INTERFACE);
|
2007-06-20 18:53:26 +00:00
|
|
|
woomera_endpoint_interface->interface_name = "woomera";
|
2007-06-20 07:15:53 +00:00
|
|
|
woomera_endpoint_interface->io_routines = &woomera_io_routines;
|
|
|
|
woomera_endpoint_interface->state_handler = &woomera_event_handlers;
|
2006-01-03 22:13:59 +00:00
|
|
|
|
|
|
|
/* indicate that the module should continue to be loaded */
|
|
|
|
return SWITCH_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:
|
|
|
|
*/
|