Freeswitch-svn
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
January 2009
- 20 participants
- 514 discussions
Author: mcollins
Date: Thu Jan 22 13:44:08 2009
New Revision: 11381
Log:
Add /debug to /help list for fs_cli
Modified:
freeswitch/trunk/libs/esl/fs_cli.c
Modified: freeswitch/trunk/libs/esl/fs_cli.c
==============================================================================
--- freeswitch/trunk/libs/esl/fs_cli.c (original)
+++ freeswitch/trunk/libs/esl/fs_cli.c Thu Jan 22 13:44:08 2009
@@ -254,6 +254,7 @@
"/event, /noevent, /nixevent\tEvent commands.\n"
"/log, /nolog \tLog commands.\n"
"/filter \tFilter commands.\n"
+ "/debug [0-7] \tSet debug level.\n"
"\n"
);
1
0
22 Jan '09
Author: mikej
Date: Thu Jan 22 13:41:34 2009
New Revision: 11380
Log:
mod_xml_rpc: fixed authentication using @domain syntax (r:11064)
Modified:
freeswitch/branches/1.0/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c
Modified: freeswitch/branches/1.0/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c
==============================================================================
--- freeswitch/branches/1.0/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c (original)
+++ freeswitch/branches/1.0/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c Thu Jan 22 13:41:34 2009
@@ -178,6 +178,7 @@
if ((dp = strchr(user, '@'))) {
*dp++ = '\0';
domain_name = dp;
+ at++;
}
if (!domain_name) {
1
0
[commit] r11378 - freeswitch/branches/1.0/src/mod/applications/mod_conference
by FreeSWITCH SVN 22 Jan '09
by FreeSWITCH SVN 22 Jan '09
22 Jan '09
Author: mikej
Date: Thu Jan 22 13:37:56 2009
New Revision: 11378
Log:
mod_conference: add 'conference xml_list' and 'conference [conf_name] xml_list' (r:11062-11063)
Modified:
freeswitch/branches/1.0/src/mod/applications/mod_conference/mod_conference.c
Modified: freeswitch/branches/1.0/src/mod/applications/mod_conference/mod_conference.c
==============================================================================
--- freeswitch/branches/1.0/src/mod/applications/mod_conference/mod_conference.c (original)
+++ freeswitch/branches/1.0/src/mod/applications/mod_conference/mod_conference.c Thu Jan 22 13:37:56 2009
@@ -3038,6 +3038,140 @@
return ret_status;
}
+
+static void add_x_tag(switch_xml_t x_member, const char *name, const char *value, int off)
+{
+ switch_size_t dlen = strlen(value) * 3;
+ char *data;
+ switch_xml_t x_tag;
+
+ x_tag = switch_xml_add_child_d(x_member, name, off);
+ switch_assert(x_tag);
+
+ switch_zmalloc(data, dlen);
+
+ switch_url_encode(value, data, dlen);
+ switch_xml_set_txt_d(x_tag, data);
+ free(data);
+}
+
+static void conference_xlist(conference_obj_t *conference, switch_xml_t x_conference, int off)
+{
+ conference_member_t *member = NULL;
+ switch_xml_t x_member = NULL, x_members = NULL, x_flags;
+ int moff = 0;
+ char i[30] = "";
+ char *ival = i;
+ switch_assert(conference != NULL);
+ switch_assert(x_conference != NULL);
+
+ switch_xml_set_attr_d(x_conference, "name", conference->name);
+ switch_snprintf(i, sizeof(i), "%d", conference->count);
+ switch_xml_set_attr_d(x_conference, "member-count", ival);
+
+ if (switch_test_flag(conference, CFLAG_LOCKED)) {
+ switch_xml_set_attr_d(x_conference, "locked", "true");
+ }
+
+ x_members = switch_xml_add_child_d(x_conference, "members", 0);
+ switch_assert(x_members);
+
+ switch_mutex_lock(conference->member_mutex);
+
+ for (member = conference->members; member; member = member->next) {
+ switch_channel_t *channel;
+ switch_caller_profile_t *profile;
+ char *uuid;
+ char *name;
+ uint32_t count = 0;
+ switch_xml_t x_tag;
+ int toff = 0;
+
+ if (switch_test_flag(member, MFLAG_NOCHANNEL)) {
+ continue;
+ }
+
+ uuid = switch_core_session_get_uuid(member->session);
+ channel = switch_core_session_get_channel(member->session);
+ profile = switch_channel_get_caller_profile(channel);
+ name = switch_channel_get_name(channel);
+
+
+ x_member = switch_xml_add_child_d(x_members, "member", moff++);
+ switch_assert(x_member);
+
+ switch_snprintf(i, sizeof(i), "%d", member->id);
+
+ add_x_tag(x_member, "id", i, toff++);
+ add_x_tag(x_member, "uuid", uuid, toff++);
+ add_x_tag(x_member, "caller_id_name", profile->caller_id_name, toff++);
+ add_x_tag(x_member, "caller_id_number", profile->caller_id_number, toff++);
+
+
+ x_flags = switch_xml_add_child_d(x_member, "flags", count++);
+ switch_assert(x_flags);
+
+ x_tag = switch_xml_add_child_d(x_flags, "can_hear", count++);
+ switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_CAN_HEAR) ? "true" : "false");
+
+ x_tag = switch_xml_add_child_d(x_flags, "can_speak", count++);
+ switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_CAN_SPEAK) ? "true" : "false");
+
+ x_tag = switch_xml_add_child_d(x_flags, "talking", count++);
+ switch_xml_set_txt_d(x_tag, switch_test_flag(member, MFLAG_TALKING) ? "true" : "false");
+
+ x_tag = switch_xml_add_child_d(x_flags, "has_video", count++);
+ switch_xml_set_txt_d(x_tag, switch_channel_test_flag(switch_core_session_get_channel(member->session), CF_VIDEO) ? "true" : "false");
+
+ x_tag = switch_xml_add_child_d(x_flags, "has_floor", count++);
+ switch_xml_set_txt_d(x_tag, (member == member->conference->floor_holder) ? "true" : "false");
+
+ }
+
+ switch_mutex_unlock(conference->member_mutex);
+}
+static switch_status_t conf_api_sub_xml_list(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
+{
+ int count = 0;
+ switch_hash_index_t *hi;
+ void *val;
+ switch_xml_t x_conference, x_conferences;
+ int off = 0;
+ char *ebuf;
+
+ x_conferences = switch_xml_new("conferences");
+ switch_assert(x_conferences);
+
+ if (conference == NULL) {
+ for (hi = switch_hash_first(NULL, globals.conference_hash); hi; hi = switch_hash_next(hi)) {
+ switch_hash_this(hi, NULL, NULL, &val);
+ conference = (conference_obj_t *) val;
+
+ x_conference = switch_xml_add_child_d(x_conferences, "conference", off++);
+ switch_assert(conference);
+
+ count++;
+ conference_xlist(conference, x_conference, off);
+
+ }
+ } else {
+ x_conference = switch_xml_add_child_d(x_conferences, "conference", off++);
+ switch_assert(conference);
+ count++;
+ conference_xlist(conference, x_conference, off);
+ }
+
+
+ ebuf = switch_xml_toxml(x_conferences, SWITCH_TRUE);
+
+ stream->write_function(stream, "%s", ebuf);
+
+ switch_xml_free(x_conferences);
+ free(ebuf);
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
static switch_status_t conf_api_sub_play(conference_obj_t *conference, switch_stream_handle_t *stream, int argc, char **argv)
{
int ret_status = SWITCH_STATUS_GENERR;
@@ -3578,6 +3712,7 @@
/* Entries in this list should be kept in sync with the enum above */
static api_command_t conf_api_sub_commands[] = {
{"list", (void_fn_t) &conf_api_sub_list, CONF_API_SUB_ARGS_SPLIT, "<confname> list [delim <string>]"},
+ {"xml_list", (void_fn_t) &conf_api_sub_xml_list, CONF_API_SUB_ARGS_SPLIT, "<confname> xml_list"},
{"energy", (void_fn_t) &conf_api_sub_energy, CONF_API_SUB_MEMBER_TARGET,
"<confname> energy <member_id|all|last> [<newval>]"},
{"volume_in", (void_fn_t) &conf_api_sub_volume_in, CONF_API_SUB_MEMBER_TARGET,
@@ -3778,6 +3913,8 @@
/* special case the list command, because it doesn't require a conference argument */
if (strcasecmp(argv[0], "list") == 0) {
conf_api_sub_list(NULL, stream, argc, argv);
+ } else if (strcasecmp(argv[0], "xml_list") == 0) {
+ conf_api_sub_xml_list(NULL, stream, argc, argv);
} else if (strcasecmp(argv[0], "help") == 0 || strcasecmp(argv[0], "commands") == 0) {
stream->write_function(stream, "%s\n", api_syntax);
} else if (argv[1] && strcasecmp(argv[1], "dial") == 0) {
1
0
[commit] r11376 - freeswitch/trunk/src/mod/event_handlers/mod_erlang_event
by FreeSWITCH SVN 22 Jan '09
by FreeSWITCH SVN 22 Jan '09
22 Jan '09
Author: andrew
Date: Thu Jan 22 13:34:53 2009
New Revision: 11376
Log:
Merge in Rob Charlton's patch for outbound session support in mod_erlang_event
Added:
freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/ei_helpers.c
freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/handle_msg.c
freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h
Modified:
freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/Makefile
freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c
Modified: freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/Makefile
==============================================================================
--- freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/Makefile (original)
+++ freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/Makefile Thu Jan 22 13:34:53 2009
@@ -1,5 +1,8 @@
BASE=../../../..
+LOCAL_SOURCES=handle_msg.c ei_helpers.c
+LOCAL_OBJS=handle_msg.o ei_helpers.o
include $(BASE)/build/modmake.rules
-LOCAL_CFLAGS=-I/usr/local/lib/erlang/lib/erl_interface-3.5.8/include -L/usr/local/lib/erlang/lib/erl_interface-3.5.8/lib/ -D_REENTRANT
+
+LOCAL_CFLAGS=-I/usr/local/lib/erlang/lib/erl_interface-3.5.9/include -L/usr/local/lib/erlang/lib/erl_interface-3.5.9/lib/ -D_REENTRANT
LOCAL_LDFLAGS=-lei
Added: freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/ei_helpers.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/ei_helpers.c Thu Jan 22 13:34:53 2009
@@ -0,0 +1,183 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II <anthmct(a)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(a)yahoo.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Anthony Minessale II <anthmct(a)yahoo.com>
+ * Andrew Thompson <andrew(a)hijacked.us>
+ * Rob Charlton <rob.charlton(a)savageminds.com>
+ *
+ *
+ * ei_helpers.c -- helper functions for ei
+ *
+ */
+#include <switch.h>
+#include <ei.h>
+#include "mod_erlang_event.h"
+
+/* Stolen from code added to ei in R12B-5.
+ * Since not everyone has this version yet;
+ * provide our own version.
+ * */
+
+#define put8(s,n) do { \
+ (s)[0] = (char)((n) & 0xff); \
+ (s) += 1; \
+} while (0)
+
+#define put32be(s,n) do { \
+ (s)[0] = ((n) >> 24) & 0xff; \
+ (s)[1] = ((n) >> 16) & 0xff; \
+ (s)[2] = ((n) >> 8) & 0xff; \
+ (s)[3] = (n) & 0xff; \
+ (s) += 4; \
+} while (0)
+
+void ei_link(listener_t *listener, erlang_pid *from, erlang_pid *to) {
+ char msgbuf[2048];
+ char *s;
+ int index = 0;
+ /*int n;*/
+
+ index = 5; /* max sizes: */
+ ei_encode_version(msgbuf,&index); /* 1 */
+ ei_encode_tuple_header(msgbuf,&index,3);
+ ei_encode_long(msgbuf,&index,ERL_LINK);
+ ei_encode_pid(msgbuf,&index,from); /* 268 */
+ ei_encode_pid(msgbuf,&index,to); /* 268 */
+
+ /* 5 byte header missing */
+ s = msgbuf;
+ put32be(s, index - 4); /* 4 */
+ put8(s, ERL_PASS_THROUGH); /* 1 */
+ /* sum: 542 */
+
+ switch_mutex_lock(listener->sock_mutex);
+ write(listener->sockfd, msgbuf, index);
+ switch_mutex_unlock(listener->sock_mutex);
+}
+
+void ei_encode_switch_event_headers(ei_x_buff *ebuf, switch_event_t *event)
+{
+ int i;
+ char *uuid = switch_event_get_header(event, "unique-id");
+
+ switch_event_header_t *hp;
+
+ for (i = 0, hp = event->headers; hp; hp = hp->next, i++);
+
+ if (event->body)
+ i++;
+
+ ei_x_encode_list_header(ebuf, i+1);
+
+ if (uuid) {
+ ei_x_encode_string(ebuf, switch_event_get_header(event, "unique-id"));
+ } else {
+ ei_x_encode_atom(ebuf, "undefined");
+ }
+
+ for (hp = event->headers; hp; hp = hp->next) {
+ ei_x_encode_tuple_header(ebuf, 2);
+ ei_x_encode_string(ebuf, hp->name);
+ ei_x_encode_string(ebuf, hp->value);
+ }
+
+ if (event->body) {
+ ei_x_encode_tuple_header(ebuf, 2);
+ ei_x_encode_string(ebuf, "body");
+ ei_x_encode_string(ebuf, event->body);
+ }
+
+ ei_x_encode_empty_list(ebuf);
+}
+
+
+void ei_encode_switch_event_tag(ei_x_buff *ebuf, switch_event_t *event, char *tag)
+{
+
+ ei_x_encode_tuple_header(ebuf, 2);
+ ei_x_encode_atom(ebuf, tag);
+ ei_encode_switch_event_headers(ebuf, event);
+}
+
+
+switch_status_t initialise_ei(struct ei_cnode_s *ec)
+{
+ switch_status_t rv;
+ struct sockaddr_in server_addr;
+
+ /* zero out the struct before we use it */
+ memset(&server_addr, 0, sizeof(server_addr));
+
+ /* convert the configured IP to network byte order, handing errors */
+ rv = inet_pton(AF_INET, prefs.ip, &server_addr.sin_addr.s_addr);
+ if (rv == 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not parse invalid ip address: %s\n", prefs.ip);
+ return SWITCH_STATUS_FALSE;
+ } else if (rv == -1) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error when parsing ip address %s : %s\n", prefs.ip, strerror(errno));
+ return SWITCH_STATUS_FALSE;
+ }
+
+ /* set the address family and port */
+ server_addr.sin_family = AF_INET;
+ server_addr.sin_port = htons(prefs.port);
+
+ struct hostent *nodehost = gethostbyaddr(&server_addr.sin_addr.s_addr, sizeof(server_addr.sin_addr.s_addr), AF_INET);
+
+ char *thishostname = nodehost->h_name;
+ char thisnodename[MAXNODELEN+1];
+
+ if (!strcmp(thishostname, "localhost"))
+ gethostname(thishostname, EI_MAXHOSTNAMELEN);
+
+ if (prefs.shortname) {
+ char *off;
+ if ((off = strchr(thishostname, '.'))) {
+ *off = '\0';
+ }
+ }
+
+ snprintf(thisnodename, MAXNODELEN+1, "%s@%s", prefs.nodename, thishostname);
+
+ /* init the ei stuff */
+ if (ei_connect_xinit(ec, thishostname, prefs.nodename, thisnodename, (Erl_IpAddr)(&server_addr.sin_addr.s_addr), prefs.cookie, 0) < 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to init ei connection\n");
+ return SWITCH_STATUS_FALSE;
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ei initialized at %s\n", thisnodename);
+ return SWITCH_STATUS_SUCCESS;
+}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
Added: freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/handle_msg.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/handle_msg.c Thu Jan 22 13:34:53 2009
@@ -0,0 +1,713 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II <anthmct(a)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(a)yahoo.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Anthony Minessale II <anthmct(a)yahoo.com>
+ * Andrew Thompson <andrew(a)hijacked.us>
+ * Rob Charlton <rob.charlton(a)savageminds.com>
+ *
+ *
+ * handle_msg.c -- handle messages received from erlang nodes
+ *
+ */
+#include <switch.h>
+#include <ei.h>
+#include "mod_erlang_event.h"
+
+static char *MARKER = "1";
+
+static void *SWITCH_THREAD_FUNC api_exec(switch_thread_t *thread, void *obj)
+{
+ switch_bool_t r = SWITCH_TRUE;
+ struct api_command_struct *acs = (struct api_command_struct *) obj;
+ switch_stream_handle_t stream = { 0 };
+ char *reply, *freply = NULL;
+ switch_status_t status;
+
+ if (!acs) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Internal error.\n");
+ return NULL;
+ }
+
+ if (!acs->listener || !acs->listener->rwlock || switch_thread_rwlock_tryrdlock(acs->listener->rwlock) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error! cannot get read lock.\n");
+ goto done;
+ }
+
+ SWITCH_STANDARD_STREAM(stream);
+
+ if ((status = switch_api_execute(acs->api_cmd, acs->arg, NULL, &stream)) == SWITCH_STATUS_SUCCESS) {
+ reply = stream.data;
+ } else {
+ freply = switch_mprintf("%s: Command not found!\n", acs->api_cmd);
+ reply = freply;
+ r = SWITCH_FALSE;
+ }
+
+ if (!reply) {
+ reply = "Command returned no output!";
+ r = SWITCH_FALSE;
+ }
+
+ if (*reply == '-')
+ r = SWITCH_FALSE;
+
+ if (acs->bg) {
+ switch_event_t *event;
+
+ if (switch_event_create(&event, SWITCH_EVENT_BACKGROUND_JOB) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-UUID", acs->uuid_str);
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Command", acs->api_cmd);
+
+ ei_x_buff ebuf;
+ ei_x_new_with_version(&ebuf);
+
+ if (acs->arg) {
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Command-Arg", acs->arg);
+ }
+
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Successful", r ? "true" : "false");
+ switch_event_add_body(event, "%s", reply);
+
+ switch_event_fire(&event);
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending bgapi reply to %s\n", acs->pid.node);
+
+ ei_x_encode_tuple_header(&ebuf, 3);
+
+ if (r)
+ ei_x_encode_atom(&ebuf, "bgok");
+ else
+ ei_x_encode_atom(&ebuf, "bgerror");
+
+ ei_x_encode_string(&ebuf, acs->uuid_str);
+ ei_x_encode_string(&ebuf, reply);
+
+ switch_mutex_lock(acs->listener->sock_mutex);
+ ei_send(acs->listener->sockfd, &acs->pid, ebuf.buff, ebuf.index);
+ switch_mutex_unlock(acs->listener->sock_mutex);
+
+ ei_x_free(&ebuf);
+ }
+ } else {
+ ei_x_buff rbuf;
+ ei_x_new_with_version(&rbuf);
+ ei_x_encode_tuple_header(&rbuf, 2);
+
+ if (!strlen(reply)) {
+ reply = "Command returned no output!";
+ r = SWITCH_FALSE;
+ }
+
+ if (r) {
+ ei_x_encode_atom(&rbuf, "ok");
+ } else {
+ ei_x_encode_atom(&rbuf, "error");
+ }
+
+ ei_x_encode_string(&rbuf, reply);
+
+
+ switch_mutex_lock(acs->listener->sock_mutex);
+ ei_send(acs->listener->sockfd, &acs->pid, rbuf.buff, rbuf.index);
+ switch_mutex_unlock(acs->listener->sock_mutex);
+
+ ei_x_free(&rbuf);
+ }
+
+ switch_safe_free(stream.data);
+ switch_safe_free(freply);
+
+ if (acs->listener->rwlock) {
+ switch_thread_rwlock_unlock(acs->listener->rwlock);
+ }
+
+ done:
+ if (acs->bg) {
+ switch_memory_pool_t *pool = acs->pool;
+ acs = NULL;
+ switch_core_destroy_memory_pool(&pool);
+ pool = NULL;
+ }
+ return NULL;
+
+}
+
+static switch_status_t handle_msg_fetch_reply(listener_t *listener, ei_x_buff *buf, ei_x_buff *rbuf)
+{
+ char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
+
+ if (ei_decode_string(buf->buff, &buf->index, uuid_str)) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ else {
+ ei_x_buff *nbuf = switch_core_alloc(listener->pool, sizeof(nbuf));
+ nbuf->buff = switch_core_alloc(listener->pool, buf->buffsz);
+ memcpy(nbuf->buff, buf->buff, buf->buffsz);
+ nbuf->index = buf->index;
+ nbuf->buffsz = buf->buffsz;
+
+ switch_core_hash_insert(listener->fetch_reply_hash, uuid_str, nbuf);
+ ei_x_encode_atom(rbuf, "ok");
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t handle_msg_set_log_level(listener_t *listener, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
+{
+ switch_log_level_t ltype = SWITCH_LOG_DEBUG;
+ char loglevelstr[MAXATOMLEN];
+ if (arity != 2 ||
+ ei_decode_atom(buf->buff, &buf->index, loglevelstr)) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ else {
+ ltype = switch_log_str2level(loglevelstr);
+
+ if (ltype && ltype != SWITCH_LOG_INVALID) {
+ listener->level = ltype;
+ ei_x_encode_atom(rbuf, "ok");
+ } else {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t handle_msg_event(listener_t *listener, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
+{
+ char atom[MAXATOMLEN];
+
+ if (arity == 1) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ else {
+ int custom = 0;
+ switch_event_types_t type;
+
+ if (!switch_test_flag(listener, LFLAG_EVENTS)) {
+ switch_set_flag_locked(listener, LFLAG_EVENTS);
+ }
+
+ for (int i = 1; i < arity; i++) {
+ if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
+
+ if (custom) {
+ switch_core_hash_insert(listener->event_hash, atom, MARKER);
+ } else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) {
+ if (type == SWITCH_EVENT_ALL) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ALL events enabled\n");
+ uint32_t x = 0;
+ for (x = 0; x < SWITCH_EVENT_ALL; x++) {
+ listener->event_list[x] = 1;
+ }
+ }
+ if (type <= SWITCH_EVENT_ALL) {
+ listener->event_list[type] = 1;
+ }
+ if (type == SWITCH_EVENT_CUSTOM) {
+ custom++;
+ }
+
+ }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "enable event %s\n", atom);
+ }
+ }
+ ei_x_encode_atom(rbuf, "ok");
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t handle_msg_nixevent(listener_t *listener, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
+{
+ char atom[MAXATOMLEN];
+
+ if (arity == 1) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ else {
+ int custom = 0;
+ switch_event_types_t type;
+
+ for (int i = 1; i < arity; i++) {
+ if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
+
+ if (custom) {
+ switch_core_hash_delete(listener->event_hash, atom);
+ } else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) {
+ uint32_t x = 0;
+
+ if (type == SWITCH_EVENT_CUSTOM) {
+ custom++;
+ } else if (type == SWITCH_EVENT_ALL) {
+ for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
+ listener->event_list[x] = 0;
+ }
+ } else {
+ if (listener->event_list[SWITCH_EVENT_ALL]) {
+ listener->event_list[SWITCH_EVENT_ALL] = 0;
+ for (x = 0; x < SWITCH_EVENT_ALL; x++) {
+ listener->event_list[x] = 1;
+ }
+ }
+ listener->event_list[type] = 0;
+ }
+ }
+ }
+ }
+ ei_x_encode_atom(rbuf, "ok");
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t handle_msg_api(listener_t *listener, erlang_msg *msg, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
+{
+ char api_cmd[MAXATOMLEN];
+ char arg[1024];
+ if (arity < 3 ||
+ ei_decode_atom(buf->buff, &buf->index, api_cmd) ||
+ ei_decode_string(buf->buff, &buf->index, arg)) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ return SWITCH_STATUS_SUCCESS;
+ }
+ else {
+ struct api_command_struct acs = { 0 };
+ acs.listener = listener;
+ acs.api_cmd = api_cmd;
+ acs.arg = arg;
+ acs.bg = 0;
+ acs.pid = msg->from;
+ api_exec(NULL, (void *) &acs);
+ /* don't reply */
+ return SWITCH_STATUS_FALSE;
+ }
+}
+
+static switch_status_t handle_msg_bgapi(listener_t *listener, erlang_msg *msg, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
+{
+ char api_cmd[MAXATOMLEN];
+ char arg[1024];
+ if (arity < 3 ||
+ ei_decode_atom(buf->buff, &buf->index, api_cmd) ||
+ ei_decode_string(buf->buff, &buf->index, arg)) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ else {
+ struct api_command_struct *acs = NULL;
+ switch_memory_pool_t *pool;
+ switch_thread_t *thread;
+ switch_threadattr_t *thd_attr = NULL;
+ switch_uuid_t uuid;
+
+ switch_core_new_memory_pool(&pool);
+ acs = switch_core_alloc(pool, sizeof(*acs));
+ switch_assert(acs);
+ acs->pool = pool;
+ acs->listener = listener;
+ acs->api_cmd = switch_core_strdup(acs->pool, api_cmd);
+ acs->arg = switch_core_strdup(acs->pool, arg);
+ acs->bg = 1;
+ acs->pid = msg->from;
+
+ switch_threadattr_create(&thd_attr, acs->pool);
+ switch_threadattr_detach_set(thd_attr, 1);
+ switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+
+ switch_uuid_get(&uuid);
+ switch_uuid_format(acs->uuid_str, &uuid);
+ switch_thread_create(&thread, thd_attr, api_exec, acs, acs->pool);
+
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "ok");
+ ei_x_encode_string(rbuf, acs->uuid_str);
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t handle_msg_sendevent(listener_t *listener, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
+{
+ char ename[MAXATOMLEN];
+ int headerlength;
+
+ if (ei_decode_atom(buf->buff, &buf->index, ename) ||
+ ei_decode_list_header(buf->buff, &buf->index, &headerlength)) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ else {
+ switch_event_types_t etype;
+ if (switch_name_event(ename, &etype) == SWITCH_STATUS_SUCCESS) {
+ switch_event_t *event;
+ if (switch_event_create(&event, etype) == SWITCH_STATUS_SUCCESS) {
+ char key[1024];
+ char value[1024];
+ int i = 0;
+ switch_bool_t fail = SWITCH_FALSE;
+
+ while(!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
+ i++;
+ if (ei_decode_string(buf->buff, &buf->index, key) ||
+ ei_decode_string(buf->buff, &buf->index, value)) {
+ fail = SWITCH_TRUE;
+ break;
+ }
+
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, key, value);
+ }
+
+ if (headerlength != i || fail) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ else {
+ switch_event_fire(&event);
+ ei_x_encode_atom(rbuf, "ok");
+ }
+ }
+ }
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t handle_msg_sendmsg(listener_t *listener, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
+{
+ char uuid[37];
+ int headerlength;
+
+ if (ei_decode_string(buf->buff, &buf->index, uuid) ||
+ ei_decode_list_header(buf->buff, &buf->index, &headerlength)) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ else {
+ switch_core_session_t *session;
+ if (!switch_strlen_zero(uuid) && (session = switch_core_session_locate(uuid))) {
+ switch_event_t *event;
+ if (switch_event_create(&event, SWITCH_EVENT_SEND_MESSAGE) == SWITCH_STATUS_SUCCESS) {
+
+ char key[1024];
+ char value[1024];
+ int i = 0;
+ switch_bool_t fail = SWITCH_FALSE;
+ while(!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
+ i++;
+ if (ei_decode_string(buf->buff, &buf->index, key) ||
+ ei_decode_string(buf->buff, &buf->index, value)) {
+ fail = SWITCH_TRUE;
+ break;
+ }
+ switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, key, value);
+ }
+
+ if (headerlength != i || fail) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ else {
+ if (switch_core_session_queue_private_event(session, &event) == SWITCH_STATUS_SUCCESS) {
+ ei_x_encode_atom(rbuf, "ok");
+ } else {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badmem");
+ }
+
+ }
+ }
+ /* release the lock returned by switch_core_locate_session */
+ switch_core_session_rwunlock(session);
+
+ } else {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "nosession");
+ }
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t handle_msg_bind(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf)
+{
+ /* format is (result|config|directory|dialplan|phrases) */
+ char sectionstr[MAXATOMLEN];
+ switch_xml_section_t section;
+
+ if (ei_decode_atom(buf->buff, &buf->index, sectionstr) ||
+ !(section = switch_xml_parse_section_string(sectionstr))) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ else {
+ struct erlang_binding *binding, *ptr;
+
+ if (!(binding = switch_core_alloc(listener->pool, sizeof(*binding)))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n");
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badmem");
+ }
+ else {
+ binding->section = section;
+ binding->pid = msg->from;
+ binding->listener = listener;
+
+ switch_core_hash_init(&listener->fetch_reply_hash, listener->pool);
+
+ switch_mutex_lock(globals.listener_mutex);
+
+ for (ptr = bindings.head; ptr && ptr->next; ptr = ptr->next);
+
+ if (ptr) {
+ ptr->next = binding;
+ } else {
+ bindings.head = binding;
+ }
+
+ switch_xml_set_binding_sections(bindings.search_binding, switch_xml_get_binding_sections(bindings.search_binding) | section);
+ switch_mutex_unlock(globals.listener_mutex);
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sections %d\n", switch_xml_get_binding_sections(bindings.search_binding));
+
+ ei_link(listener, ei_self(listener->ec), &msg->from);
+ ei_x_encode_atom(rbuf, "ok");
+ }
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
+/* {handlecall,<uuid>,<handler process registered name>} */
+static switch_status_t handle_msg_handlecall(listener_t *listener, int arity, ei_x_buff *buf, ei_x_buff *rbuf)
+{
+ char reg_name[MAXATOMLEN];
+ char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
+
+ if (arity != 3 ||
+ ei_decode_string(buf->buff, &buf->index, uuid_str) ||
+ ei_decode_string(buf->buff, &buf->index, reg_name)) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ else {
+ switch_core_session_t *session;
+ if (!switch_strlen_zero(uuid_str) && (session = switch_core_session_locate(uuid_str))) {
+ /* create a new sesion list element and attach it to this listener */
+ if (attach_call_to_listener(listener,reg_name,session)) {
+ ei_x_encode_atom(rbuf, "ok");
+ }
+ else {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badsession");
+ }
+ }
+ else {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ }
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static switch_status_t handle_msg_tuple(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf)
+{
+ char tupletag[MAXATOMLEN];
+ int arity;
+ switch_status_t ret = SWITCH_STATUS_SUCCESS;
+
+ ei_decode_tuple_header(buf->buff, &buf->index, &arity);
+ if (ei_decode_atom(buf->buff, &buf->index, tupletag)) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ else {
+ if (!strncmp(tupletag, "fetch_reply", MAXATOMLEN)) {
+ ret = handle_msg_fetch_reply(listener,buf,rbuf);
+ } else if (!strncmp(tupletag, "set_log_level", MAXATOMLEN)) {
+ ret = handle_msg_set_log_level(listener,arity,buf,rbuf);
+ } else if (!strncmp(tupletag, "event", MAXATOMLEN)) {
+ ret = handle_msg_event(listener,arity,buf,rbuf);
+ } else if (!strncmp(tupletag, "nixevent", MAXATOMLEN)) {
+ ret = handle_msg_nixevent(listener,arity,buf,rbuf);
+ } else if (!strncmp(tupletag, "api", MAXATOMLEN)) {
+ ret = handle_msg_api(listener,msg,arity,buf,rbuf);
+ } else if (!strncmp(tupletag, "bgapi", MAXATOMLEN)) {
+ ret = handle_msg_bgapi(listener,msg,arity,buf,rbuf);
+ } else if (!strncmp(tupletag, "sendevent", MAXATOMLEN)) {
+ ret = handle_msg_sendevent(listener,arity,buf,rbuf);
+ } else if (!strncmp(tupletag, "sendmsg", MAXATOMLEN)) {
+ ret = handle_msg_sendmsg(listener,arity,buf,rbuf);
+ } else if (!strncmp(tupletag, "bind", MAXATOMLEN)) {
+ ret = handle_msg_bind(listener,msg,buf,rbuf);
+ } else if (!strncmp(tupletag, "handlecall", MAXATOMLEN)) {
+ ret = handle_msg_handlecall(listener,arity,buf,rbuf);
+ } else {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "undef");
+ }
+ }
+ return ret;
+}
+
+static switch_status_t handle_msg_atom(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf)
+{
+ char atom[MAXATOMLEN];
+ switch_status_t ret = SWITCH_STATUS_SUCCESS;
+
+ if (ei_decode_atom(buf->buff, &buf->index, atom)) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "badarg");
+ }
+ else if (!strncmp(atom, "nolog", MAXATOMLEN)) {
+ if (switch_test_flag(listener, LFLAG_LOG)) {
+ switch_clear_flag_locked(listener, LFLAG_LOG);
+ }
+ ei_x_encode_atom(rbuf, "ok");
+ } else if (!strncmp(atom, "register_log_handler", MAXATOMLEN)) {
+ ei_link(listener, ei_self(listener->ec), &msg->from);
+ listener->log_pid = msg->from;
+ listener->level = SWITCH_LOG_DEBUG;
+ switch_set_flag(listener, LFLAG_LOG);
+ ei_x_encode_atom(rbuf, "ok");
+ } else if (!strncmp(atom, "register_event_handler", MAXATOMLEN)) {
+ ei_link(listener, ei_self(listener->ec), &msg->from);
+ listener->event_pid = msg->from;
+ if (!switch_test_flag(listener, LFLAG_EVENTS)) {
+ switch_set_flag_locked(listener, LFLAG_EVENTS);
+ }
+ ei_x_encode_atom(rbuf, "ok");
+ } else if (!strncmp(atom, "noevents", MAXATOMLEN)) {
+ void *pop;
+ /*purge the event queue */
+ while (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS);
+
+ if (switch_test_flag(listener, LFLAG_EVENTS)) {
+ uint8_t x = 0;
+ switch_clear_flag_locked(listener, LFLAG_EVENTS);
+ for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
+ listener->event_list[x] = 0;
+ }
+ /* wipe the hash */
+ switch_core_hash_destroy(&listener->event_hash);
+ switch_core_hash_init(&listener->event_hash, listener->pool);
+ ei_x_encode_atom(rbuf, "ok");
+ } else {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "notlistening");
+ }
+ } else if (!strncmp(atom, "exit", MAXATOMLEN)) {
+ ei_x_encode_atom(rbuf, "ok");
+ ret = SWITCH_STATUS_TERM;
+ } else if (!strncmp(atom, "getpid", MAXATOMLEN)) {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "ok");
+ ei_x_encode_pid(rbuf, ei_self(listener->ec));
+ } else if (!strncmp(atom, "link", MAXATOMLEN)) {
+ /* debugging */
+ ei_link(listener, ei_self(listener->ec), &msg->from);
+ ret = SWITCH_STATUS_FALSE;
+ } else {
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "undef");
+ }
+
+ return ret;
+}
+
+int handle_msg(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf)
+{
+ int type, size, version;
+ switch_status_t ret = SWITCH_STATUS_SUCCESS;
+
+ buf->index = 0;
+ ei_decode_version(buf->buff, &buf->index, &version);
+ ei_get_type(buf->buff, &buf->index, &type, &size);
+
+ switch(type) {
+ case ERL_SMALL_TUPLE_EXT :
+ case ERL_LARGE_TUPLE_EXT :
+ ret = handle_msg_tuple(listener,msg,buf,rbuf);
+ break;
+
+ case ERL_ATOM_EXT :
+ ret = handle_msg_atom(listener,msg,buf,rbuf);
+ break;
+
+ default :
+ /* some other kind of erlang term */
+ ei_x_encode_tuple_header(rbuf, 2);
+ ei_x_encode_atom(rbuf, "error");
+ ei_x_encode_atom(rbuf, "undef");
+ break;
+ }
+
+ if (SWITCH_STATUS_FALSE==ret)
+ return 0;
+ else {
+ switch_mutex_lock(listener->sock_mutex);
+ ei_send(listener->sockfd, &msg->from, rbuf->buff, rbuf->index);
+ switch_mutex_unlock(listener->sock_mutex);
+
+ if (SWITCH_STATUS_SUCCESS==ret)
+ return 0;
+ else /* SWITCH_STATUS_TERM */
+ return 1;
+ }
+}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
Modified: freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c
==============================================================================
--- freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c (original)
+++ freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c Thu Jan 22 13:34:53 2009
@@ -25,101 +25,22 @@
*
* Anthony Minessale II <anthmct(a)yahoo.com>
* Andrew Thompson <andrew(a)hijacked.us>
+ * Rob Charlton <rob.charlton(a)savageminds.com>
*
*
* mod_erlang_event.c -- Erlang Event Handler derived from mod_event_socket
*
*/
#include <switch.h>
-
#include <ei.h>
+#define DEFINE_GLOBALS
+#include "mod_erlang_event.h"
SWITCH_MODULE_LOAD_FUNCTION(mod_erlang_event_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_erlang_event_shutdown);
SWITCH_MODULE_RUNTIME_FUNCTION(mod_erlang_event_runtime);
SWITCH_MODULE_DEFINITION(mod_erlang_event, mod_erlang_event_load, mod_erlang_event_shutdown, mod_erlang_event_runtime);
-static char *MARKER = "1";
-
-typedef enum {
- LFLAG_AUTHED = (1 << 0),
- LFLAG_RUNNING = (1 << 1),
- LFLAG_EVENTS = (1 << 2),
- LFLAG_LOG = (1 << 3),
- LFLAG_FULL = (1 << 4),
- LFLAG_MYEVENTS = (1 << 5),
- LFLAG_SESSION = (1 << 6),
- LFLAG_ASYNC = (1 << 7),
- LFLAG_STATEFUL = (1 << 8)
-} event_flag_t;
-
-struct listener {
- int sockfd;
- struct ei_cnode_s *ec;
- erlang_pid log_pid;
- erlang_pid event_pid;
- switch_queue_t *event_queue;
- switch_queue_t *log_queue;
- switch_memory_pool_t *pool;
- switch_mutex_t *flag_mutex;
- switch_mutex_t *sock_mutex;
- char *ebuf;
- uint32_t flags;
- switch_log_level_t level;
- uint8_t event_list[SWITCH_EVENT_ALL + 1];
- switch_hash_t *event_hash;
- switch_hash_t *fetch_reply_hash;
- switch_thread_rwlock_t *rwlock;
- switch_core_session_t *session;
- int lost_events;
- int lost_logs;
- time_t last_flush;
- uint32_t timeout;
- uint32_t id;
- char remote_ip[50];
- /*switch_port_t remote_port;*/
- struct listener *next;
-};
-
-typedef struct listener listener_t;
-
-static struct {
- int sockfd;
- switch_mutex_t *sock_mutex;
- listener_t *listeners;
- uint8_t ready;
-} listen_list;
-
-#define MAX_ACL 100
-
-struct erlang_binding {
- switch_xml_section_t section;
- erlang_pid pid;
- char *registered_process; /* TODO */
- listener_t *listener;
- struct erlang_binding *next;
-};
-
-static struct {
- struct erlang_binding *head;
- switch_xml_binding_t *search_binding;
-} bindings;
-
-static struct {
- switch_mutex_t *mutex;
- char *ip;
- char *nodename;
- switch_bool_t shortname;
- uint16_t port;
- char *cookie;
- int done;
- int threads;
- char *acl[MAX_ACL];
- uint32_t acl_count;
- uint32_t id;
-} prefs;
-
-
static void remove_listener(listener_t *listener);
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_pref_ip, prefs.ip);
@@ -129,12 +50,6 @@
static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj);
static void launch_listener_thread(listener_t *listener);
-static struct {
- switch_mutex_t *listener_mutex;
- switch_event_node_t *node;
-} globals;
-
-
static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_level_t level)
{
listener_t *l;
@@ -173,49 +88,6 @@
}
-/* Stolen from code added to ei in R12B-5.
- * Since not everyone has this verison yet;
- * provide our own version.
- * */
-
-#define put8(s,n) do { \
- (s)[0] = (char)((n) & 0xff); \
- (s) += 1; \
-} while (0)
-
-#define put32be(s,n) do { \
- (s)[0] = ((n) >> 24) & 0xff; \
- (s)[1] = ((n) >> 16) & 0xff; \
- (s)[2] = ((n) >> 8) & 0xff; \
- (s)[3] = (n) & 0xff; \
- (s) += 4; \
-} while (0)
-
-static void ei_link(listener_t *listener, erlang_pid *from, erlang_pid *to) {
- char msgbuf[2048];
- char *s;
- int index = 0;
- /*int n;*/
-
- index = 5; /* max sizes: */
- ei_encode_version(msgbuf,&index); /* 1 */
- ei_encode_tuple_header(msgbuf,&index,3);
- ei_encode_long(msgbuf,&index,ERL_LINK);
- ei_encode_pid(msgbuf,&index,from); /* 268 */
- ei_encode_pid(msgbuf,&index,to); /* 268 */
-
- /* 5 byte header missing */
- s = msgbuf;
- put32be(s, index - 4); /* 4 */
- put8(s, ERL_PASS_THROUGH); /* 1 */
- /* sum: 542 */
-
- switch_mutex_lock(listener->sock_mutex);
- write(listener->sockfd, msgbuf, index);
- switch_mutex_unlock(listener->sock_mutex);
-}
-
-
static void expire_listener(listener_t **listener)
{
void *pop;
@@ -268,54 +140,33 @@
}
-static void ei_encode_switch_event_headers(ei_x_buff *ebuf, switch_event_t *event)
+static void send_event_to_attached_sessions(listener_t* listener, switch_event_t *event)
{
- int i;
char *uuid = switch_event_get_header(event, "unique-id");
+ switch_event_t *clone = NULL;
+ session_elem_t* s;
- switch_event_header_t *hp;
-
- for (i = 0, hp = event->headers; hp; hp = hp->next, i++);
-
- if (event->body)
- i++;
-
- ei_x_encode_list_header(ebuf, i+1);
-
- if (uuid) {
- ei_x_encode_string(ebuf, switch_event_get_header(event, "unique-id"));
- } else {
- ei_x_encode_atom(ebuf, "undefined");
- }
-
- for (hp = event->headers; hp; hp = hp->next) {
- ei_x_encode_tuple_header(ebuf, 2);
- ei_x_encode_string(ebuf, hp->name);
- ei_x_encode_string(ebuf, hp->value);
- }
-
- if (event->body) {
- ei_x_encode_tuple_header(ebuf, 2);
- ei_x_encode_string(ebuf, "body");
- ei_x_encode_string(ebuf, event->body);
+ if (!uuid)
+ return;
+ switch_mutex_lock(listener->session_mutex);
+ for (s = listener->session_list; s; s = s->next) {
+ /* check the event uuid against the uuid of each session */
+ if (!strcmp(uuid, switch_core_session_get_uuid(s->session))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending event to attached session\n");
+ if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) {
+ /* add the event to the queue for this session */
+ if (switch_queue_trypush(s->event_queue, clone) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Lost event!\n");
+ switch_event_destroy(&clone);
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
+ }
+ }
}
-
- ei_x_encode_empty_list(ebuf);
-}
-
-
-static void ei_encode_switch_event_tag(ei_x_buff *ebuf, switch_event_t *event, char *tag)
-{
-
- ei_x_encode_tuple_header(ebuf, 2);
- ei_x_encode_atom(ebuf, tag);
- ei_encode_switch_event_headers(ebuf, event);
+ switch_mutex_unlock(listener->session_mutex);
}
-
-#define ei_encode_switch_event(_b, _e) ei_encode_switch_event_tag(_b, _e, "event")
-
-
static void event_handler(switch_event_t *event)
{
switch_event_t *clone = NULL;
@@ -335,7 +186,12 @@
l = lp;
lp = lp->next;
-
+
+ /* test all of the sessions attached to this event in case
+ one of them should receive it as well
+ */
+ send_event_to_attached_sessions(l,event);
+
if (!switch_test_flag(l, LFLAG_EVENTS)) {
continue;
}
@@ -355,13 +211,6 @@
}
}
- if (send && switch_test_flag(l, LFLAG_MYEVENTS)) {
- char *uuid = switch_event_get_header(event, "unique-id");
- if (!uuid || strcmp(uuid, switch_core_session_get_uuid(l->session))) {
- send = 0;
- }
- }
-
if (send) {
if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) {
if (switch_queue_trypush(l->event_queue, clone) == SWITCH_STATUS_SUCCESS) {
@@ -429,134 +278,27 @@
switch_mutex_unlock(globals.listener_mutex);
}
+/* Search for a listener already talking to the specified node */
+static listener_t * find_listener(char* nodename)
+{
+ listener_t *l = NULL;
-struct api_command_struct {
- char *api_cmd;
- char *arg;
- listener_t *listener;
- char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
- uint8_t bg;
- erlang_pid pid;
- switch_memory_pool_t *pool;
-};
-
-
-static void *SWITCH_THREAD_FUNC api_exec(switch_thread_t *thread, void *obj)
-{
- switch_bool_t r = SWITCH_TRUE;
- struct api_command_struct *acs = (struct api_command_struct *) obj;
- switch_stream_handle_t stream = { 0 };
- char *reply, *freply = NULL;
- switch_status_t status;
-
- if (!acs) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Internal error.\n");
- return NULL;
- }
-
- if (!acs->listener || !acs->listener->rwlock || switch_thread_rwlock_tryrdlock(acs->listener->rwlock) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error! cannot get read lock.\n");
- goto done;
- }
-
-
- SWITCH_STANDARD_STREAM(stream);
-
- if ((status = switch_api_execute(acs->api_cmd, acs->arg, NULL, &stream)) == SWITCH_STATUS_SUCCESS) {
- reply = stream.data;
- } else {
- freply = switch_mprintf("%s: Command not found!\n", acs->api_cmd);
- reply = freply;
- r = SWITCH_FALSE;
- }
-
- if (!reply) {
- reply = "Command returned no output!";
- r = SWITCH_FALSE;
- }
-
- if (*reply == '-')
- r = SWITCH_FALSE;
-
- if (acs->bg) {
- switch_event_t *event;
-
- if (switch_event_create(&event, SWITCH_EVENT_BACKGROUND_JOB) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-UUID", acs->uuid_str);
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Command", acs->api_cmd);
-
- ei_x_buff ebuf;
- ei_x_new_with_version(&ebuf);
-
- if (acs->arg) {
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Command-Arg", acs->arg);
- }
-
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Job-Successful", r ? "true" : "false");
- switch_event_add_body(event, "%s", reply);
-
- switch_event_fire(&event);
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending bgapi reply to %s\n", acs->pid.node);
-
- ei_x_encode_tuple_header(&ebuf, 3);
-
- if (r)
- ei_x_encode_atom(&ebuf, "bgok");
- else
- ei_x_encode_atom(&ebuf, "bgerror");
-
- ei_x_encode_string(&ebuf, acs->uuid_str);
- ei_x_encode_string(&ebuf, reply);
-
- switch_mutex_lock(acs->listener->sock_mutex);
- ei_send(acs->listener->sockfd, &acs->pid, ebuf.buff, ebuf.index);
- switch_mutex_unlock(acs->listener->sock_mutex);
-
- ei_x_free(&ebuf);
- }
- } else {
- ei_x_buff rbuf;
- ei_x_new_with_version(&rbuf);
- ei_x_encode_tuple_header(&rbuf, 2);
-
- if (!strlen(reply)) {
- reply = "Command returned no output!";
- r = SWITCH_FALSE;
- }
-
- if (r) {
- ei_x_encode_atom(&rbuf, "ok");
- } else {
- ei_x_encode_atom(&rbuf, "error");
+ switch_mutex_lock(globals.listener_mutex);
+ for (l = listen_list.listeners; l; l = l->next) {
+ if (!strncmp(nodename, l->peer_nodename, MAXNODELEN)) {
+ break;
}
-
- ei_x_encode_string(&rbuf, reply);
-
-
- switch_mutex_lock(acs->listener->sock_mutex);
- ei_send(acs->listener->sockfd, &acs->pid, rbuf.buff, rbuf.index);
- switch_mutex_unlock(acs->listener->sock_mutex);
-
- ei_x_free(&rbuf);
}
+ switch_mutex_unlock(globals.listener_mutex);
+ return l;
+}
- switch_safe_free(stream.data);
- switch_safe_free(freply);
-
- if (acs->listener->rwlock) {
- switch_thread_rwlock_unlock(acs->listener->rwlock);
- }
-
- done:
- if (acs->bg) {
- switch_memory_pool_t *pool = acs->pool;
- acs = NULL;
- switch_core_destroy_memory_pool(&pool);
- pool = NULL;
- }
- return NULL;
-
+static void add_session_elem_to_listener(listener_t *listener, session_elem_t *session_element)
+{
+ switch_mutex_lock(listener->session_mutex);
+ session_element->next = listener->session_list;
+ listener->session_list = session_element;
+ switch_mutex_unlock(listener->session_mutex);
}
static switch_xml_t erlang_fetch(const char *sectionstr, const char *tag_name, const char *key_name, const char *key_value,
@@ -650,571 +392,187 @@
}
-static int handle_msg(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf)
+static switch_status_t notify_new_session(listener_t *listener, switch_core_session_t *session, char* reg_name)
{
- int type, size, version, arity;
- char tupletag[MAXATOMLEN];
- char atom[MAXATOMLEN];
-
- buf->index = 0;
- ei_decode_version(buf->buff, &buf->index, &version);
- ei_get_type(buf->buff, &buf->index, &type, &size);
-
- switch(type) {
- case ERL_SMALL_TUPLE_EXT :
- case ERL_LARGE_TUPLE_EXT :
- ei_decode_tuple_header(buf->buff, &buf->index, &arity);
- if (ei_decode_atom(buf->buff, &buf->index, tupletag)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- if (!strncmp(tupletag, "fetch_reply", MAXATOMLEN)) {
- char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
-
- if (ei_decode_string(buf->buff, &buf->index, uuid_str)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- ei_x_buff *nbuf = switch_core_alloc(listener->pool, sizeof(nbuf));
- /*char *wtf = "hello world";*/
- nbuf->buff = switch_core_alloc(listener->pool, buf->buffsz);
- memcpy(nbuf->buff, buf->buff, buf->buffsz);
- /*memcpy(nbuf, wtf, 20);*/
- nbuf->index = buf->index;
- nbuf->buffsz = buf->buffsz;
-
- /*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "stored %d %d %s\n", buf->index, buf->buffsz, nbuf);*/
-
- switch_core_hash_insert(listener->fetch_reply_hash, uuid_str, nbuf);
-
- } else if (!strncmp(tupletag, "set_log_level", MAXATOMLEN)) {
- if (arity == 2) {
- switch_log_level_t ltype = SWITCH_LOG_DEBUG;
- char loglevelstr[MAXATOMLEN];
- if (ei_decode_atom(buf->buff, &buf->index, loglevelstr)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
- ltype = switch_log_str2level(loglevelstr);
-
- if (ltype && ltype != SWITCH_LOG_INVALID) {
- listener->level = ltype;
- } else {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
- } else {
- /* tuple too long */
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
- } else if (!strncmp(tupletag, "event", MAXATOMLEN)) {
- if (arity == 1) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- int custom = 0;
- switch_event_types_t type;
-
- if (!switch_test_flag(listener, LFLAG_EVENTS)) {
- switch_set_flag_locked(listener, LFLAG_EVENTS);
- }
-
- for (int i = 1; i < arity; i++) {
- if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
-
- if (custom) {
- switch_core_hash_insert(listener->event_hash, atom, MARKER);
- } else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) {
- if (type == SWITCH_EVENT_ALL) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "ALL events enabled\n");
- uint32_t x = 0;
- for (x = 0; x < SWITCH_EVENT_ALL; x++) {
- listener->event_list[x] = 1;
- }
- }
- if (type <= SWITCH_EVENT_ALL) {
- listener->event_list[type] = 1;
- }
- if (type == SWITCH_EVENT_CUSTOM) {
- custom++;
- }
-
- }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "enable event %s\n", atom);
- }
- }
- } else if (!strncmp(tupletag, "nixevent", MAXATOMLEN)) {
- if (arity == 1) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- int custom = 0;
- switch_event_types_t type;
+ switch_event_t *call_event=NULL;
+ switch_channel_t *channel=NULL;
- for (int i = 1; i < arity; i++) {
- if (!ei_decode_atom(buf->buff, &buf->index, atom)) {
-
- if (custom) {
- switch_core_hash_delete(listener->event_hash, atom);
- } else if (switch_name_event(atom, &type) == SWITCH_STATUS_SUCCESS) {
- uint32_t x = 0;
-
- if (type == SWITCH_EVENT_CUSTOM) {
- custom++;
- } else if (type == SWITCH_EVENT_ALL) {
- for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
- listener->event_list[x] = 0;
- }
- } else {
- if (listener->event_list[SWITCH_EVENT_ALL]) {
- listener->event_list[SWITCH_EVENT_ALL] = 0;
- for (x = 0; x < SWITCH_EVENT_ALL; x++) {
- listener->event_list[x] = 1;
- }
- }
- listener->event_list[type] = 0;
- }
- }
- }
- }
- } else if (!strncmp(tupletag, "api", MAXATOMLEN)) {
- if (arity < 3) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- char api_cmd[MAXATOMLEN];
- char arg[1024];
+ /* Send a message to the associated registered process to let it know there is a call.
+ Message is a tuple of the form {call, <call-event>}
+ */
+ channel = switch_core_session_get_channel(session);
+ if (switch_event_create(&call_event, SWITCH_EVENT_CHANNEL_DATA) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+ return SWITCH_STATUS_MEMERR;
+ }
+ switch_caller_profile_event_set_data(switch_channel_get_caller_profile(channel), "Channel", call_event);
+ switch_channel_event_set_data(channel, call_event);
+ switch_event_add_header_string(call_event, SWITCH_STACK_BOTTOM, "Content-Type", "command/reply");
+ switch_event_add_header_string(call_event, SWITCH_STACK_BOTTOM, "Reply-Text", "+OK\n");
- if (ei_decode_atom(buf->buff, &buf->index, api_cmd)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- if (ei_decode_string(buf->buff, &buf->index, arg)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
- struct api_command_struct acs = { 0 };
- acs.listener = listener;
- acs.api_cmd = api_cmd;
- acs.arg = arg;
- acs.bg = 0;
- acs.pid = msg->from;
- api_exec(NULL, (void *) &acs);
- goto noreply;
-
- } else if (!strncmp(tupletag, "bgapi", MAXATOMLEN)) {
- if (arity < 3) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- char api_cmd[MAXATOMLEN];
- char arg[1024];
-
- if (ei_decode_atom(buf->buff, &buf->index, api_cmd)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- if (ei_decode_string(buf->buff, &buf->index, arg)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- struct api_command_struct *acs = NULL;
- switch_memory_pool_t *pool;
- switch_thread_t *thread;
- switch_threadattr_t *thd_attr = NULL;
- switch_uuid_t uuid;
-
- switch_core_new_memory_pool(&pool);
- acs = switch_core_alloc(pool, sizeof(*acs));
- switch_assert(acs);
- acs->pool = pool;
- acs->listener = listener;
- acs->api_cmd = switch_core_strdup(acs->pool, api_cmd);
- acs->arg = switch_core_strdup(acs->pool, arg);
- acs->bg = 1;
- acs->pid = msg->from;
-
- switch_threadattr_create(&thd_attr, acs->pool);
- switch_threadattr_detach_set(thd_attr, 1);
- switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
-
- switch_uuid_get(&uuid);
- switch_uuid_format(acs->uuid_str, &uuid);
- switch_thread_create(&thread, thd_attr, api_exec, acs, acs->pool);
-
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "ok");
- ei_x_encode_string(rbuf, acs->uuid_str);
-
- break;
- } else if (!strncmp(tupletag, "sendevent", MAXATOMLEN)) {
- char ename[MAXATOMLEN];
-
- if (ei_decode_atom(buf->buff, &buf->index, ename)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- int headerlength;
-
- if (ei_decode_list_header(buf->buff, &buf->index, &headerlength)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- switch_event_types_t etype;
- if (switch_name_event(ename, &etype) == SWITCH_STATUS_SUCCESS) {
- switch_event_t *event;
-
- if (switch_event_create(&event, etype) == SWITCH_STATUS_SUCCESS) {
-
- char key[1024];
- char value[1024];
- int i = 0;
- while(!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
- i++;
- if (ei_decode_string(buf->buff, &buf->index, key))
- goto sendevent_fail;
- if (ei_decode_string(buf->buff, &buf->index, value))
- goto sendevent_fail;
-
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, key, value);
- }
-
- if (headerlength != i)
- goto sendevent_fail;
-
-
- switch_event_fire(&event);
- ei_x_encode_atom(rbuf, "ok");
- break;
+ ei_x_buff lbuf;
+ ei_x_new_with_version(&lbuf);
+ ei_x_encode_tuple_header(&lbuf, 2);
+ ei_x_encode_atom(&lbuf, "call");
+ ei_encode_switch_event(&lbuf, call_event);
+ switch_mutex_lock(listener->sock_mutex);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Sending initial call event\n");
+ if (ei_reg_send(listener->ec,listener->sockfd, reg_name, lbuf.buff, lbuf.index)==ERL_ERROR) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to send call event\n");
+ }
+ switch_mutex_unlock(listener->sock_mutex);
+
+ ei_x_free(&lbuf);
+ return SWITCH_STATUS_SUCCESS;
+}
-sendevent_fail:
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
- }
- } else if (!strncmp(tupletag, "sendmsg", MAXATOMLEN)) {
- char uuid[37];
+static switch_status_t check_attached_sessions(listener_t *listener)
+{
+ session_elem_t *last,*sp;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ void *pop;
+ /* check up on all the attached sessions -
+ if they have not yet sent an initial call event to the associated erlang process then do so
+ if they have pending events in their queues then send them
+ if the session has finished then clean it up
+ */
+ switch_mutex_lock(listener->session_mutex);
+ sp = listener->session_list;
+ last = NULL;
+ while(sp) {
+ if (!switch_test_flag(sp, LFLAG_OUTBOUND_INIT)) {
+ status = notify_new_session(listener, sp->session, sp->reg_name);
+ if (status != SWITCH_STATUS_SUCCESS)
+ break;
+ switch_set_flag(sp, LFLAG_OUTBOUND_INIT);
+ }
+ /* check event queue for this session */
+ if (switch_queue_trypop(sp->event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
+ switch_event_t *pevent = (switch_event_t *) pop;
- if (ei_decode_string(buf->buff, &buf->index, uuid)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- switch_core_session_t *session;
- if (!switch_strlen_zero(uuid) && (session = switch_core_session_locate(uuid))) {
- } else {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "nosession");
- break;
- }
-
- int headerlength;
-
- if (ei_decode_list_header(buf->buff, &buf->index, &headerlength)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- switch_event_t *event;
-
- if (switch_event_create(&event, SWITCH_EVENT_SEND_MESSAGE) == SWITCH_STATUS_SUCCESS) {
-
- char key[1024];
- char value[1024];
- int i = 0;
- while(!ei_decode_tuple_header(buf->buff, &buf->index, &arity) && arity == 2) {
- i++;
- if (ei_decode_string(buf->buff, &buf->index, key))
- goto sendmsg_fail;
- if (ei_decode_string(buf->buff, &buf->index, value))
- goto sendmsg_fail;
-
- switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, key, value);
- }
-
- if (headerlength != i)
- goto sendmsg_fail;
-
- if (switch_core_session_queue_private_event(session, &event) == SWITCH_STATUS_SUCCESS) {
- ei_x_encode_atom(rbuf, "ok");
- } else {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badmem");
- }
-
- /* release the lock returned by switch_core_locate_session */
- switch_core_session_rwunlock(session);
- break;
-
-sendmsg_fail:
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- } else if (!strncmp(tupletag, "bind", MAXATOMLEN)) {
-
- /* format is (result|config|directory|dialplan|phrases) */
- char sectionstr[MAXATOMLEN];
-
- if (ei_decode_atom(buf->buff, &buf->index, sectionstr)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- switch_xml_section_t section;
-
- if (!(section = switch_xml_parse_section_string(sectionstr))) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
-
- struct erlang_binding *binding, *ptr;
-
- if (!(binding = switch_core_alloc(listener->pool, sizeof(*binding)))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n");
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badmem");
- break;
- }
-
- binding->section = section;
- binding->pid = msg->from;
- binding->listener = listener;
-
- switch_core_hash_init(&listener->fetch_reply_hash, listener->pool);
-
- switch_mutex_lock(globals.listener_mutex);
-
- for (ptr = bindings.head; ptr && ptr->next; ptr = ptr->next);
-
- if (ptr) {
- ptr->next = binding;
- } else {
- bindings.head = binding;
- }
+ /* events from attached sessions are wrapped in a {call_event,<EVT>} tuple
+ to distinguish them from normal events (if they are sent to the same process)
+ */
+ ei_x_buff ebuf;
+ ei_x_new_with_version(&ebuf);
+ ei_x_encode_tuple_header(&ebuf, 2);
+ ei_x_encode_atom(&ebuf, "call_event");
+ ei_encode_switch_event(&ebuf, pevent);
- switch_xml_set_binding_sections(bindings.search_binding, switch_xml_get_binding_sections(bindings.search_binding) | section);
- switch_mutex_unlock(globals.listener_mutex);
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sections %d\n", switch_xml_get_binding_sections(bindings.search_binding));
-
- ei_link(listener, ei_self(listener->ec), &msg->from);
-
- } else {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "undef");
- break;
- }
-
- ei_x_encode_atom(rbuf, "ok");
- break;
- case ERL_ATOM_EXT :
- if (ei_decode_atom(buf->buff, &buf->index, atom)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "badarg");
- break;
- }
+ switch_mutex_lock(listener->sock_mutex);
+ ei_reg_send(listener->ec, listener->sockfd, sp->reg_name, ebuf.buff, ebuf.index);
+ switch_mutex_unlock(listener->sock_mutex);
+
+ /* event is a hangup, so this session can be removed */
+ if (pevent->event_id == SWITCH_EVENT_CHANNEL_HANGUP) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Hangup event for attached session\n");
+
+ /* remove session from list */
+ if (last)
+ last->next = sp->next;
+ else
+ listener->session_list = sp->next;
+
+ /* this allows the application threads to exit */
+ switch_clear_flag_locked(sp, LFLAG_SESSION_ALIVE);
- if (!strncmp(atom, "nolog", MAXATOMLEN)) {
- if (switch_test_flag(listener, LFLAG_LOG)) {
- switch_clear_flag_locked(listener, LFLAG_LOG);
- }
- } else if (!strncmp(atom, "register_log_handler", MAXATOMLEN)) {
- ei_link(listener, ei_self(listener->ec), &msg->from);
- listener->log_pid = msg->from;
- listener->level = SWITCH_LOG_DEBUG;
- switch_set_flag(listener, LFLAG_LOG);
- } else if (!strncmp(atom, "register_event_handler", MAXATOMLEN)) {
- ei_link(listener, ei_self(listener->ec), &msg->from);
- listener->event_pid = msg->from;
- if (!switch_test_flag(listener, LFLAG_EVENTS)) {
- switch_set_flag_locked(listener, LFLAG_EVENTS);
+ /* TODO
+ if this listener was created outbound, and the last session has been detached
+ should the listener also exit? Does it matter?
+ */
}
- } else if (!strncmp(atom, "noevents", MAXATOMLEN)) {
- void *pop;
- /*purge the event queue */
- while (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS);
-
- if (switch_test_flag(listener, LFLAG_EVENTS)) {
- uint8_t x = 0;
- switch_clear_flag_locked(listener, LFLAG_EVENTS);
- for (x = 0; x <= SWITCH_EVENT_ALL; x++) {
- listener->event_list[x] = 0;
- }
- /* wipe the hash */
- switch_core_hash_destroy(&listener->event_hash);
- switch_core_hash_init(&listener->event_hash, listener->pool);
- } else {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "notlistening");
- break;
- }
- } else if (!strncmp(atom, "exit", MAXATOMLEN)) {
- switch_clear_flag_locked(listener, LFLAG_RUNNING);
- ei_x_encode_atom(rbuf, "ok");
- goto event_done;
- } else if (!strncmp(atom, "getpid", MAXATOMLEN)) {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "ok");
- ei_x_encode_pid(rbuf, ei_self(listener->ec));
- } else if (!strncmp(atom, "link", MAXATOMLEN)) {
- /* debugging */
- ei_link(listener, ei_self(listener->ec), &msg->from);
- goto noreply;
- } else {
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "undef");
- break;
+
+ ei_x_free(&ebuf);
+ switch_event_destroy(&pevent);
}
-
- ei_x_encode_atom(rbuf, "ok");
- break;
- default :
- /* some other kind of erlang term */
- ei_x_encode_tuple_header(rbuf, 2);
- ei_x_encode_atom(rbuf, "error");
- ei_x_encode_atom(rbuf, "undef");
- break;
+ last = sp;
+ sp = sp->next;
}
-
-
- switch_mutex_lock(listener->sock_mutex);
- ei_send(listener->sockfd, &msg->from, rbuf->buff, rbuf->index);
- switch_mutex_unlock(listener->sock_mutex);
-noreply:
- return 0;
-
-event_done:
- switch_mutex_lock(listener->sock_mutex);
- ei_send(listener->sockfd, &msg->from, rbuf->buff, rbuf->index);
- switch_mutex_unlock(listener->sock_mutex);
- return 1;
+ switch_mutex_unlock(listener->session_mutex);
+ return status;
}
-
-static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
+static void check_log_queue(listener_t *listener)
{
- listener_t *listener = (listener_t *) obj;
- switch_core_session_t *session = NULL;
- switch_channel_t *channel = NULL;
- int status = 1;
void *pop;
- switch_mutex_lock(globals.listener_mutex);
- prefs.threads++;
- switch_mutex_unlock(globals.listener_mutex);
-
- switch_assert(listener != NULL);
-
- if (prefs.acl_count && !switch_strlen_zero(listener->remote_ip)) {
- uint32_t x = 0;
- for (x = 0; x < prefs.acl_count; x++) {
- if (!switch_check_network_list_ip(listener->remote_ip, prefs.acl[x])) {
- erlang_msg msg;
-
- ei_x_buff buf;
- ei_x_new(&buf);
-
- status = ei_xreceive_msg(listener->sockfd, &msg, &buf);
- /* get data off the socket, just so we can get the pid on the other end */
- if (status == ERL_MSG) {
- /* if we got a message, return an ACL error. */
- ei_x_buff rbuf;
- ei_x_new_with_version(&rbuf);
-
- ei_x_encode_tuple_header(&rbuf, 2);
- ei_x_encode_atom(&rbuf, "error");
- ei_x_encode_atom(&rbuf, "acldeny");
-
- ei_send(listener->sockfd, &msg.from, rbuf.buff, rbuf.index);
-
- ei_x_free(&rbuf);
- }
-
- ei_x_free(&buf);
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection from %s denied by acl %s\n", listener->remote_ip, prefs.acl[x]);
- goto done;
+ /* send out any pending crap in the log queue */
+ if (switch_test_flag(listener, LFLAG_LOG)) {
+ if (switch_queue_trypop(listener->log_queue, &pop) == SWITCH_STATUS_SUCCESS) {
+ switch_log_node_t *dnode = (switch_log_node_t *) pop;
+
+ if (dnode->data) {
+ ei_x_buff lbuf;
+ ei_x_new_with_version(&lbuf);
+ ei_x_encode_tuple_header(&lbuf, 2);
+ ei_x_encode_atom(&lbuf, "log");
+ ei_x_encode_list_header(&lbuf, 6);
+
+ ei_x_encode_tuple_header(&lbuf, 2);
+ ei_x_encode_atom(&lbuf, "level");
+ ei_x_encode_char(&lbuf, (unsigned char)dnode->level);
+
+ ei_x_encode_tuple_header(&lbuf, 2);
+ ei_x_encode_atom(&lbuf, "text_channel");
+ ei_x_encode_char(&lbuf, (unsigned char)dnode->level);
+
+ ei_x_encode_tuple_header(&lbuf, 2);
+ ei_x_encode_atom(&lbuf, "file");
+ ei_x_encode_string(&lbuf, dnode->file);
+
+ ei_x_encode_tuple_header(&lbuf, 2);
+ ei_x_encode_atom(&lbuf, "func");
+ ei_x_encode_string(&lbuf, dnode->func);
+
+ ei_x_encode_tuple_header(&lbuf, 2);
+ ei_x_encode_atom(&lbuf, "line");
+ ei_x_encode_ulong(&lbuf, (unsigned long)dnode->line);
+
+ ei_x_encode_tuple_header(&lbuf, 2);
+ ei_x_encode_atom(&lbuf, "data");
+ ei_x_encode_string(&lbuf, dnode->data);
+
+ ei_x_encode_empty_list(&lbuf);
+
+ switch_mutex_lock(listener->sock_mutex);
+ ei_send(listener->sockfd, &listener->log_pid, lbuf.buff, lbuf.index);
+ switch_mutex_unlock(listener->sock_mutex);
+
+ ei_x_free(&lbuf);
+ free(dnode->data);
+ free(dnode);
}
}
}
+}
- if ((session = listener->session)) {
- channel = switch_core_session_get_channel(session);
- if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
- goto done;
+static void check_event_queue(listener_t *listener)
+{
+ void* pop;
+ /* send out any pending crap in the event queue */
+ if (switch_test_flag(listener, LFLAG_EVENTS)) {
+ if (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
+
+ switch_event_t *pevent = (switch_event_t *) pop;
+
+ ei_x_buff ebuf;
+ ei_x_new_with_version(&ebuf);
+
+ ei_encode_switch_event(&ebuf, pevent);
+
+ switch_mutex_lock(listener->sock_mutex);
+ ei_send(listener->sockfd, &listener->event_pid, ebuf.buff, ebuf.index);
+ switch_mutex_unlock(listener->sock_mutex);
+
+ ei_x_free(&ebuf);
+ switch_event_destroy(&pevent);
}
}
+}
- if (switch_strlen_zero(listener->remote_ip)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Open\n");
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Open from %s\n", listener->remote_ip);/*, listener->remote_port);*/
- }
-
- switch_set_flag_locked(listener, LFLAG_RUNNING);
- add_listener(listener);
+static void listener_main_loop(listener_t *listener)
+{
+ int status = 1;
while ((status >= 0 || erl_errno == ETIMEDOUT || erl_errno == EAGAIN) && !prefs.done) {
erlang_msg msg;
@@ -1237,13 +595,13 @@
case ERL_SEND :
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "erl_send\n");*/
if (handle_msg(listener, &msg, &buf, &rbuf)) {
- goto done;
+ return;
}
break;
case ERL_REG_SEND :
/*switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "erl_reg_send\n");*/
if (handle_msg(listener, &msg, &buf, &rbuf)) {
- goto done;
+ return;
}
break;
case ERL_LINK :
@@ -1275,77 +633,76 @@
ei_x_free(&buf);
ei_x_free(&rbuf);
- /* send out any pending crap in the log queue */
- if (switch_test_flag(listener, LFLAG_LOG)) {
- if (switch_queue_trypop(listener->log_queue, &pop) == SWITCH_STATUS_SUCCESS) {
- switch_log_node_t *dnode = (switch_log_node_t *) pop;
-
- if (dnode->data) {
- ei_x_buff lbuf;
- ei_x_new_with_version(&lbuf);
- ei_x_encode_tuple_header(&lbuf, 2);
- ei_x_encode_atom(&lbuf, "log");
- ei_x_encode_list_header(&lbuf, 6);
-
- ei_x_encode_tuple_header(&lbuf, 2);
- ei_x_encode_atom(&lbuf, "level");
- ei_x_encode_char(&lbuf, (unsigned char)dnode->level);
-
- ei_x_encode_tuple_header(&lbuf, 2);
- ei_x_encode_atom(&lbuf, "text_channel");
- ei_x_encode_char(&lbuf, (unsigned char)dnode->level);
-
- ei_x_encode_tuple_header(&lbuf, 2);
- ei_x_encode_atom(&lbuf, "file");
- ei_x_encode_string(&lbuf, dnode->file);
-
- ei_x_encode_tuple_header(&lbuf, 2);
- ei_x_encode_atom(&lbuf, "func");
- ei_x_encode_string(&lbuf, dnode->func);
-
- ei_x_encode_tuple_header(&lbuf, 2);
- ei_x_encode_atom(&lbuf, "line");
- ei_x_encode_ulong(&lbuf, (unsigned long)dnode->line);
-
- ei_x_encode_tuple_header(&lbuf, 2);
- ei_x_encode_atom(&lbuf, "data");
- ei_x_encode_string(&lbuf, dnode->data);
-
- ei_x_encode_empty_list(&lbuf);
-
- switch_mutex_lock(listener->sock_mutex);
- ei_send(listener->sockfd, &listener->log_pid, lbuf.buff, lbuf.index);
- switch_mutex_unlock(listener->sock_mutex);
-
- ei_x_free(&lbuf);
- free(dnode->data);
- free(dnode);
- }
- }
+ check_log_queue(listener);
+ check_event_queue(listener);
+ if (SWITCH_STATUS_SUCCESS != check_attached_sessions(listener)) {
+ return;
}
+ }
+}
- /* ditto with the event queue */
- if (switch_test_flag(listener, LFLAG_EVENTS)) {
- if (switch_queue_trypop(listener->event_queue, &pop) == SWITCH_STATUS_SUCCESS) {
+static switch_bool_t check_inbound_acl(listener_t* listener)
+{
+ /* check acl to see if inbound connection is allowed */
+ if (prefs.acl_count && !switch_strlen_zero(listener->remote_ip)) {
+ uint32_t x = 0;
+ for (x = 0; x < prefs.acl_count; x++) {
+ if (!switch_check_network_list_ip(listener->remote_ip, prefs.acl[x])) {
+ int status = 1;
+ erlang_msg msg;
- switch_event_t *pevent = (switch_event_t *) pop;
+ ei_x_buff buf;
+ ei_x_new(&buf);
- ei_x_buff ebuf;
- ei_x_new_with_version(&ebuf);
+ status = ei_xreceive_msg(listener->sockfd, &msg, &buf);
+ /* get data off the socket, just so we can get the pid on the other end */
+ if (status == ERL_MSG) {
+ /* if we got a message, return an ACL error. */
+ ei_x_buff rbuf;
+ ei_x_new_with_version(&rbuf);
- ei_encode_switch_event(&ebuf, pevent);
+ ei_x_encode_tuple_header(&rbuf, 2);
+ ei_x_encode_atom(&rbuf, "error");
+ ei_x_encode_atom(&rbuf, "acldeny");
- switch_mutex_lock(listener->sock_mutex);
- ei_send(listener->sockfd, &listener->event_pid, ebuf.buff, ebuf.index);
- switch_mutex_unlock(listener->sock_mutex);
+ ei_send(listener->sockfd, &msg.from, rbuf.buff, rbuf.index);
+
+ ei_x_free(&rbuf);
+ }
+
+ ei_x_free(&buf);
- ei_x_free(&ebuf);
- switch_event_destroy(&pevent);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection from %s denied by acl %s\n", listener->remote_ip, prefs.acl[x]);
+ return SWITCH_FALSE;
}
}
}
+ return SWITCH_TRUE;
+}
-done:
+static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj)
+{
+ listener_t *listener = (listener_t *) obj;
+ session_elem_t* s;
+
+ switch_mutex_lock(globals.listener_mutex);
+ prefs.threads++;
+ switch_mutex_unlock(globals.listener_mutex);
+
+ switch_assert(listener != NULL);
+
+ if (check_inbound_acl(listener)) {
+ if (switch_strlen_zero(listener->remote_ip)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Open\n");
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Open from %s\n", listener->remote_ip);/*, listener->remote_port);*/
+ }
+
+ add_listener(listener);
+ listener_main_loop(listener);
+ }
+
+ /* clean up */
remove_listener(listener);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Session complete, waiting for children\n");
@@ -1364,16 +721,22 @@
/* remove any bindings for this connection */
remove_binding(listener, NULL);
- if (listener->session) {
- switch_channel_clear_flag(switch_core_session_get_channel(listener->session), CF_CONTROLLED);
- switch_clear_flag_locked(listener, LFLAG_SESSION);
- switch_core_session_rwunlock(listener->session);
- } else if (listener->pool) {
+ /* clean up all the attached sessions */
+ switch_mutex_lock(listener->session_mutex);
+ for (s = listener->session_list; s; s = s->next) {
+ switch_channel_clear_flag(switch_core_session_get_channel(s->session), CF_CONTROLLED);
+ /* this allows the application threads to exit */
+ switch_clear_flag_locked(s, LFLAG_SESSION_ALIVE);
+ /* */
+ switch_core_session_rwunlock(s->session);
+ }
+ switch_mutex_unlock(listener->session_mutex);
+
+ if (listener->pool) {
switch_memory_pool_t *pool = listener->pool;
switch_core_destroy_memory_pool(&pool);
}
-
switch_mutex_lock(globals.listener_mutex);
prefs.threads--;
switch_mutex_unlock(globals.listener_mutex);
@@ -1454,12 +817,148 @@
return 0;
}
+static listener_t* new_listener(struct ei_cnode_s *ec, int clientfd)
+{
+ switch_memory_pool_t *listener_pool = NULL;
+ listener_t* listener = NULL;
+
+ if (switch_core_new_memory_pool(&listener_pool) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "OH OH no pool\n");
+ return NULL;
+ }
+
+ if (!(listener = switch_core_alloc(listener_pool, sizeof(*listener)))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n");
+ return NULL;
+ }
+
+ switch_thread_rwlock_create(&listener->rwlock, listener_pool);
+ switch_queue_create(&listener->event_queue, SWITCH_CORE_QUEUE_LEN, listener_pool);
+ switch_queue_create(&listener->log_queue, SWITCH_CORE_QUEUE_LEN, listener_pool);
+
+ listener->ec = ec;
+ listener->sockfd = clientfd;
+ listener->pool = listener_pool;
+ listener_pool = NULL;
+ listener->level = SWITCH_LOG_DEBUG;
+ switch_mutex_init(&listener->flag_mutex, SWITCH_MUTEX_NESTED, listener->pool);
+ switch_mutex_init(&listener->sock_mutex, SWITCH_MUTEX_NESTED, listener->pool);
+ switch_mutex_init(&listener->session_mutex, SWITCH_MUTEX_NESTED, listener->pool);
+ switch_core_hash_init(&listener->event_hash, listener->pool);
+
+ return listener;
+}
+
+static listener_t* new_outbound_listener(char* node)
+{
+ listener_t* listener = NULL;
+ struct ei_cnode_s ec;
+ int clientfd;
+
+ if (SWITCH_STATUS_SUCCESS==initialise_ei(&ec)) {
+ errno = 0;
+ if ((clientfd=ei_connect(&ec,node)) == ERL_ERROR) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error connecting to node %s (erl_errno=%d, errno=%d)!\n",node,erl_errno,errno);
+ return NULL;
+ }
+ listener = new_listener(&ec,clientfd);
+ listener->peer_nodename = switch_core_strdup(listener->pool,node);
+ }
+ return listener;
+}
+
+session_elem_t* attach_call_to_listener(listener_t* listener, char* reg_name, switch_core_session_t *session)
+{
+ /* create a session list element */
+ session_elem_t* session_element=NULL;
+ if (!(session_element = switch_core_alloc(switch_core_session_get_pool(session), sizeof(*session_element)))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to allocate session element\n");
+ }
+ else {
+ if (SWITCH_STATUS_SUCCESS != switch_core_session_read_lock(session)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get session read lock\n");
+ }
+ else {
+ session_element->session = session;
+ session_element->reg_name = switch_core_strdup(switch_core_session_get_pool(session),reg_name);
+ switch_set_flag(session_element, LFLAG_SESSION_ALIVE);
+ switch_clear_flag(session_element, LFLAG_OUTBOUND_INIT);
+ switch_queue_create(&session_element->event_queue, SWITCH_CORE_QUEUE_LEN, switch_core_session_get_pool(session));
+ switch_mutex_init(&session_element->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
+ /* attach the session to the listener */
+ add_session_elem_to_listener(listener,session_element);
+ }
+ }
+ return session_element;
+}
/* Module Hooks */
+/* Entry point for outbound mode */
+SWITCH_STANDARD_APP(erlang_outbound_function)
+{
+ char *reg_name, *node;
+ listener_t *listener;
+ int argc = 0;
+ char *argv[80] = { 0 };
+ char *mydata;
+ switch_bool_t new_session = SWITCH_FALSE;
+ session_elem_t* session_element=NULL;
+
+ /* process app arguments */
+ if (data && (mydata = switch_core_session_strdup(session, data))) {
+ argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+ }
+ if (argc < 2) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error - need registered name and node!\n");
+ return;
+ }
+ reg_name = argv[0];
+ if (switch_strlen_zero(reg_name)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing registered name!\n");
+ return;
+ }
+ node = argv[1];
+ if (switch_strlen_zero(node)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing node name!\n");
+ return;
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "enter erlang_outbound_function %s %s\n",reg_name, node);
+
+ /* first work out if there is a listener already talking to the node we want to talk to */
+ listener = find_listener(node);
+ /* if there is no listener, then create one */
+ if (!listener) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Creating new listener for session\n");
+ new_session = SWITCH_TRUE;
+ listener = new_outbound_listener(node);
+ }
+ else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Using existing listener for session\n");
+ }
+ if (listener &&
+ (session_element=attach_call_to_listener(listener,reg_name,session)) != NULL) {
+
+ if (new_session)
+ launch_listener_thread(listener);
+ switch_ivr_park(session, NULL);
+
+ /* keep app thread running for lifetime of session */
+ if (switch_channel_get_state(switch_core_session_get_channel(session)) >= CS_HANGUP) {
+ while (switch_test_flag(session_element, LFLAG_SESSION_ALIVE)) {
+ switch_yield(100000);
+ }
+ }
+ }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "exit erlang_outbound_function\n");
+}
+
SWITCH_MODULE_LOAD_FUNCTION(mod_erlang_event_load)
{
+ switch_application_interface_t *app_interface;
+
switch_mutex_init(&globals.listener_mutex, SWITCH_MUTEX_NESTED, pool);
if (switch_event_bind_removable(modname, SWITCH_EVENT_ALL, SWITCH_EVENT_SUBCLASS_ANY, event_handler, NULL, &globals.node) != SWITCH_STATUS_SUCCESS) {
@@ -1483,6 +982,8 @@
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
+ SWITCH_ADD_APP(app_interface, "erlang", "Connect to an erlang node", "Connect to erlang", erlang_outbound_function, "<registered name> <node@host>", SAF_SUPPORT_NOMEDIA);
+
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
@@ -1557,25 +1058,7 @@
switch_yield(100000);
}
- struct hostent *nodehost = gethostbyaddr(&server_addr.sin_addr.s_addr, sizeof(server_addr.sin_addr.s_addr), AF_INET);
-
- char *thishostname = nodehost->h_name;
- char thisnodename[MAXNODELEN+1];
-
- if (!strcmp(thishostname, "localhost"))
- gethostname(thishostname, EI_MAXHOSTNAMELEN);
-
- if (prefs.shortname) {
- char *off;
- if ((off = strchr(thishostname, '.'))) {
- *off = '\0';
- }
- }
-
- snprintf(thisnodename, MAXNODELEN+1, "%s@%s", prefs.nodename, thishostname);
-
- /* init the ei stuff */
- if (ei_connect_xinit(&ec, thishostname, prefs.nodename, thisnodename, (Erl_IpAddr)(&server_addr.sin_addr.s_addr), prefs.cookie, 0) < 0) {
+ if (SWITCH_STATUS_SUCCESS!=initialise_ei(&ec)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to init ei connection\n");
close_socket(&listen_list.sockfd);
return SWITCH_STATUS_GENERR;
@@ -1596,7 +1079,7 @@
}
}
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connected and published erlang cnode at %s port %u\n", thisnodename, prefs.port);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connected and published erlang cnode\n");
listen_list.ready = 1;
@@ -1621,59 +1104,42 @@
break;
}
- if (switch_core_new_memory_pool(&listener_pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "OH OH no pool\n");
- goto fail;
- }
+ listener = new_listener(&ec,clientfd);
+ if (listener) {
+ /* store the IP and node name we are talking with */
+ inet_ntop(AF_INET, conn.ipadr, listener->remote_ip, sizeof(listener->remote_ip));
+ listener->peer_nodename = switch_core_strdup(listener->pool,conn.nodename);
- if (!(listener = switch_core_alloc(listener_pool, sizeof(*listener)))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n");
- break;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Launching listener, connection from node %s, ip %s\n", conn.nodename, listener->remote_ip);
+ launch_listener_thread(listener);
}
-
- switch_thread_rwlock_create(&listener->rwlock, listener_pool);
- switch_queue_create(&listener->event_queue, SWITCH_CORE_QUEUE_LEN, listener_pool);
- switch_queue_create(&listener->log_queue, SWITCH_CORE_QUEUE_LEN, listener_pool);
-
- inet_ntop(AF_INET, conn.ipadr, listener->remote_ip, sizeof(listener->remote_ip));
-
- listener->ec = &ec;
- listener->sockfd = clientfd;
- listener->pool = listener_pool;
- listener_pool = NULL;
- listener->level = SWITCH_LOG_DEBUG;
- switch_mutex_init(&listener->flag_mutex, SWITCH_MUTEX_NESTED, listener->pool);
- switch_mutex_init(&listener->sock_mutex, SWITCH_MUTEX_NESTED, listener->pool);
- switch_core_hash_init(&listener->event_hash, listener->pool);
-
- launch_listener_thread(listener);
-
+ else
+ /* if we fail to create a listener (memory error), then the module will exit */
+ break;
}
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Exiting module mod_erlang_event\n");
+
/* cleanup epmd registration */
ei_unpublish(&ec);
close(epmdfd);
close_socket(&listen_list.sockfd);
-
if (pool) {
switch_core_destroy_memory_pool(&pool);
}
-
if (listener_pool) {
switch_core_destroy_memory_pool(&listener_pool);
}
-
-
for (x = 0; x < prefs.acl_count; x++) {
switch_safe_free(prefs.acl[x]);
}
- fail:
prefs.done = 2;
return SWITCH_STATUS_TERM;
}
+
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_erlang_event_shutdown)
{
listener_t *l;
Added: freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h Thu Jan 22 13:34:53 2009
@@ -0,0 +1,190 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II <anthmct(a)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(a)yahoo.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Anthony Minessale II <anthmct(a)yahoo.com>
+ * Andrew Thompson <andrew(a)hijacked.us>
+ * Rob Charlton <rob.charlton(a)savageminds.com>
+ *
+ *
+ * mod_erlang_event.h -- Erlang Event Handler derived from mod_event_socket
+ *
+ */
+
+
+typedef enum {
+ LFLAG_OUTBOUND_INIT = (1 << 0), /* Erlang peer has been notified of this session */
+ LFLAG_SESSION_ALIVE
+} session_flag_t;
+
+struct session_elem {
+ switch_core_session_t *session;
+ switch_mutex_t *flag_mutex;
+ uint32_t flags;
+ /* registered process name that will receive call notifications from this session */
+ char* reg_name;
+ switch_queue_t *event_queue;
+ struct session_elem *next;
+};
+
+typedef struct session_elem session_elem_t;
+
+typedef enum {
+ LFLAG_RUNNING = (1 << 0),
+ LFLAG_EVENTS = (1 << 1),
+ LFLAG_LOG = (1 << 2),
+ LFLAG_MYEVENTS = (1 << 3),
+ LFLAG_STATEFUL = (1 << 4)
+} event_flag_t;
+
+/* There is one listener for each Erlang node we are attached to - either
+ inbound or outbound. For example, if the erlang node node1@server connects
+ to freeswitch then a listener is created and handles commands sent from
+ that node. If 5 calls are directed to the outbound erlang application
+ via the dialplan, and are also set to talk to node1@server, then those
+ 5 call sessions will be "attached" to the same listener.
+ */
+struct listener {
+ int sockfd;
+ struct ei_cnode_s *ec;
+ erlang_pid log_pid;
+ erlang_pid event_pid;
+ char *peer_nodename;
+ switch_queue_t *event_queue;
+ switch_queue_t *log_queue;
+ switch_memory_pool_t *pool;
+ switch_mutex_t *flag_mutex;
+ switch_mutex_t *sock_mutex;
+ char *ebuf;
+ uint32_t flags;
+ switch_log_level_t level;
+ uint8_t event_list[SWITCH_EVENT_ALL + 1];
+ switch_hash_t *event_hash;
+ switch_hash_t *fetch_reply_hash;
+ switch_thread_rwlock_t *rwlock;
+ switch_mutex_t *session_mutex;
+ session_elem_t *session_list;
+ int lost_events;
+ int lost_logs;
+ time_t last_flush;
+ uint32_t timeout;
+ uint32_t id;
+ char remote_ip[50];
+ /*switch_port_t remote_port;*/
+ struct listener *next;
+};
+
+typedef struct listener listener_t;
+
+struct erlang_binding {
+ switch_xml_section_t section;
+ erlang_pid pid;
+ char *registered_process; /* TODO */
+ listener_t *listener;
+ struct erlang_binding *next;
+};
+
+struct api_command_struct {
+ char *api_cmd;
+ char *arg;
+ listener_t *listener;
+ char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
+ uint8_t bg;
+ erlang_pid pid;
+ switch_memory_pool_t *pool;
+};
+
+struct globals_struct {
+ switch_mutex_t *listener_mutex;
+ switch_event_node_t *node;
+};
+typedef struct globals_struct globals_t;
+
+struct listen_list_struct {
+ int sockfd;
+ switch_mutex_t *sock_mutex;
+ listener_t *listeners;
+ uint8_t ready;
+};
+typedef struct listen_list_struct listen_list_t;
+
+struct bindings_struct {
+ struct erlang_binding *head;
+ switch_xml_binding_t *search_binding;
+};
+typedef struct bindings_struct bindings_t;
+
+#define MAX_ACL 100
+struct prefs_struct {
+ switch_mutex_t *mutex;
+ char *ip;
+ char *nodename;
+ switch_bool_t shortname;
+ uint16_t port;
+ char *cookie;
+ int done;
+ int threads;
+ char *acl[MAX_ACL];
+ uint32_t acl_count;
+ uint32_t id;
+};
+typedef struct prefs_struct prefs_t;
+
+/* shared globals */
+#ifdef DEFINE_GLOBALS
+globals_t globals;
+listen_list_t listen_list;
+bindings_t bindings;
+prefs_t prefs;
+#else
+extern globals_t globals;
+extern listen_list_t listen_list;
+extern bindings_t bindings;
+extern prefs_t prefs;
+#endif
+
+/* function prototypes */
+/* handle_msg.c */
+int handle_msg(listener_t *listener, erlang_msg *msg, ei_x_buff *buf, ei_x_buff *rbuf);
+
+/* ei_helpers.c */
+void ei_link(listener_t *listener, erlang_pid *from, erlang_pid *to);
+void ei_encode_switch_event_headers(ei_x_buff *ebuf, switch_event_t *event);
+void ei_encode_switch_event_tag(ei_x_buff *ebuf, switch_event_t *event, char *tag);
+switch_status_t initialise_ei(struct ei_cnode_s *ec);
+#define ei_encode_switch_event(_b, _e) ei_encode_switch_event_tag(_b, _e, "event")
+
+/* mod_erlang_event.c */
+session_elem_t* attach_call_to_listener(listener_t* listener, char* reg_name, switch_core_session_t *session);
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
1
0
Author: mikej
Date: Thu Jan 22 13:30:46 2009
New Revision: 11375
Log:
core: fix c leg no hangup when converting attended to blind transfer before b leg answers (MODENDP-165/r:11061)
Modified:
freeswitch/branches/1.0/src/switch_ivr_bridge.c
freeswitch/branches/1.0/src/switch_ivr_originate.c
Modified: freeswitch/branches/1.0/src/switch_ivr_bridge.c
==============================================================================
--- freeswitch/branches/1.0/src/switch_ivr_bridge.c (original)
+++ freeswitch/branches/1.0/src/switch_ivr_bridge.c Thu Jan 22 13:30:46 2009
@@ -829,8 +829,8 @@
switch_channel_set_variable(peer_channel, SWITCH_BRIDGE_VARIABLE, switch_core_session_get_uuid(session));
if (!switch_channel_media_ready(caller_channel) ||
- !(switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) {
- if ((status = switch_ivr_wait_for_answer(session, peer_session)) != SWITCH_STATUS_SUCCESS) {
+ (!switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) {
+ if ((status = switch_ivr_wait_for_answer(session, peer_session)) != SWITCH_STATUS_SUCCESS || !switch_channel_ready(caller_channel)) {
switch_channel_state_t w_state = switch_channel_get_state(caller_channel);
switch_channel_hangup(peer_channel, SWITCH_CAUSE_ALLOTTED_TIMEOUT);
if (w_state < CS_HANGUP && w_state != CS_ROUTING && w_state != CS_PARK &&
@@ -850,6 +850,7 @@
switch_core_session_rwunlock(peer_session);
goto done;
}
+
if (switch_channel_test_flag(peer_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
switch_channel_answer(caller_channel);
}
Modified: freeswitch/branches/1.0/src/switch_ivr_originate.c
==============================================================================
--- freeswitch/branches/1.0/src/switch_ivr_originate.c (original)
+++ freeswitch/branches/1.0/src/switch_ivr_originate.c Thu Jan 22 13:30:46 2009
@@ -330,7 +330,7 @@
}
if ((switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) {
- return SWITCH_STATUS_SUCCESS;
+ goto end;
}
switch_zmalloc(write_frame.data, SWITCH_RECOMMENDED_BUFFER_SIZE);
@@ -551,7 +551,9 @@
switch_safe_free(write_frame.data);
- return status;
+ end:
+
+ return (!caller_channel || switch_channel_ready(caller_channel)) ? status : SWITCH_STATUS_FALSE;
}
static void process_import(switch_core_session_t *session, switch_channel_t *peer_channel)
1
0
22 Jan '09
Author: anthm
Date: Thu Jan 22 13:06:48 2009
New Revision: 11369
Log:
fix domain param lookup
Modified:
freeswitch/trunk/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c
Modified: freeswitch/trunk/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c
==============================================================================
--- freeswitch/trunk/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c (original)
+++ freeswitch/trunk/src/mod/xml_int/mod_xml_rpc/mod_xml_rpc.c Thu Jan 22 13:06:48 2009
@@ -148,7 +148,7 @@
return ret ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS;
}
-static abyss_bool http_directory_auth(TSession * r, char *domain_name)
+static abyss_bool http_directory_auth(TSession *r, char *domain_name)
{
char *p;
char *x;
@@ -210,7 +210,7 @@
switch_event_create(¶ms, SWITCH_EVENT_REQUEST_PARAMS);
switch_assert(params);
switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "mailbox", "check");
-
+
if (switch_xml_locate_user("id", user, domain_name, NULL, &x_domain_root, &x_domain, &x_user, NULL, params) != SWITCH_STATUS_SUCCESS) {
switch_event_destroy(¶ms);
goto fail;
@@ -218,17 +218,20 @@
switch_event_destroy(¶ms);
box = switch_xml_attr_soft(x_user, "mailbox");
-
- for (x_param = switch_xml_child(x_domain, "param"); x_param; x_param = x_param->next) {
- const char *var = switch_xml_attr_soft(x_param, "name");
- const char *val = switch_xml_attr_soft(x_param, "value");
- if (!strcasecmp(var, "password")) {
- mypass1 = val;
- } else if (!strcasecmp(var, "vm-password")) {
- mypass2 = val;
- } else if (!strncasecmp(var, "http-", 5)) {
- ResponseAddField(r, (char *) var, (char *) val);
+ if ((x_params = switch_xml_child(x_domain, "params"))) {
+
+ for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
+ const char *var = switch_xml_attr_soft(x_param, "name");
+ const char *val = switch_xml_attr_soft(x_param, "value");
+
+ if (!strcasecmp(var, "password")) {
+ mypass1 = val;
+ } else if (!strcasecmp(var, "vm-password")) {
+ mypass2 = val;
+ } else if (!strncasecmp(var, "http-", 5)) {
+ ResponseAddField(r, (char *) var, (char *) val);
+ }
}
}
@@ -240,7 +243,7 @@
for (x_param = switch_xml_child(x_params, "param"); x_param; x_param = x_param->next) {
const char *var = switch_xml_attr_soft(x_param, "name");
const char *val = switch_xml_attr_soft(x_param, "value");
-
+
if (!strcasecmp(var, "password")) {
mypass1 = val;
} else if (!strcasecmp(var, "vm-password")) {
1
0
Author: brian
Date: Thu Jan 22 12:45:07 2009
New Revision: 11367
Log:
remove generated file from tree
Removed:
freeswitch/trunk/libs/libg722_1/src/dct4.h
1
0
Author: anthm
Date: Thu Jan 22 12:40:53 2009
New Revision: 11366
Log:
fix for fix that broke the other fix
Modified:
freeswitch/trunk/src/switch_core_io.c
Modified: freeswitch/trunk/src/switch_core_io.c
==============================================================================
--- freeswitch/trunk/src/switch_core_io.c (original)
+++ freeswitch/trunk/src/switch_core_io.c Thu Jan 22 12:40:53 2009
@@ -616,7 +616,7 @@
if ((session->write_codec && frame->codec && session->write_codec->implementation != frame->codec->implementation)) {
- if (session->write_impl.codec_id != frame->codec->implementation->codec_id) {
+ if (session->write_impl.microseconds_per_packet != frame->codec->implementation->microseconds_per_packet) {
ptime_mismatch = TRUE;
if (switch_test_flag(frame->codec, SWITCH_CODEC_FLAG_PASSTHROUGH) || switch_test_flag(session->read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH)) {
status = perform_write(session, frame, flags, stream_id);
1
0
[commit] r11365 - freeswitch/branches/1.0/src/mod/event_handlers/mod_event_socket
by FreeSWITCH SVN 22 Jan '09
by FreeSWITCH SVN 22 Jan '09
22 Jan '09
Author: mikej
Date: Thu Jan 22 12:30:12 2009
New Revision: 11365
Log:
mod_event_socket: add debug logging to event-sink (r:11060)
Modified:
freeswitch/branches/1.0/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
Modified: freeswitch/branches/1.0/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
==============================================================================
--- freeswitch/branches/1.0/src/mod/event_handlers/mod_event_socket/mod_event_socket.c (original)
+++ freeswitch/branches/1.0/src/mod/event_handlers/mod_event_socket/mod_event_socket.c Thu Jan 22 12:30:12 2009
@@ -778,6 +778,7 @@
stream->write_function(stream, " <reply type=\"success\">Listener %u Created</reply>\n", listener->id);
xmlize_listener(listener, stream);
stream->write_function(stream, "</data>\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Creating event-sink listener [%u]\n", listener->id);
goto end;
} else if (!strcasecmp(wcmd, "destroy-listener")) {
@@ -789,6 +790,7 @@
}
if ((listener = find_listener(idl))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Destroying event-sink listener [%u]\n", idl);
remove_listener(listener);
stream->write_function(stream, "<data>\n <reply type=\"success\">listener %u destroyed</reply>\n", listener->id);
xmlize_listener(listener, stream);
@@ -796,6 +798,7 @@
expire_listener(&listener);
goto end;
} else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Request to destroy unknown event-sink listener [%u]\n", idl);
stream->write_function(stream, "<data><reply type=\"error\">Can't find listener</reply></data>\n");
goto end;
}
1
0
[commit] r11364 - in freeswitch/trunk: libs/libg722_1/src src/mod/endpoints/mod_portaudio
by FreeSWITCH SVN 22 Jan '09
by FreeSWITCH SVN 22 Jan '09
22 Jan '09
Author: anthm
Date: Thu Jan 22 12:28:24 2009
New Revision: 11364
Log:
more pa bs
Modified:
freeswitch/trunk/libs/libg722_1/src/dct4.h
freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c
Modified: freeswitch/trunk/libs/libg722_1/src/dct4.h
==============================================================================
--- freeswitch/trunk/libs/libg722_1/src/dct4.h (original)
+++ freeswitch/trunk/libs/libg722_1/src/dct4.h Thu Jan 22 12:28:24 2009
@@ -3,34 +3,34 @@
5.572937315437795e-02f,
5.435713103213160e-02f,
5.164643594289910e-02f,
- 4.766403419605858e-02f,
- 4.250798573945089e-02f,
- 3.630524959802148e-02f,
+ 4.766403419605859e-02f,
+ 4.250798573945090e-02f,
+ 3.630524959802149e-02f,
2.920855772127337e-02f,
2.139265421578210e-02f,
1.304999256534943e-02f,
4.385996787515619e-03f,
5.435713103213160e-02f,
- 4.250798573945089e-02f,
+ 4.250798573945090e-02f,
2.139265421578210e-02f,
-4.385996787515612e-03f,
-2.920855772127336e-02f,
-4.766403419605858e-02f,
-5.572937315437795e-02f,
- -5.164643594289911e-02f,
+ -5.164643594289910e-02f,
-3.630524959802151e-02f,
-1.304999256534941e-02f,
5.164643594289910e-02f,
2.139265421578210e-02f,
-2.139265421578209e-02f,
-5.164643594289910e-02f,
- -5.164643594289911e-02f,
+ -5.164643594289910e-02f,
-2.139265421578213e-02f,
2.139265421578211e-02f,
5.164643594289909e-02f,
5.164643594289910e-02f,
- 2.139265421578213e-02f,
- 4.766403419605858e-02f,
+ 2.139265421578214e-02f,
+ 4.766403419605859e-02f,
-4.385996787515612e-03f,
-5.164643594289910e-02f,
-4.250798573945090e-02f,
@@ -40,17 +40,17 @@
-2.139265421578210e-02f,
-5.572937315437795e-02f,
-2.920855772127336e-02f,
- 4.250798573945089e-02f,
+ 4.250798573945090e-02f,
-2.920855772127336e-02f,
- -5.164643594289911e-02f,
+ -5.164643594289910e-02f,
1.304999256534939e-02f,
5.572937315437795e-02f,
4.385996787515657e-03f,
-5.435713103213161e-02f,
-2.139265421578214e-02f,
- 4.766403419605858e-02f,
+ 4.766403419605859e-02f,
3.630524959802153e-02f,
- 3.630524959802148e-02f,
+ 3.630524959802149e-02f,
-4.766403419605858e-02f,
-2.139265421578213e-02f,
5.435713103213161e-02f,
@@ -66,12 +66,12 @@
3.630524959802152e-02f,
-5.435713103213161e-02f,
1.304999256534937e-02f,
- 4.250798573945089e-02f,
+ 4.250798573945090e-02f,
-5.164643594289908e-02f,
- 4.385996787515504e-03f,
+ 4.385996787515503e-03f,
4.766403419605861e-02f,
2.139265421578210e-02f,
- -5.164643594289911e-02f,
+ -5.164643594289910e-02f,
5.164643594289909e-02f,
-2.139265421578210e-02f,
-2.139265421578214e-02f,
@@ -84,15 +84,15 @@
-3.630524959802151e-02f,
5.164643594289910e-02f,
-5.572937315437795e-02f,
- 4.766403419605858e-02f,
+ 4.766403419605859e-02f,
-2.920855772127332e-02f,
- 4.385996787515504e-03f,
+ 4.385996787515503e-03f,
2.139265421578216e-02f,
-4.250798573945092e-02f,
5.435713103213160e-02f,
4.385996787515619e-03f,
-1.304999256534941e-02f,
- 2.139265421578213e-02f,
+ 2.139265421578214e-02f,
-2.920855772127336e-02f,
3.630524959802153e-02f,
-4.250798573945090e-02f,
@@ -107,54 +107,54 @@
7.881323533747238e-02f,
7.687259191733195e-02f,
7.303909015868119e-02f,
- 6.740712359748102e-02f,
- 6.011536994189358e-02f,
- 5.134337636686234e-02f,
+ 6.740712359748104e-02f,
+ 6.011536994189359e-02f,
+ 5.134337636686236e-02f,
4.130713846678219e-02f,
3.025378172711701e-02f,
1.845547647478522e-02f,
6.202736141429415e-03f,
7.687259191733195e-02f,
- 6.011536994189358e-02f,
+ 6.011536994189359e-02f,
3.025378172711701e-02f,
- -6.202736141429404e-03f,
+ -6.202736141429406e-03f,
-4.130713846678218e-02f,
-6.740712359748102e-02f,
-7.881323533747238e-02f,
- -7.303909015868121e-02f,
+ -7.303909015868119e-02f,
-5.134337636686238e-02f,
- -1.845547647478519e-02f,
+ -1.845547647478520e-02f,
7.303909015868119e-02f,
3.025378172711701e-02f,
-3.025378172711701e-02f,
-7.303909015868119e-02f,
- -7.303909015868121e-02f,
+ -7.303909015868119e-02f,
-3.025378172711705e-02f,
3.025378172711703e-02f,
7.303909015868118e-02f,
7.303909015868119e-02f,
- 3.025378172711706e-02f,
- 6.740712359748102e-02f,
- -6.202736141429404e-03f,
+ 3.025378172711707e-02f,
+ 6.740712359748104e-02f,
+ -6.202736141429406e-03f,
-7.303909015868119e-02f,
-6.011536994189359e-02f,
1.845547647478516e-02f,
7.687259191733196e-02f,
5.134337636686239e-02f,
- -3.025378172711702e-02f,
+ -3.025378172711701e-02f,
-7.881323533747238e-02f,
-4.130713846678218e-02f,
- 6.011536994189358e-02f,
+ 6.011536994189359e-02f,
-4.130713846678218e-02f,
- -7.303909015868121e-02f,
+ -7.303909015868119e-02f,
1.845547647478516e-02f,
7.881323533747238e-02f,
6.202736141429469e-03f,
-7.687259191733196e-02f,
-3.025378172711707e-02f,
- 6.740712359748102e-02f,
+ 6.740712359748104e-02f,
5.134337636686240e-02f,
- 5.134337636686234e-02f,
+ 5.134337636686236e-02f,
-6.740712359748102e-02f,
-3.025378172711705e-02f,
7.687259191733196e-02f,
@@ -170,17 +170,17 @@
5.134337636686239e-02f,
-7.687259191733196e-02f,
1.845547647478515e-02f,
- 6.011536994189358e-02f,
- -7.303909015868118e-02f,
- 6.202736141429252e-03f,
+ 6.011536994189359e-02f,
+ -7.303909015868117e-02f,
+ 6.202736141429251e-03f,
6.740712359748108e-02f,
3.025378172711701e-02f,
- -7.303909015868121e-02f,
+ -7.303909015868119e-02f,
7.303909015868118e-02f,
- -3.025378172711702e-02f,
+ -3.025378172711701e-02f,
-3.025378172711707e-02f,
7.303909015868119e-02f,
- -7.303909015868118e-02f,
+ -7.303909015868117e-02f,
3.025378172711699e-02f,
3.025378172711710e-02f,
-7.303909015868128e-02f,
@@ -188,15 +188,15 @@
-5.134337636686238e-02f,
7.303909015868119e-02f,
-7.881323533747238e-02f,
- 6.740712359748102e-02f,
+ 6.740712359748104e-02f,
-4.130713846678212e-02f,
- 6.202736141429252e-03f,
+ 6.202736141429251e-03f,
3.025378172711710e-02f,
-6.011536994189360e-02f,
7.687259191733195e-02f,
6.202736141429415e-03f,
- -1.845547647478519e-02f,
- 3.025378172711706e-02f,
+ -1.845547647478520e-02f,
+ 3.025378172711707e-02f,
-4.130713846678218e-02f,
5.134337636686240e-02f,
-6.011536994189359e-02f,
@@ -211,8 +211,8 @@
{9.969173337331280e-01f, -7.845909572784494e-02f},
{9.723699203976766e-01f, -2.334453638559054e-01f},
{9.238795325112867e-01f, -3.826834323650898e-01f},
- {8.526401643540922e-01f, -5.224985647159488e-01f},
- {7.604059656000309e-01f, -6.494480483301837e-01f}
+ {8.526401643540923e-01f, -5.224985647159488e-01f},
+ {7.604059656000310e-01f, -6.494480483301837e-01f}
};
static const cos_msin_t cos_msin_10[10] =
@@ -222,8 +222,8 @@
{9.807852804032304e-01f, -1.950903220161282e-01f},
{9.624552364536473e-01f, -2.714404498650743e-01f},
{9.381913359224842e-01f, -3.461170570774930e-01f},
- {9.081431738250813e-01f, -4.186597375374281e-01f},
- {8.724960070727972e-01f, -4.886212414969549e-01f},
+ {9.081431738250814e-01f, -4.186597375374281e-01f},
+ {8.724960070727972e-01f, -4.886212414969550e-01f},
{8.314696123025452e-01f, -5.555702330196022e-01f},
{7.853169308807449e-01f, -6.190939493098340e-01f},
{7.343225094356856e-01f, -6.788007455329417e-01f}
@@ -241,7 +241,7 @@
{9.569403357322088e-01f, -2.902846772544623e-01f},
{9.448060464668780e-01f, -3.276301795616935e-01f},
{9.312149347588036e-01f, -3.644704998791496e-01f},
- {9.161879571171360e-01f, -4.007488331031410e-01f},
+ {9.161879571171359e-01f, -4.007488331031410e-01f},
{8.997482840522215e-01f, -4.364092406733421e-01f},
{8.819212643483550e-01f, -4.713967368259976e-01f},
{8.627343859777918e-01f, -5.056573733779846e-01f},
@@ -286,13 +286,13 @@
{8.474695394742344e-01f, -5.308440257395095e-01f},
{8.368837533084094e-01f, -5.473806568087964e-01f},
{8.259753325248732e-01f, -5.637062622150167e-01f},
- {8.147484825274894e-01f, -5.798145481265136e-01f},
+ {8.147484825274895e-01f, -5.798145481265136e-01f},
{8.032075314806449e-01f, -5.956993044924334e-01f},
- {7.913569286406602e-01f, -6.113544074368165e-01f},
+ {7.913569286406603e-01f, -6.113544074368165e-01f},
{7.792012426405167e-01f, -6.267738216194696e-01f},
- {7.667451597285615e-01f, -6.419516025627030e-01f},
+ {7.667451597285615e-01f, -6.419516025627031e-01f},
{7.539934819618694e-01f, -6.568818989430414e-01f},
- {7.409511253549591e-01f, -6.715589548470183e-01f},
+ {7.409511253549592e-01f, -6.715589548470183e-01f},
{7.276231179845748e-01f, -6.859771119901928e-01f},
{7.140145980512683e-01f, -7.001308118985236e-01f}
};
@@ -327,7 +327,7 @@
{9.688268450411880e-01f, -2.477388631755984e-01f},
{9.663480247352773e-01f, -2.572382069021397e-01f},
{9.637760657954398e-01f, -2.667127574748984e-01f},
- {9.611112161124317e-01f, -2.761616017169707e-01f},
+ {9.611112161124316e-01f, -2.761616017169707e-01f},
{9.583537325300114e-01f, -2.855838289290823e-01f},
{9.555038808201862e-01f, -2.949785309773635e-01f},
{9.525619356575953e-01f, -3.043448023808773e-01f},
@@ -339,11 +339,11 @@
{9.329927988347390e-01f, -3.598950365349881e-01f},
{9.294146324393044e-01f, -3.690371810640665e-01f},
{9.257468871271640e-01f, -3.781437570215405e-01f},
- {9.219899164032445e-01f, -3.872138866966656e-01f},
+ {9.219899164032446e-01f, -3.872138866966656e-01f},
{9.181440823722039e-01f, -3.962466958914656e-01f},
{9.142097557035307e-01f, -4.052413140049899e-01f},
{9.101873155958178e-01f, -4.141968741172237e-01f},
- {9.060771497402148e-01f, -4.231125130726441e-01f},
+ {9.060771497402147e-01f, -4.231125130726441e-01f},
{9.018796542830616e-01f, -4.319873715634118e-01f},
{8.975952337877069e-01f, -4.408205942121939e-01f},
{8.932243011955153e-01f, -4.496113296546065e-01f},
@@ -365,12 +365,12 @@
{8.118925199965048e-01f, -5.838069338177863e-01f},
{8.061219749505210e-01f, -5.917494076903429e-01f},
{8.002737341907743e-01f, -5.996348475233523e-01f},
- {7.943483613828813e-01f, -6.074624933017110e-01f},
+ {7.943483613828815e-01f, -6.074624933017110e-01f},
{7.883464276266063e-01f, -6.152315905806268e-01f},
{7.822685114008164e-01f, -6.229413905583340e-01f},
{7.761151985077279e-01f, -6.305911501482637e-01f},
- {7.698870820164444e-01f, -6.381801320506653e-01f},
- {7.635847622057965e-01f, -6.457076048236672e-01f},
+ {7.698870820164445e-01f, -6.381801320506653e-01f},
+ {7.635847622057965e-01f, -6.457076048236673e-01f},
{7.572088465064846e-01f, -6.531728429537768e-01f},
{7.507599494425343e-01f, -6.605751269258050e-01f},
{7.442386925720670e-01f, -6.679137432922161e-01f},
@@ -417,7 +417,7 @@
{9.880693132714919e-01f, -1.540098443970461e-01f},
{9.873014181578584e-01f, -1.588581433338614e-01f},
{9.865097333595187e-01f, -1.637026144779952e-01f},
- {9.856942779526452e-01f, -1.685431410986913e-01f},
+ {9.856942779526452e-01f, -1.685431410986914e-01f},
{9.848550715861784e-01f, -1.733796065602395e-01f},
{9.839921344813541e-01f, -1.782118943247859e-01f},
{9.831054874312163e-01f, -1.830398879551410e-01f},
@@ -490,17 +490,17 @@
{8.712941233961736e-01f, -4.907611950177941e-01f},
{8.688746174820854e-01f, -4.950322202598127e-01f},
{8.664341754558650e-01f, -4.992913173710469e-01f},
- {8.639728561215868e-01f, -5.035383837257176e-01f},
+ {8.639728561215867e-01f, -5.035383837257176e-01f},
{8.614907187863783e-01f, -5.077733169879345e-01f},
- {8.589878232589904e-01f, -5.119960151141624e-01f},
+ {8.589878232589903e-01f, -5.119960151141624e-01f},
{8.564642298483565e-01f, -5.162063763556797e-01f},
{8.539199993621391e-01f, -5.204042992610306e-01f},
{8.513551931052652e-01f, -5.245896826784689e-01f},
{8.487698728784481e-01f, -5.287624257583958e-01f},
- {8.461641009766995e-01f, -5.329224279557898e-01f},
+ {8.461641009766994e-01f, -5.329224279557898e-01f},
{8.435379401878270e-01f, -5.370695890326298e-01f},
{8.408914537909229e-01f, -5.412038090603096e-01f},
- {8.382247055548381e-01f, -5.453249884220465e-01f},
+ {8.382247055548380e-01f, -5.453249884220465e-01f},
{8.355377597366458e-01f, -5.494330278152808e-01f},
{8.328306810800937e-01f, -5.535278282540700e-01f},
{8.301035348140438e-01f, -5.576092910714722e-01f},
@@ -518,12 +518,12 @@
{7.958369046088836e-01f, -6.055110414043255e-01f},
{7.928550330615741e-01f, -6.094102858903271e-01f},
{7.898540571446090e-01f, -6.132948462299359e-01f},
- {7.868340491684999e-01f, -6.171646288220856e-01f},
+ {7.868340491685000e-01f, -6.171646288220856e-01f},
{7.837950819023488e-01f, -6.210195404217892e-01f},
{7.807372285720945e-01f, -6.248594881423863e-01f},
{7.776605628587479e-01f, -6.286843794577813e-01f},
{7.745651588966166e-01f, -6.324941222046724e-01f},
- {7.714510912715192e-01f, -6.362886245847729e-01f},
+ {7.714510912715193e-01f, -6.362886245847729e-01f},
{7.683184350189877e-01f, -6.400677951670226e-01f},
{7.651672656224590e-01f, -6.438315428897914e-01f},
{7.619976590114568e-01f, -6.475797770630733e-01f},
@@ -534,15 +534,15 @@
{7.458757562673048e-01f, -6.660850968252301e-01f},
{7.425971456384329e-01f, -6.697383662966099e-01f},
{7.393006416371488e-01f, -6.733754979763520e-01f},
- {7.359863236949099e-01f, -6.769964042253483e-01f},
+ {7.359863236949100e-01f, -6.769964042253483e-01f},
{7.326542716724128e-01f, -6.806009977954530e-01f},
{7.293045658576685e-01f, -6.841891918315852e-01f},
- {7.259372869640676e-01f, -6.877608998738217e-01f},
+ {7.259372869640677e-01f, -6.877608998738217e-01f},
{7.225525161284360e-01f, -6.913160358594803e-01f},
{7.191503349090794e-01f, -6.948545141251936e-01f},
{7.157308252838186e-01f, -6.983762494089729e-01f},
{7.122940696480137e-01f, -7.018811568522627e-01f},
- {7.088401508125785e-01f, -7.053691520019861e-01f}
+ {7.088401508125786e-01f, -7.053691520019861e-01f}
};
static const cos_msin_t cos_msin_320[320] =
@@ -562,17 +562,17 @@
{9.995294175010931e-01f, -3.067480317663663e-02f},
{9.994511197373437e-01f, -3.312792259967294e-02f},
{9.993668013545645e-01f, -3.558084246257342e-02f},
- {9.992764628606833e-01f, -3.803354798913168e-02f},
+ {9.992764628606832e-01f, -3.803354798913168e-02f},
{9.991801047998923e-01f, -4.048602440443251e-02f},
{9.990777277526454e-01f, -4.293825693494082e-02f},
{9.989693323356542e-01f, -4.539023080859068e-02f},
{9.988549192018848e-01f, -4.784193125487429e-02f},
{9.987344890405533e-01f, -5.029334350493095e-02f},
{9.986080425771219e-01f, -5.274445279163603e-02f},
- {9.984755805732948e-01f, -5.519524434968993e-02f},
+ {9.984755805732948e-01f, -5.519524434968994e-02f},
{9.983371038270131e-01f, -5.764570341570704e-02f},
{9.981926131724506e-01f, -6.009581522830464e-02f},
- {9.980421094800079e-01f, -6.254556502819182e-02f},
+ {9.980421094800079e-01f, -6.254556502819184e-02f},
{9.978855936563085e-01f, -6.499493805825848e-02f},
{9.977230666441916e-01f, -6.744391956366405e-02f},
{9.975545294227081e-01f, -6.989249479192657e-02f},
@@ -646,10 +646,10 @@
{9.720827077212779e-01f, -2.346384651954331e-01f},
{9.715038909862518e-01f, -2.370236059943672e-01f},
{9.709192219842182e-01f, -2.394073189807704e-01f},
- {9.703287042371799e-01f, -2.417895897953334e-01f},
+ {9.703287042371798e-01f, -2.417895897953334e-01f},
{9.697323413023714e-01f, -2.441704040874346e-01f},
{9.691301367722388e-01f, -2.465497475152259e-01f},
- {9.685220942744174e-01f, -2.489276057457201e-01f},
+ {9.685220942744173e-01f, -2.489276057457201e-01f},
{9.679082174717095e-01f, -2.513039644548766e-01f},
{9.672885100620635e-01f, -2.536788093276874e-01f},
{9.666629757785506e-01f, -2.560521260582643e-01f},
@@ -667,12 +667,12 @@
{9.587034748958716e-01f, -2.844075372112719e-01f},
{9.580025469007496e-01f, -2.867596905628075e-01f},
{9.572958479697103e-01f, -2.891101164953470e-01f},
- {9.565833823598556e-01f, -2.914588008500998e-01f},
+ {9.565833823598557e-01f, -2.914588008500998e-01f},
{9.558651543630251e-01f, -2.938057294787664e-01f},
- {9.551411683057708e-01f, -2.961508882436238e-01f},
+ {9.551411683057707e-01f, -2.961508882436238e-01f},
{9.544114285493304e-01f, -2.984942630176104e-01f},
{9.536759394896021e-01f, -3.008358396844112e-01f},
- {9.529347055571170e-01f, -3.031756041385431e-01f},
+ {9.529347055571171e-01f, -3.031756041385431e-01f},
{9.521877312170133e-01f, -3.055135422854393e-01f},
{9.514350209690083e-01f, -3.078496400415349e-01f},
{9.506765793473728e-01f, -3.101838833343510e-01f},
@@ -709,7 +709,7 @@
{9.243484599469451e-01f, -3.815493737299417e-01f},
{9.234092137297489e-01f, -3.838169146859046e-01f},
{9.224644049642953e-01f, -3.860821435573893e-01f},
- {9.215140393420420e-01f, -3.883450466988262e-01f},
+ {9.215140393420419e-01f, -3.883450466988262e-01f},
{9.205581225879205e-01f, -3.906056104786556e-01f},
{9.195966604603021e-01f, -3.928638212794095e-01f},
{9.186296587509630e-01f, -3.951196654977946e-01f},
@@ -728,12 +728,12 @@
{9.055572304297014e-01f, -4.242241181456904e-01f},
{9.045133013352465e-01f, -4.264454099971220e-01f},
{9.034639235201017e-01f, -4.286641329731982e-01f},
- {9.024091033056408e-01f, -4.308802737084970e-01f},
+ {9.024091033056407e-01f, -4.308802737084971e-01f},
{9.013488470460220e-01f, -4.330938188531520e-01f},
{9.002831611281501e-01f, -4.353047550729321e-01f},
{8.992120519716374e-01f, -4.375130690493225e-01f},
{8.981355260287659e-01f, -4.397187474796043e-01f},
- {8.970535897844474e-01f, -4.419217770769352e-01f},
+ {8.970535897844474e-01f, -4.419217770769353e-01f},
{8.959662497561852e-01f, -4.441221445704292e-01f},
{8.948735124940346e-01f, -4.463198367052365e-01f},
{8.937753845805634e-01f, -4.485148402426236e-01f},
@@ -745,12 +745,12 @@
{8.870737861323454e-01f, -4.616276616027529e-01f},
{8.859381106942048e-01f, -4.638034756441384e-01f},
{8.847970984309378e-01f, -4.659764957679662e-01f},
- {8.836507562159172e-01f, -4.681467088841250e-01f},
+ {8.836507562159173e-01f, -4.681467088841250e-01f},
{8.824990909546231e-01f, -4.703141019194129e-01f},
{8.813421095846011e-01f, -4.724786618176158e-01f},
{8.801798190754208e-01f, -4.746403755395864e-01f},
{8.790122264286335e-01f, -4.767992300633221e-01f},
- {8.778393386777302e-01f, -4.789552123840445e-01f},
+ {8.778393386777303e-01f, -4.789552123840445e-01f},
{8.766611628880995e-01f, -4.811083095142767e-01f},
{8.754777061569843e-01f, -4.832585084839222e-01f},
{8.742889756134398e-01f, -4.854057963403425e-01f},
@@ -770,15 +770,15 @@
{8.570970653106597e-01f, -5.151549481814718e-01f},
{8.558301045664012e-01f, -5.172570271324139e-01f},
{8.545579883654005e-01f, -5.193559901655896e-01f},
- {8.532807243707908e-01f, -5.214518246370019e-01f},
+ {8.532807243707907e-01f, -5.214518246370019e-01f},
{8.519983202767152e-01f, -5.235445179215000e-01f},
{8.507107838082801e-01f, -5.256340574128560e-01f},
{8.494181227215095e-01f, -5.277204305238395e-01f},
{8.481203448032972e-01f, -5.298036246862946e-01f},
{8.468174578713608e-01f, -5.318836273512150e-01f},
- {8.455094697741939e-01f, -5.339604259888194e-01f},
+ {8.455094697741938e-01f, -5.339604259888194e-01f},
{8.441963883910193e-01f, -5.360340080886280e-01f},
- {8.428782216317413e-01f, -5.381043611595366e-01f},
+ {8.428782216317414e-01f, -5.381043611595366e-01f},
{8.415549774368984e-01f, -5.401714727298929e-01f},
{8.402266637776148e-01f, -5.422353303475707e-01f},
{8.388932886555529e-01f, -5.442959215800456e-01f},
@@ -791,7 +791,7 @@
{8.294186203736174e-01f, -5.586275612405148e-01f},
{8.280450452577558e-01f, -5.606615761973360e-01f},
{8.266664820602777e-01f, -5.626922137706231e-01f},
- {8.252829390855451e-01f, -5.647194617279668e-01f},
+ {8.252829390855451e-01f, -5.647194617279667e-01f},
{8.238944246679176e-01f, -5.667433078573766e-01f},
{8.225009471717026e-01f, -5.687637399673542e-01f},
{8.211025149911046e-01f, -5.707807458869673e-01f},
@@ -800,14 +800,14 @@
{8.168775747324537e-01f, -5.768110851043212e-01f},
{8.154594083525400e-01f, -5.788142649670318e-01f},
{8.140363297059484e-01f, -5.808139580957645e-01f},
- {8.126083473651983e-01f, -5.828101524445172e-01f},
+ {8.126083473651982e-01f, -5.828101524445172e-01f},
{8.111754699323488e-01f, -5.848028359883638e-01f},
{8.097377060389469e-01f, -5.867919967235272e-01f},
- {8.082950643459751e-01f, -5.887776226674516e-01f},
+ {8.082950643459751e-01f, -5.887776226674515e-01f},
{8.068475535437993e-01f, -5.907597018588742e-01f},
- {8.053951823521167e-01f, -5.927382223578977e-01f},
+ {8.053951823521167e-01f, -5.927382223578979e-01f},
{8.039379595199031e-01f, -5.947131722460625e-01f},
- {8.024758938253601e-01f, -5.966845396264172e-01f},
+ {8.024758938253600e-01f, -5.966845396264172e-01f},
{8.010089940758625e-01f, -5.986523126235920e-01f},
{7.995372691079050e-01f, -6.006164793838690e-01f},
{7.980607277870492e-01f, -6.025770280752539e-01f},
@@ -823,11 +823,11 @@
{7.830323862678940e-01f, -6.219809338360844e-01f},
{7.815034584514979e-01f, -6.239009091421072e-01f},
{7.799698229165344e-01f, -6.258171261155689e-01f},
- {7.784314889015095e-01f, -6.277295732133219e-01f},
+ {7.784314889015094e-01f, -6.277295732133219e-01f},
{7.768884656732324e-01f, -6.296382389149270e-01f},
{7.753407625267603e-01f, -6.315431117227246e-01f},
{7.737883887853415e-01f, -6.334441801619028e-01f},
- {7.722313538003597e-01f, -6.353414327805670e-01f},
+ {7.722313538003597e-01f, -6.353414327805671e-01f},
{7.706696669512773e-01f, -6.372348581498091e-01f},
{7.691033376455797e-01f, -6.391244448637757e-01f},
{7.675323753187178e-01f, -6.410101815397373e-01f},
@@ -844,29 +844,29 @@
{7.499487366876190e-01f, -6.614959503584616e-01f},
{7.483229241734281e-01f, -6.633346072356920e-01f},
{7.466926038177344e-01f, -6.651692682347043e-01f},
- {7.450577854414661e-01f, -6.669999223036375e-01f},
+ {7.450577854414659e-01f, -6.669999223036375e-01f},
{7.434184788926470e-01f, -6.688265584147679e-01f},
- {7.417746940463380e-01f, -6.706491655645758e-01f},
+ {7.417746940463379e-01f, -6.706491655645758e-01f},
{7.401264408045760e-01f, -6.724677327738116e-01f},
- {7.384737290963160e-01f, -6.742822490875620e-01f},
- {7.368165688773699e-01f, -6.760927035753159e-01f},
- {7.351549701303474e-01f, -6.778990853310308e-01f},
- {7.334889428645953e-01f, -6.797013834731973e-01f},
+ {7.384737290963159e-01f, -6.742822490875620e-01f},
+ {7.368165688773698e-01f, -6.760927035753159e-01f},
+ {7.351549701303473e-01f, -6.778990853310308e-01f},
+ {7.334889428645954e-01f, -6.797013834731973e-01f},
{7.318184971161379e-01f, -6.814995871449060e-01f},
{7.301436429476156e-01f, -6.832936855139119e-01f},
{7.284643904482252e-01f, -6.850836677727004e-01f},
{7.267807497336585e-01f, -6.868695231385515e-01f},
{7.250927309460417e-01f, -6.886512408536060e-01f},
- {7.234003442538740e-01f, -6.904288101849290e-01f},
- {7.217035998519666e-01f, -6.922022204245754e-01f},
- {7.200025079613817e-01f, -6.939714608896540e-01f},
- {7.182970788293696e-01f, -6.957365209223924e-01f},
+ {7.234003442538739e-01f, -6.904288101849290e-01f},
+ {7.217035998519667e-01f, -6.922022204245754e-01f},
+ {7.200025079613817e-01f, -6.939714608896539e-01f},
+ {7.182970788293694e-01f, -6.957365209223924e-01f},
{7.165873227293083e-01f, -6.974973898902004e-01f},
{7.148732499606411e-01f, -6.992540571857347e-01f},
{7.131548708488146e-01f, -7.010065122269625e-01f},
{7.114321957452164e-01f, -7.027547444572253e-01f},
- {7.097052350271130e-01f, -7.044987433453024e-01f},
- {7.079739990975870e-01f, -7.062384983854745e-01f}
+ {7.097052350271131e-01f, -7.044987433453024e-01f},
+ {7.079739990975871e-01f, -7.062384983854745e-01f}
};
static const cos_msin_t cos_msin_640[640] =
@@ -941,7 +941,7 @@
{9.965711457905548e-01f, -8.274026454937569e-02f},
{9.964688578260101e-01f, -8.396317873286374e-02f},
{9.963650691973739e-01f, -8.518596646932200e-02f},
- {9.962597800609497e-01f, -8.640862591725426e-02f},
+ {9.962597800609497e-01f, -8.640862591725428e-02f},
{9.961529905753015e-01f, -8.763115523535747e-02f},
{9.960447009012520e-01f, -8.885355258252460e-02f},
{9.959349112018836e-01f, -9.007581611784729e-02f},
@@ -959,7 +959,7 @@
{9.945004952793278e-01f, -1.047318714106244e-01f},
{9.943712211188022e-01f, -1.059522279647869e-01f},
{9.942404494531879e-01f, -1.071724249568088e-01f},
- {9.941081804794248e-01f, -1.083924605490956e-01f},
+ {9.941081804794248e-01f, -1.083924605490957e-01f},
{9.939744143967076e-01f, -1.096123329042957e-01f},
{9.938391514064855e-01f, -1.108320401853034e-01f},
{9.937023917124622e-01f, -1.120515805552615e-01f},
@@ -979,14 +979,14 @@
{9.916307215336136e-01f, -1.291065920498434e-01f},
{9.914715372589731e-01f, -1.303234085087122e-01f},
{9.913108598461154e-01f, -1.315400287028831e-01f},
- {9.911486895370180e-01f, -1.327564508001479e-01f},
+ {9.911486895370178e-01f, -1.327564508001479e-01f},
{9.909850265759061e-01f, -1.339726729685971e-01f},
{9.908198712092535e-01f, -1.351886933766218e-01f},
{9.906532236857811e-01f, -1.364045101929175e-01f},
{9.904850842564571e-01f, -1.376201215864860e-01f},
{9.903154531744962e-01f, -1.388355257266385e-01f},
{9.901443306953601e-01f, -1.400507207829983e-01f},
- {9.899717170767560e-01f, -1.412657049255036e-01f},
+ {9.899717170767559e-01f, -1.412657049255036e-01f},
{9.897976125786367e-01f, -1.424804763244102e-01f},
{9.896220174632009e-01f, -1.436950331502945e-01f},
{9.894449319948911e-01f, -1.449093735740556e-01f},
@@ -1077,7 +1077,7 @@
{9.689786733147769e-01f, -2.471443518697825e-01f},
{9.686746520086348e-01f, -2.483332812088429e-01f},
{9.683691718959728e-01f, -2.495218365624697e-01f},
- {9.680622334368384e-01f, -2.507100161407201e-01f},
+ {9.680622334368385e-01f, -2.507100161407201e-01f},
{9.677538370934755e-01f, -2.518978181542170e-01f},
{9.674439833303232e-01f, -2.530852408141520e-01f},
{9.671326726140158e-01f, -2.542722823322882e-01f},
@@ -1101,7 +1101,7 @@
{9.612804858113206e-01f, -2.755718193109581e-01f},
{9.609415845594780e-01f, -2.767512801493782e-01f},
{9.606012361469752e-01f, -2.779303242053718e-01f},
- {9.602594410863711e-01f, -2.791089497033199e-01f},
+ {9.602594410863710e-01f, -2.791089497033199e-01f},
{9.599161998924024e-01f, -2.802871548682339e-01f},
{9.595715130819845e-01f, -2.814649379257579e-01f},
{9.592253811742094e-01f, -2.826422971021723e-01f},
@@ -1117,11 +1117,11 @@
{9.556846974971080e-01f, -2.943921856467341e-01f},
{9.553227044003364e-01f, -2.955647652498983e-01f},
{9.549592726048367e-01f, -2.967368997378675e-01f},
- {9.545944026579306e-01f, -2.979085873454284e-01f},
+ {9.545944026579306e-01f, -2.979085873454283e-01f},
{9.542280951091057e-01f, -2.990798263080405e-01f},
{9.538603505100144e-01f, -3.002506148618392e-01f},
{9.534911694144735e-01f, -3.014209512436381e-01f},
- {9.531205523784633e-01f, -3.025908336909318e-01f},
+ {9.531205523784632e-01f, -3.025908336909318e-01f},
{9.527484999601259e-01f, -3.037602604418984e-01f},
{9.523750127197659e-01f, -3.049292297354024e-01f},
{9.520000912198481e-01f, -3.060977398109971e-01f},
@@ -1156,29 +1156,29 @@
{9.405060705932683e-01f, -3.397768844068269e-01f},
{9.400883935350755e-01f, -3.409308028627527e-01f},
{9.396693007207513e-01f, -3.420842078830508e-01f},
- {9.392487927814420e-01f, -3.432370977307140e-01f},
+ {9.392487927814421e-01f, -3.432370977307140e-01f},
{9.388268703504251e-01f, -3.443894706695110e-01f},
{9.384035340631081e-01f, -3.455413249639891e-01f},
{9.379787845570278e-01f, -3.466926588794764e-01f},
- {9.375526224718491e-01f, -3.478434706820849e-01f},
+ {9.375526224718490e-01f, -3.478434706820849e-01f},
{9.371250484493645e-01f, -3.489937586387129e-01f},
{9.366960631334929e-01f, -3.501435210170474e-01f},
{9.362656671702783e-01f, -3.512927560855671e-01f},
{9.358338612078891e-01f, -3.524414621135448e-01f},
{9.354006458966176e-01f, -3.535896373710499e-01f},
{9.349660218888781e-01f, -3.547372801289512e-01f},
- {9.345299898392064e-01f, -3.558843886589194e-01f},
+ {9.345299898392063e-01f, -3.558843886589194e-01f},
{9.340925504042590e-01f, -3.570309612334300e-01f},
{9.336537042428116e-01f, -3.581769961257653e-01f},
{9.332134520157588e-01f, -3.593224916100174e-01f},
{9.327717943861125e-01f, -3.604674459610909e-01f},
{9.323287320190009e-01f, -3.616118574547051e-01f},
{9.318842655816681e-01f, -3.627557243673972e-01f},
- {9.314383957434725e-01f, -3.638990449765241e-01f},
+ {9.314383957434724e-01f, -3.638990449765241e-01f},
{9.309911231758859e-01f, -3.650418175602657e-01f},
{9.305424485524929e-01f, -3.661840403976272e-01f},
{9.300923725489892e-01f, -3.673257117684415e-01f},
- {9.296408958431813e-01f, -3.684668299533723e-01f},
+ {9.296408958431812e-01f, -3.684668299533723e-01f},
{9.291880191149847e-01f, -3.696073932339162e-01f},
{9.287337430464239e-01f, -3.707473998924054e-01f},
{9.282780683216301e-01f, -3.718868482120106e-01f},
@@ -1199,7 +1199,7 @@
{9.212755803477590e-01f, -3.889104074911081e-01f},
{9.207976218807237e-01f, -3.900406895937958e-01f},
{9.203182767091106e-01f, -3.911703843022539e-01f},
- {9.198375455548048e-01f, -3.922994899151824e-01f},
+ {9.198375455548049e-01f, -3.922994899151824e-01f},
{9.193554291417789e-01f, -3.934280047321689e-01f},
{9.188719281960914e-01f, -3.945559270536903e-01f},
{9.183870434458861e-01f, -3.956832551811160e-01f},
@@ -1217,8 +1217,8 @@
{9.124607575766490e-01f, -4.091642284983474e-01f},
{9.119579505754890e-01f, -4.102836779377824e-01f},
{9.114537701821365e-01f, -4.114025094974132e-01f},
- {9.109482171558779e-01f, -4.125207214922996e-01f},
- {9.104412922580672e-01f, -4.136383122384345e-01f},
+ {9.109482171558780e-01f, -4.125207214922996e-01f},
+ {9.104412922580672e-01f, -4.136383122384346e-01f},
{9.099329962521239e-01f, -4.147552800527466e-01f},
{9.094233299035327e-01f, -4.158716232531024e-01f},
{9.089122939798419e-01f, -4.169873401583093e-01f},
@@ -1252,23 +1252,23 @@
{8.940504215712870e-01f, -4.479663421376699e-01f},
{8.935000110874138e-01f, -4.490631694837502e-01f},
{8.929482550086714e-01f, -4.501593205488127e-01f},
- {8.923951541659944e-01f, -4.512547936820739e-01f},
+ {8.923951541659945e-01f, -4.512547936820739e-01f},
{8.918407093923427e-01f, -4.523495872337709e-01f},
{8.912849215227001e-01f, -4.534436995551644e-01f},
{8.907277913940732e-01f, -4.545371289985410e-01f},
- {8.901693198454897e-01f, -4.556298739172159e-01f},
+ {8.901693198454899e-01f, -4.556298739172159e-01f},
{8.896095077179980e-01f, -4.567219326655349e-01f},
{8.890483558546646e-01f, -4.578133035988772e-01f},
{8.884858651005743e-01f, -4.589039850736579e-01f},
{8.879220363028281e-01f, -4.599939754473306e-01f},
{8.873568703105417e-01f, -4.610832730783892e-01f},
- {8.867903679748451e-01f, -4.621718763263714e-01f},
+ {8.867903679748452e-01f, -4.621718763263714e-01f},
{8.862225301488806e-01f, -4.632597835518601e-01f},
{8.856533576878016e-01f, -4.643469931164871e-01f},
{8.850828514487716e-01f, -4.654335033829341e-01f},
{8.845110122909626e-01f, -4.665193127149364e-01f},
{8.839378410755541e-01f, -4.676044194772847e-01f},
- {8.833633386657316e-01f, -4.686888220358279e-01f},
+ {8.833633386657316e-01f, -4.686888220358280e-01f},
{8.827875059266853e-01f, -4.697725187574754e-01f},
{8.822103437256089e-01f, -4.708555080101994e-01f},
{8.816318529316984e-01f, -4.719377881630376e-01f},
@@ -1279,11 +1279,11 @@
{8.787195006314716e-01f, -4.773384954201548e-01f},
{8.781330566456232e-01f, -4.784164867834454e-01f},
{8.775452902072614e-01f, -4.794937576601530e-01f},
- {8.769562022015515e-01f, -4.805703064279270e-01f},
+ {8.769562022015513e-01f, -4.805703064279270e-01f},
{8.763657935156495e-01f, -4.816461314655044e-01f},
- {8.757740650387004e-01f, -4.827212311527123e-01f},
+ {8.757740650387003e-01f, -4.827212311527123e-01f},
{8.751810176618363e-01f, -4.837956038704698e-01f},
- {8.745866522781761e-01f, -4.848692480007911e-01f},
+ {8.745866522781762e-01f, -4.848692480007911e-01f},
{8.739909697828232e-01f, -4.859421619267875e-01f},
{8.733939710728648e-01f, -4.870143440326701e-01f},
{8.727956570473698e-01f, -4.880857927037520e-01f},
@@ -1297,13 +1297,13 @@
{8.679619020254642e-01f, -4.966307850227757e-01f},
{8.673517909446490e-01f, -4.976955603027919e-01f},
{8.667403736477115e-01f, -4.987595860622885e-01f},
- {8.661276510554351e-01f, -4.998228606988624e-01f},
+ {8.661276510554352e-01f, -4.998228606988624e-01f},
{8.655136240905691e-01f, -5.008853826112407e-01f},
{8.648982936778269e-01f, -5.019471501992850e-01f},
{8.642816607438848e-01f, -5.030081618639924e-01f},
- {8.636637262173812e-01f, -5.040684160074983e-01f},
+ {8.636637262173812e-01f, -5.040684160074984e-01f},
{8.630444910289141e-01f, -5.051279110330795e-01f},
- {8.624239561110406e-01f, -5.061866453451552e-01f},
+ {8.624239561110405e-01f, -5.061866453451552e-01f},
{8.618021223982749e-01f, -5.072446173492910e-01f},
{8.611789908270876e-01f, -5.083018254522002e-01f},
{8.605545623359034e-01f, -5.093582680617462e-01f},
@@ -1322,8 +1322,8 @@
{8.523194027626210e-01f, -5.230216397763758e-01f},
{8.516769170172609e-01f, -5.240671989544601e-01f},
{8.510331486618554e-01f, -5.251119688968137e-01f},
- {8.503880986659081e-01f, -5.261559480300321e-01f},
- {8.497417680008525e-01f, -5.271991347819013e-01f},
+ {8.503880986659080e-01f, -5.261559480300321e-01f},
+ {8.497417680008525e-01f, -5.271991347819014e-01f},
{8.490941576400509e-01f, -5.282415275814013e-01f},
{8.484452685587929e-01f, -5.292831248587072e-01f},
{8.477951017342936e-01f, -5.303239250451923e-01f},
@@ -1342,7 +1342,7 @@
{8.392271065094661e-01f, -5.437810806747042e-01f},
{8.385591549620770e-01f, -5.448105575604123e-01f},
{8.378899405597550e-01f, -5.458392139712668e-01f},
- {8.372194643103249e-01f, -5.468670483581293e-01f},
+ {8.372194643103250e-01f, -5.468670483581293e-01f},
{8.365477272235120e-01f, -5.478940591731002e-01f},
{8.358747303109401e-01f, -5.489202448695194e-01f},
{8.352004745861303e-01f, -5.499456039019702e-01f},
@@ -1367,37 +1367,37 @@
{8.221518032996592e-01f, -5.692683131275782e-01f},
{8.214525870777344e-01f, -5.702768162772331e-01f},
{8.207521337630588e-01f, -5.712844606003090e-01f},
- {8.200504444105025e-01f, -5.722912445793115e-01f},
- {8.193475200767969e-01f, -5.732971666980422e-01f},
+ {8.200504444105026e-01f, -5.722912445793115e-01f},
+ {8.193475200767970e-01f, -5.732971666980422e-01f},
{8.186433618205335e-01f, -5.743022254416005e-01f},
{8.179379707021619e-01f, -5.753064192963863e-01f},
- {8.172313477839882e-01f, -5.763097467501014e-01f},
+ {8.172313477839883e-01f, -5.763097467501014e-01f},
{8.165234941301740e-01f, -5.773122062917532e-01f},
{8.158144108067338e-01f, -5.783137964116556e-01f},
- {8.151040988815345e-01f, -5.793145156014319e-01f},
+ {8.151040988815346e-01f, -5.793145156014319e-01f},
{8.143925594242929e-01f, -5.803143623540171e-01f},
{8.136797935065747e-01f, -5.813133351636602e-01f},
- {8.129658022017924e-01f, -5.823114325259262e-01f},
+ {8.129658022017923e-01f, -5.823114325259262e-01f},
{8.122505865852039e-01f, -5.833086529376983e-01f},
- {8.115341477339112e-01f, -5.843049948971807e-01f},
- {8.108164867268581e-01f, -5.853004569039005e-01f},
+ {8.115341477339113e-01f, -5.843049948971807e-01f},
+ {8.108164867268581e-01f, -5.853004569039004e-01f},
{8.100976046448293e-01f, -5.862950374587097e-01f},
{8.093775025704479e-01f, -5.872887350637883e-01f},
{8.086561815881750e-01f, -5.882815482226452e-01f},
{8.079336427843067e-01f, -5.892734754401222e-01f},
- {8.072098872469734e-01f, -5.902645152223945e-01f},
+ {8.072098872469735e-01f, -5.902645152223945e-01f},
{8.064849160661379e-01f, -5.912546660769743e-01f},
{8.057587303335938e-01f, -5.922439265127122e-01f},
{8.050313311429637e-01f, -5.932322950397998e-01f},
{8.043027195896973e-01f, -5.942197701697721e-01f},
{8.035728967710708e-01f, -5.952063504155093e-01f},
{8.028418637861839e-01f, -5.961920342912395e-01f},
- {8.021096217359593e-01f, -5.971768203125404e-01f},
- {8.013761717231402e-01f, -5.981607069963423e-01f},
+ {8.021096217359593e-01f, -5.971768203125405e-01f},
+ {8.013761717231402e-01f, -5.981607069963424e-01f},
{8.006415148522891e-01f, -5.991436928609294e-01f},
{7.999056522297859e-01f, -6.001257764259429e-01f},
{7.991685849638264e-01f, -6.011069562123827e-01f},
- {7.984303141644207e-01f, -6.020872307426096e-01f},
+ {7.984303141644207e-01f, -6.020872307426097e-01f},
{7.976908409433912e-01f, -6.030665985403482e-01f},
{7.969501664143711e-01f, -6.040450581306880e-01f},
{7.962082916928030e-01f, -6.050226080400867e-01f},
@@ -1426,30 +1426,30 @@
{7.788165123814760e-01f, -6.272518154951441e-01f},
{7.780461723455767e-01f, -6.282070945941292e-01f},
{7.772746605862029e-01f, -6.291614276245828e-01f},
- {7.765019782652373e-01f, -6.301148131492967e-01f},
+ {7.765019782652371e-01f, -6.301148131492967e-01f},
{7.757281265463254e-01f, -6.310672497324895e-01f},
- {7.749531065948739e-01f, -6.320187359398091e-01f},
+ {7.749531065948738e-01f, -6.320187359398091e-01f},
{7.741769195780490e-01f, -6.329692703383341e-01f},
{7.733995666647743e-01f, -6.339188514965771e-01f},
{7.726210490257291e-01f, -6.348674779844861e-01f},
{7.718413678333470e-01f, -6.358151483734467e-01f},
{7.710605242618138e-01f, -6.367618612362842e-01f},
{7.702785194870657e-01f, -6.377076151472665e-01f},
- {7.694953546867879e-01f, -6.386524086821050e-01f},
+ {7.694953546867880e-01f, -6.386524086821050e-01f},
{7.687110310404124e-01f, -6.395962404179578e-01f},
{7.679255497291163e-01f, -6.405391089334316e-01f},
{7.671389119358204e-01f, -6.414810128085832e-01f},
- {7.663511188451869e-01f, -6.424219506249224e-01f},
+ {7.663511188451870e-01f, -6.424219506249224e-01f},
{7.655621716436182e-01f, -6.433619209654138e-01f},
- {7.647720715192542e-01f, -6.443009224144792e-01f},
+ {7.647720715192541e-01f, -6.443009224144792e-01f},
{7.639808196619715e-01f, -6.452389535579994e-01f},
- {7.631884172633813e-01f, -6.461760129833163e-01f},
+ {7.631884172633814e-01f, -6.461760129833163e-01f},
{7.623948655168271e-01f, -6.471120992792355e-01f},
{7.616001656173835e-01f, -6.480472110360278e-01f},
{7.608043187618542e-01f, -6.489813468454321e-01f},
{7.600073261487703e-01f, -6.499145053006563e-01f},
- {7.592091889783881e-01f, -6.508466849963809e-01f},
- {7.584099084526877e-01f, -6.517778845287601e-01f},
+ {7.592091889783880e-01f, -6.508466849963810e-01f},
+ {7.584099084526879e-01f, -6.517778845287601e-01f},
{7.576094857753715e-01f, -6.527081024954242e-01f},
{7.568079221518612e-01f, -6.536373374954818e-01f},
{7.560052187892974e-01f, -6.545655881295217e-01f},
@@ -1457,16 +1457,16 @@
{7.543963976841503e-01f, -6.564191307093185e-01f},
{7.535902823644226e-01f, -6.573444198636738e-01f},
{7.527830321513488e-01f, -6.582687190692122e-01f},
- {7.519746482606328e-01f, -6.591920269339562e-01f},
- {7.511651319096865e-01f, -6.601143420674205e-01f},
- {7.503544843176265e-01f, -6.610356630806152e-01f},
- {7.495427067052737e-01f, -6.619559885860479e-01f},
- {7.487298002951505e-01f, -6.628753171977246e-01f},
- {7.479157663114792e-01f, -6.637936475311532e-01f},
+ {7.519746482606329e-01f, -6.591920269339562e-01f},
+ {7.511651319096864e-01f, -6.601143420674205e-01f},
+ {7.503544843176265e-01f, -6.610356630806153e-01f},
+ {7.495427067052738e-01f, -6.619559885860480e-01f},
+ {7.487298002951506e-01f, -6.628753171977246e-01f},
+ {7.479157663114792e-01f, -6.637936475311533e-01f},
{7.471006059801801e-01f, -6.647109782033448e-01f},
- {7.462843205288703e-01f, -6.656273078328160e-01f},
+ {7.462843205288703e-01f, -6.656273078328161e-01f},
{7.454669111868606e-01f, -6.665426350395909e-01f},
- {7.446483791851549e-01f, -6.674569584452033e-01f},
+ {7.446483791851548e-01f, -6.674569584452033e-01f},
{7.438287257564475e-01f, -6.683702766726985e-01f},
{7.430079521351217e-01f, -6.692825883466360e-01f},
{7.421860595572477e-01f, -6.701938920930909e-01f},
@@ -1474,28 +1474,28 @@
{7.405389224845600e-01f, -6.720134703154446e-01f},
{7.397136804703048e-01f, -6.729217420510915e-01f},
{7.388873244606151e-01f, -6.738290003787560e-01f},
- {7.380598556999681e-01f, -6.747352439321236e-01f},
+ {7.380598556999680e-01f, -6.747352439321236e-01f},
{7.372312754345167e-01f, -6.756404713464076e-01f},
{7.364015849120877e-01f, -6.765446812583521e-01f},
- {7.355707853821803e-01f, -6.774478723062332e-01f},
- {7.347388780959635e-01f, -6.783500431298615e-01f},
+ {7.355707853821805e-01f, -6.774478723062332e-01f},
+ {7.347388780959634e-01f, -6.783500431298615e-01f},
{7.339058643062745e-01f, -6.792511923705841e-01f},
{7.330717452676171e-01f, -6.801513186712865e-01f},
{7.322365222361595e-01f, -6.810504206763948e-01f},
- {7.314001964697324e-01f, -6.819484970318775e-01f},
+ {7.314001964697325e-01f, -6.819484970318775e-01f},
{7.305627692278276e-01f, -6.828455463852481e-01f},
{7.297242417715950e-01f, -6.837415673855661e-01f},
{7.288846153638420e-01f, -6.846365586834405e-01f},
{7.280438912690308e-01f, -6.855305189310302e-01f},
- {7.272020707532766e-01f, -6.864234467820476e-01f},
+ {7.272020707532767e-01f, -6.864234467820476e-01f},
{7.263591550843460e-01f, -6.873153408917591e-01f},
{7.255151455316546e-01f, -6.882061999169885e-01f},
{7.246700433662657e-01f, -6.890960225161182e-01f},
- {7.238238498608879e-01f, -6.899848073490914e-01f},
- {7.229765662898732e-01f, -6.908725530774144e-01f},
+ {7.238238498608880e-01f, -6.899848073490914e-01f},
+ {7.229765662898732e-01f, -6.908725530774142e-01f},
{7.221281939292153e-01f, -6.917592583641577e-01f},
{7.212787340565479e-01f, -6.926449218739597e-01f},
- {7.204281879511419e-01f, -6.935295422730269e-01f},
+ {7.204281879511419e-01f, -6.935295422730268e-01f},
{7.195765568939045e-01f, -6.944131182291369e-01f},
{7.187238421673769e-01f, -6.952956484116404e-01f},
{7.178700450557317e-01f, -6.961771314914630e-01f},
@@ -1503,13 +1503,13 @@
{7.161592088219294e-01f, -6.979369510346534e-01f},
{7.153021722762606e-01f, -6.988152848477649e-01f},
{7.144440584984474e-01f, -6.996925662576865e-01f},
- {7.135848687807936e-01f, -7.005687939432483e-01f},
- {7.127246044172235e-01f, -7.014439665848672e-01f},
- {7.118632667032795e-01f, -7.023180828645491e-01f},
+ {7.135848687807935e-01f, -7.005687939432483e-01f},
+ {7.127246044172235e-01f, -7.014439665848673e-01f},
+ {7.118632667032795e-01f, -7.023180828645490e-01f},
{7.110008569361208e-01f, -7.031911414658905e-01f},
{7.101373764145209e-01f, -7.040631410740809e-01f},
{7.092728264388657e-01f, -7.049340803759049e-01f},
- {7.084072083111520e-01f, -7.058039580597435e-01f},
+ {7.084072083111521e-01f, -7.058039580597435e-01f},
{7.075405233349850e-01f, -7.066727728155766e-01f}
};
Modified: freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_portaudio/mod_portaudio.c Thu Jan 22 12:28:24 2009
@@ -157,8 +157,8 @@
static switch_status_t channel_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_write_frame(switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id);
static switch_status_t channel_kill_channel(switch_core_session_t *session, int sig);
-static switch_status_t engage_device(int samplerate, int codec_ms);
-static switch_status_t engage_ring_device(int sample_rate, int channels);
+static switch_status_t engage_device(int restart);
+static switch_status_t engage_ring_device(void);
static void deactivate_ring_device(void);
static int dump_info(int verbose);
static switch_status_t load_config(void);
@@ -200,12 +200,12 @@
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s CHANNEL INIT %d %d\n",
switch_channel_get_name(channel), switch_channel_get_state(channel), switch_test_flag(tech_pvt, TFLAG_ANSWER));
- if (engage_device(globals.sample_rate, globals.codec_ms) != SWITCH_STATUS_SUCCESS) {
+ if (engage_device(0) != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
return SWITCH_STATUS_FALSE;
}
- if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND)) {
+ if (switch_test_flag(tech_pvt, TFLAG_OUTBOUND) && !switch_test_flag(tech_pvt, TFLAG_AUTO_ANSWER)) {
add_pvt(tech_pvt, PA_SLAVE);
ring_file = globals.ring_file;
@@ -224,7 +224,7 @@
globals.read_codec.implementation->actual_samples_per_second,
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) {
- if (engage_ring_device(fh.samplerate, fh.channels) != SWITCH_STATUS_SUCCESS) {
+ if (engage_ring_device() != SWITCH_STATUS_SUCCESS) {
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Ring Error!\n");
switch_core_file_close(&fh);
@@ -290,7 +290,7 @@
}
if (ring_file) {
- deactivate_ring_device();
+ //deactivate_ring_device();
switch_core_file_close(&fh);
}
@@ -331,6 +331,9 @@
/* LOCKED ************************************************************************************************** */
if (globals.audio_stream) {
+ if (globals.ring_stream == globals.audio_stream) {
+ globals.ring_stream = NULL;
+ }
CloseAudioStream(globals.audio_stream);
globals.audio_stream = NULL;
}
@@ -370,7 +373,7 @@
}
switch_mutex_lock(globals.device_lock);
- if (globals.ringdev != globals.outdev && globals.ring_stream) {
+ if (globals.ring_stream && globals.ring_stream != globals.audio_stream) {
CloseAudioStream(globals.ring_stream);
}
globals.ring_stream = NULL;
@@ -762,12 +765,19 @@
Pa_Initialize();
- if (dump_info(0)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't find any audio devices!\n");
- return SWITCH_STATUS_TERM;
- }
-
memset(&globals, 0, sizeof(globals));
+ switch_core_hash_init(&globals.call_hash, module_pool);
+ switch_mutex_init(&globals.device_lock, SWITCH_MUTEX_NESTED, module_pool);
+ switch_mutex_init(&globals.pvt_lock, SWITCH_MUTEX_NESTED, module_pool);
+ switch_mutex_init(&globals.flag_mutex, SWITCH_MUTEX_NESTED, module_pool);
+ switch_mutex_init(&globals.pa_mutex, SWITCH_MUTEX_NESTED, module_pool);
+
+ globals.read_frame.data = globals.databuf;
+ globals.read_frame.buflen = sizeof(globals.databuf);
+ globals.cng_frame.data = globals.cngbuf;
+ globals.cng_frame.buflen = sizeof(globals.cngbuf);
+ globals.cng_frame.datalen = switch_samples_per_packet(globals.sample_rate, globals.codec_ms) * 2;
+ switch_set_flag((&globals.cng_frame), SFF_CNG);
/* dual streams makes portaudio on solaris choke */
#if defined(sun) || defined(__sun)
@@ -775,33 +785,26 @@
#else
globals.dual_streams = 1;
#endif
-
+
if ((status = load_config()) != SWITCH_STATUS_SUCCESS) {
return status;
}
+ if (dump_info(0)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't find any audio devices!\n");
+ return SWITCH_STATUS_TERM;
+ }
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"Input Device: %d, Output Device: %d, Ring Device: %d Sample Rate: %d MS: %d\n", globals.indev,
globals.outdev, globals.ringdev, globals.sample_rate, globals.codec_ms);
- switch_core_hash_init(&globals.call_hash, module_pool);
- switch_mutex_init(&globals.device_lock, SWITCH_MUTEX_NESTED, module_pool);
- switch_mutex_init(&globals.pvt_lock, SWITCH_MUTEX_NESTED, module_pool);
- switch_mutex_init(&globals.flag_mutex, SWITCH_MUTEX_NESTED, module_pool);
- switch_mutex_init(&globals.pa_mutex, SWITCH_MUTEX_NESTED, module_pool);
if (switch_event_reserve_subclass(MY_EVENT_RINGING) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Couldn't register subclass!\n");
return SWITCH_STATUS_GENERR;
}
- globals.read_frame.data = globals.databuf;
- globals.read_frame.buflen = sizeof(globals.databuf);
- globals.cng_frame.data = globals.cngbuf;
- globals.cng_frame.buflen = sizeof(globals.cngbuf);
- globals.cng_frame.datalen = switch_samples_per_packet(globals.sample_rate, globals.codec_ms) * 2;
- switch_set_flag((&globals.cng_frame), SFF_CNG);
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
@@ -923,9 +926,9 @@
if (globals.indev < 0) {
globals.indev = get_dev_by_name(NULL, 1);
if (globals.indev > -1) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default input device!\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default input device\n");
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device\n");
status = SWITCH_STATUS_GENERR;
}
}
@@ -933,16 +936,16 @@
if (globals.outdev < 0) {
globals.outdev = get_dev_by_name(NULL, 0);
if (globals.outdev > -1) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default output device!\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Switching to default output device\n");
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device!\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot find an input device\n");
status = SWITCH_STATUS_GENERR;
}
}
if (globals.ringdev < 0) {
if (globals.outdev > -1) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid ring device configured using output device!\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid ring device configured using output device\n");
globals.ringdev = globals.outdev;
}
}
@@ -954,6 +957,7 @@
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_portaudio_shutdown)
{
+#if 0
if (globals.monitor_running == 1) {
int sanity = 20;
globals.monitor_running = -1;
@@ -964,19 +968,12 @@
}
}
}
-
- if (globals.read_codec.implementation) {
- switch_core_codec_destroy(&globals.read_codec);
- }
-
- if (globals.write_codec.implementation) {
- switch_core_codec_destroy(&globals.write_codec);
- }
+#endif
deactivate_audio_device();
deactivate_ring_device();
destroy_codecs();
-
+
Pa_Terminate();
switch_core_hash_destroy(&globals.call_hash);
@@ -1162,76 +1159,78 @@
PaError err;
const char *line = "--------------------------------------------------------------------------------\n";
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
"PortAudio version number = %d\nPortAudio version text = '%s'\n", Pa_GetVersion(), Pa_GetVersionText());
- if (globals.audio_stream) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+ if (globals.call_list) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
return 0;
}
if (verbose < 0) {
+ deactivate_audio_device();
+ deactivate_ring_device();
+ destroy_codecs();
Pa_Terminate();
Pa_Initialize();
load_config();
verbose = 0;
}
-
numDevices = Pa_GetDeviceCount();
if (numDevices < 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices);
err = numDevices;
goto error;
}
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Number of devices = %d\n", numDevices);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Number of devices = %d\n", numDevices);
if (!verbose) {
return 0;
}
for (i = 0; i < numDevices; i++) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s", line);
deviceInfo = Pa_GetDeviceInfo(i);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Device #%d ", i);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Device #%d ", i);
/* Mark global and API specific default devices */
defaultDisplayed = 0;
if (i == Pa_GetDefaultInputDevice()) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default Input");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "**Default Input");
defaultDisplayed = 1;
} else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultInputDevice) {
const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default %s Input", hostInfo->name);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "**Default %s Input", hostInfo->name);
defaultDisplayed = 1;
}
if (i == Pa_GetDefaultOutputDevice()) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default Output");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "**Default Output");
defaultDisplayed = 1;
} else if (i == Pa_GetHostApiInfo(deviceInfo->hostApi)->defaultOutputDevice) {
const PaHostApiInfo *hostInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "**Default %s Output", hostInfo->name);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "**Default %s Output", hostInfo->name);
defaultDisplayed = 1;
}
if (defaultDisplayed) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "** | ");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "** | ");
}
/* print device info fields */
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Name: %s\n", deviceInfo->name);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Host: %s | ", Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "inputs: %d | ", deviceInfo->maxInputChannels);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "outputs: %d | ", deviceInfo->maxOutputChannels);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Name: %s\n", deviceInfo->name);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Host: %s | ", Pa_GetHostApiInfo(deviceInfo->hostApi)->name);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "inputs: %d | ", deviceInfo->maxInputChannels);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "outputs: %d | ", deviceInfo->maxOutputChannels);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Default rate: %8.2f\n", deviceInfo->defaultSampleRate);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Default rate: %8.2f\n", deviceInfo->defaultSampleRate);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Default input latency: %.3f | ", deviceInfo->defaultLowInputLatency);
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Default output latency: %.3f\n", deviceInfo->defaultLowOutputLatency);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Default input latency: %.3f | ", deviceInfo->defaultLowInputLatency);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Default output latency: %.3f\n", deviceInfo->defaultLowOutputLatency);
/* poll for standard sample rates */
inputParameters.device = i;
@@ -1248,25 +1247,25 @@
if (inputParameters.channelCount > 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel input rates:", inputParameters.channelCount);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel input rates:", inputParameters.channelCount);
PrintSupportedStandardSampleRates(&inputParameters, NULL);
}
if (outputParameters.channelCount > 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel output rates:", outputParameters.channelCount);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "half-duplex 16 bit %d channel output rates:", outputParameters.channelCount);
PrintSupportedStandardSampleRates(NULL, &outputParameters);
}
if (inputParameters.channelCount > 0 && outputParameters.channelCount > 0) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO,
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
"full-duplex 16 bit %d channel input, %d channel output rates:", inputParameters.channelCount,
outputParameters.channelCount);
PrintSupportedStandardSampleRates(&inputParameters, &outputParameters);
}
}
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "%s", line);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "%s", line);
return 0;
@@ -1277,148 +1276,165 @@
return err;
}
-static switch_status_t engage_device(int sample_rate, int codec_ms)
+static switch_status_t engage_device(int restart)
{
PaStreamParameters inputParameters, outputParameters;
PaError err;
+ int sample_rate = globals.sample_rate;
+ int codec_ms = globals.codec_ms;
- if (!globals.audio_stream) {
- if (!sample_rate) {
- sample_rate = globals.sample_rate;
- }
- if (!codec_ms) {
- codec_ms = globals.codec_ms;
- }
-
- if (!globals.read_codec.implementation) {
- if (switch_core_codec_init(&globals.read_codec,
- "L16",
- NULL, sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
- NULL) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
- return SWITCH_STATUS_FALSE;
- }
- }
- switch_assert(globals.read_codec.implementation);
+ if (restart) {
+ deactivate_audio_device();
+ deactivate_ring_device();
+ destroy_codecs();
+ }
- if (!globals.write_codec.implementation) {
- if (switch_core_codec_init(&globals.write_codec,
- "L16",
- NULL,
- sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
- NULL) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
- switch_core_codec_destroy(&globals.read_codec);
- return SWITCH_STATUS_FALSE;
- }
- }
+ if (globals.timer.timer_interface) {
+ switch_core_timer_sync(&globals.timer);
+ }
- if (!globals.timer.timer_interface) {
- if (switch_core_timer_init(&globals.timer,
- globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet,
- module_pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
- switch_core_codec_destroy(&globals.read_codec);
- switch_core_codec_destroy(&globals.write_codec);
- return SWITCH_STATUS_FALSE;
- }
- }
+ if (globals.audio_stream) {
+ return SWITCH_STATUS_SUCCESS;
+ }
- if (!globals.hold_timer.timer_interface) {
- if (switch_core_timer_init(&globals.hold_timer,
- globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet,
- module_pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup hold timer failed!\n");
- switch_core_codec_destroy(&globals.read_codec);
- switch_core_codec_destroy(&globals.write_codec);
- switch_core_timer_destroy(&globals.timer);
- return SWITCH_STATUS_FALSE;
- }
+ if (!globals.read_codec.implementation) {
+ if (switch_core_codec_init(&globals.read_codec,
+ "L16",
+ NULL, sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
+ NULL) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
+ return SWITCH_STATUS_FALSE;
}
-
- globals.read_frame.rate = sample_rate;
- globals.read_frame.codec = &globals.read_codec;
-
- switch_mutex_lock(globals.device_lock);
- /* LOCKED ************************************************************************************************** */
- inputParameters.device = globals.indev;
- inputParameters.channelCount = 1;
- inputParameters.sampleFormat = SAMPLE_TYPE;
- inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
- inputParameters.hostApiSpecificStreamInfo = NULL;
+ }
- outputParameters.device = globals.outdev;
- outputParameters.channelCount = 1;
- outputParameters.sampleFormat = SAMPLE_TYPE;
- outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
- outputParameters.hostApiSpecificStreamInfo = NULL;
- //err = OpenAudioStream(&globals.audio_stream, NULL/*&inputParameters*/, &outputParameters, sample_rate, paClipOff,
- //globals.read_codec.implementation->samples_per_packet);
+ switch_assert(globals.read_codec.implementation);
- err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff,
- globals.read_codec.implementation->samples_per_packet, globals.dual_streams);
- /* UNLOCKED ************************************************************************************************* */
+ if (!globals.write_codec.implementation) {
+ if (switch_core_codec_init(&globals.write_codec,
+ "L16",
+ NULL,
+ sample_rate, codec_ms, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
+ NULL) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't load codec?\n");
+ switch_core_codec_destroy(&globals.read_codec);
+ return SWITCH_STATUS_FALSE;
+ }
+ }
- if (err != paNoError) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening audio device! retrying\n");
- switch_yield(1000000);
- err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff,
- globals.read_codec.implementation->samples_per_packet, globals.dual_streams);
+ if (!globals.timer.timer_interface) {
+ if (switch_core_timer_init(&globals.timer,
+ globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet,
+ module_pool) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup timer failed!\n");
+ switch_core_codec_destroy(&globals.read_codec);
+ switch_core_codec_destroy(&globals.write_codec);
+ return SWITCH_STATUS_FALSE;
}
+ }
- switch_mutex_unlock(globals.device_lock);
-
- if (err != paNoError) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device!\n");
+ if (!globals.hold_timer.timer_interface) {
+ if (switch_core_timer_init(&globals.hold_timer,
+ globals.timer_name, codec_ms, globals.read_codec.implementation->samples_per_packet,
+ module_pool) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "setup hold timer failed!\n");
switch_core_codec_destroy(&globals.read_codec);
switch_core_codec_destroy(&globals.write_codec);
switch_core_timer_destroy(&globals.timer);
- switch_core_timer_destroy(&globals.hold_timer);
return SWITCH_STATUS_FALSE;
}
}
+ globals.read_frame.rate = sample_rate;
+ globals.read_frame.codec = &globals.read_codec;
+
+ switch_mutex_lock(globals.device_lock);
+ /* LOCKED ************************************************************************************************** */
+ inputParameters.device = globals.indev;
+ inputParameters.channelCount = 1;
+ inputParameters.sampleFormat = SAMPLE_TYPE;
+ inputParameters.suggestedLatency = Pa_GetDeviceInfo(inputParameters.device)->defaultLowInputLatency;
+ inputParameters.hostApiSpecificStreamInfo = NULL;
+ outputParameters.device = globals.outdev;
+ outputParameters.channelCount = 1;
+ outputParameters.sampleFormat = SAMPLE_TYPE;
+ outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
+ outputParameters.hostApiSpecificStreamInfo = NULL;
+ //err = OpenAudioStream(&globals.audio_stream, NULL/*&inputParameters*/, &outputParameters, sample_rate, paClipOff,
+ //globals.read_codec.implementation->samples_per_packet);
+ err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff,
+ globals.read_codec.implementation->samples_per_packet, globals.dual_streams);
+ /* UNLOCKED ************************************************************************************************* */
+ if (err != paNoError) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening audio device retrying\n");
+ switch_yield(1000000);
+ err = OpenAudioStream(&globals.audio_stream, &inputParameters, &outputParameters, sample_rate, paClipOff,
+ globals.read_codec.implementation->samples_per_packet, globals.dual_streams);
+ }
+
+ switch_mutex_unlock(globals.device_lock);
+
+ if (err != paNoError) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open audio device\n");
+ switch_core_codec_destroy(&globals.read_codec);
+ switch_core_codec_destroy(&globals.write_codec);
+ switch_core_timer_destroy(&globals.timer);
+ switch_core_timer_destroy(&globals.hold_timer);
+ return SWITCH_STATUS_FALSE;
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engage audio device rate: %d channels %d\n", sample_rate, outputParameters.channelCount);
+
+ engage_ring_device();
+
return SWITCH_STATUS_SUCCESS;
}
-static switch_status_t engage_ring_device(int sample_rate, int channels)
+static switch_status_t engage_ring_device(void)
{
PaStreamParameters outputParameters = {0};
PaError err;
+ int sample_rate = globals.sample_rate;
+ int channels = 1;
- if (!globals.ring_stream) {
- if (globals.ringdev == globals.outdev) {
+ if (globals.ring_stream) {
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ if (globals.ringdev == globals.outdev) {
+ if (engage_device(0) == SWITCH_STATUS_SUCCESS) {
globals.ring_stream = globals.audio_stream;
} else {
- if (!sample_rate) {
- sample_rate = globals.sample_rate;
- }
+ goto error;
+ }
+ } else {
+ switch_mutex_lock(globals.device_lock);
+ /* LOCKED ************************************************************************************************** */
+ outputParameters.device = globals.ringdev;
+ outputParameters.channelCount = channels;
+ outputParameters.sampleFormat = SAMPLE_TYPE;
+ outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
+ outputParameters.hostApiSpecificStreamInfo = NULL;
+ err = OpenAudioStream(&globals.ring_stream, NULL,
+ &outputParameters, sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, globals.dual_streams);
+ /* UNLOCKED ************************************************************************************************* */
+ switch_mutex_unlock(globals.device_lock);
- switch_mutex_lock(globals.device_lock);
- /* LOCKED ************************************************************************************************** */
- outputParameters.device = globals.ringdev;
- outputParameters.channelCount = channels;
- outputParameters.sampleFormat = SAMPLE_TYPE;
- outputParameters.suggestedLatency = Pa_GetDeviceInfo(outputParameters.device)->defaultLowOutputLatency;
- outputParameters.hostApiSpecificStreamInfo = NULL;
- err = OpenAudioStream(&globals.ring_stream, NULL,
- &outputParameters, sample_rate, paClipOff, globals.read_codec.implementation->samples_per_packet, globals.dual_streams);
-
- /* UNLOCKED ************************************************************************************************* */
- switch_mutex_unlock(globals.device_lock);
-
- if (err != paNoError) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open ring device!\n");
- return SWITCH_STATUS_FALSE;
- }
+ if (err != paNoError) {
+ goto error;
}
}
switch_yield(10000);
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Engage ring device! rate: %d channels %d\n", sample_rate, channels);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Engage ring device rate: %d channels %d\n", sample_rate, channels);
return SWITCH_STATUS_SUCCESS;
+
+
+ error:
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open ring device\n");
+ return SWITCH_STATUS_FALSE;
+
}
static switch_status_t dtmf_call(char **argv, int argc, switch_stream_handle_t *stream)
@@ -1723,7 +1739,7 @@
switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
}
tech_pvt->session = session;
- if ((status = engage_device(tech_pvt->sample_rate, tech_pvt->codec_ms)) == SWITCH_STATUS_SUCCESS) {
+ if ((status = engage_device(0)) == SWITCH_STATUS_SUCCESS) {
switch_set_flag_locked(tech_pvt, TFLAG_ANSWER);
switch_channel_mark_answered(channel);
switch_channel_set_state(channel, CS_INIT);
@@ -1772,8 +1788,7 @@
"pa indev #<num>|<partial name>\n"
"pa outdev #<num>|<partial name>\n"
"pa ringdev #<num>|<partial name>\n"
- "pa play <filename>\n"
- "pa ringtest\n"
+ "pa play [ringtest|<filename>]\n"
"pa looptest\n" "--------------------------------------------------------------------------------\n";
@@ -1843,7 +1858,13 @@
} else if (!strcasecmp(argv[0], "devlist")) {
func = devlist;
} else if (!strcasecmp(argv[0], "rescan")) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "Looking for new devices.\n");
+
+ if (globals.call_list) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+ goto done;
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Looking for new devices.\n");
dump_info(-1);
goto done;
} else if (!strcasecmp(argv[0], "dump")) {
@@ -1862,6 +1883,12 @@
} else if (!strcasecmp(argv[0], "dtmf")) {
func = dtmf_call;
} else if (argv[1] && !strcmp(argv[0], "indev")) {
+
+ if (globals.call_list) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+ goto done;
+ }
+
if (*argv[1] == '#') {
devval = get_dev_by_number(argv[1] + 1, 1);
} else {
@@ -1870,8 +1897,15 @@
devname = "indev";
if (devval > -1) {
globals.indev = devval;
+ engage_device(1);
}
} else if (argv[1] && !strcmp(argv[0], "outdev")) {
+
+ if (globals.call_list) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+ goto done;
+ }
+
if (*argv[1] == '#') {
devval = get_dev_by_number(argv[1] + 1, 0);
} else {
@@ -1880,8 +1914,15 @@
devname = "outdev";
if (devval > -1) {
globals.outdev = devval;
+ engage_device(1);
}
} else if (argv[1] && !strcmp(argv[0], "ringdev")) {
+
+ if (globals.call_list) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+ goto done;
+ }
+
if (*argv[1] == '#') {
devval = get_dev_by_number(argv[1] + 1, 0);
} else {
@@ -1890,52 +1931,71 @@
devname = "ringdev";
if (devval > -1) {
globals.ringdev = devval;
+ engage_device(1);
}
- } else if ((argv[1] && !strcasecmp(argv[0], "play")) || !strcasecmp(argv[0], "ringtest")) {
+ } else if ((argv[1] && !strcasecmp(argv[0], "play"))) {
switch_file_handle_t fh = { 0 };
char *playfile = NULL;
- if (globals.audio_stream) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+ int samples = 0;
+ int seconds = 5;
+
+ if (globals.call_list) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
goto done;
}
- if (!strcasecmp(argv[0], "ringtest")) {
+ if (!strcasecmp(argv[1], "ringtest")) {
playfile = globals.ring_file;
} else {
playfile = argv[1];
}
- if (engage_device(globals.sample_rate, globals.codec_ms) == SWITCH_STATUS_SUCCESS) {
+ fh.pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN;
+ if (engage_device(0) == SWITCH_STATUS_SUCCESS) {
if (switch_core_file_open(&fh,
- playfile,
- globals.read_codec.implementation->number_of_channels,
- globals.read_codec.implementation->actual_samples_per_second,
- SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) {
- switch_size_t olen = globals.timer.samples;
+ playfile,
+ globals.read_codec.implementation->number_of_channels,
+ globals.read_codec.implementation->actual_samples_per_second,
+ SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) == SWITCH_STATUS_SUCCESS) {
+ switch_size_t olen = globals.read_codec.implementation->samples_per_packet;
int16_t abuf[2048];
+ if (argv[2]) {
+ int i = atoi(argv[2]);
+ if (i > 0) {
+ seconds = i;
+ }
+ }
+
+ samples = globals.read_codec.implementation->actual_samples_per_second * seconds;
+ stream->write_function(stream, "playback test [%s] %d second(s) %d samples @%dkhz",
+ playfile, seconds, samples, globals.read_codec.implementation->actual_samples_per_second);
+
while (switch_core_file_read(&fh, abuf, &olen) == SWITCH_STATUS_SUCCESS) {
WriteAudioStream(globals.audio_stream, abuf, (long) olen, &globals.timer);
switch_core_timer_next(&globals.timer);
- olen = globals.timer.samples;
+ samples -= (int) olen;
+ if (samples <= 0) {
+ break;
+ }
+ olen = globals.read_codec.implementation->samples_per_packet;
}
switch_core_file_close(&fh);
} else {
stream->write_function(stream, "Cannot play requested file %s\n", argv[1]);
}
- deactivate_audio_device();
} else {
stream->write_function(stream, "Failed to engage audio device\n");
}
goto done;
} else if (!strcasecmp(argv[0], "looptest")) {
- if (globals.audio_stream) {
- switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
+ if (globals.call_list) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "ERROR: Cannot use this command this while a call is in progress\n");
goto done;
}
- if (engage_device(globals.sample_rate, globals.codec_ms) == SWITCH_STATUS_SUCCESS) {
+ if (engage_device(0) == SWITCH_STATUS_SUCCESS) {
int samples = 0;
int success = 0;
int i;
@@ -1947,7 +2007,6 @@
}
switch_yield(10000);
}
- deactivate_audio_device();
if (!success) {
stream->write_function(stream, "Failed to read any bytes from indev\n");
}
1
0