提交 8db35185 authored 作者: Chris Rienzo's avatar Chris Rienzo

mod_rayo CPA implemented - still needs testing

上级 85423194
......@@ -109,6 +109,9 @@
<!-- IQ request aliases. Used mainly for testing purposes or for controlling a rayo call via the console -->
<aliases>
<alias name="detect" target="call" args="1"><![CDATA[<input xmlns="urn:xmpp:rayo:input:1" mode="cpa"><grammar url="urn:xmpp:rayo:cpa:$1:1"/></input>]]></alias>
<alias name="detect-once" target="call" args="1"><![CDATA[<input xmlns="urn:xmpp:rayo:input:1" mode="cpa"><grammar url="urn:xmpp:rayo:cpa:$1:1?terminate=true"/></input>]]></alias>
<alias name="detect-tones" target="call"><![CDATA[<input xmlns="urn:xmpp:rayo:input:1" mode="cpa"><grammar url="urn:xmpp:rayo:cpa:busy:1"/><grammar url="urn:xmpp:rayo:cpa:congestion:1"/><grammar url="urn:xmpp:rayo:cpa:sit:1"/></input>]]></alias>
<alias name="ping" target="external"><![CDATA[<iq type="get"><ping xmlns="urn:xmpp:ping"/></iq>]]></alias>
<alias name="dial" target="server" args="2"><![CDATA[<dial xmlns="urn:xmpp:rayo:1" from="$1" to="$2"/>]]></alias>
<alias name="answer" target="call"><![CDATA[<answer xmlns="urn:xmpp:rayo:1"/>]]></alias>
......
......@@ -10,6 +10,7 @@ LOCAL_OBJS= $(IKS_LA) \
iks_helpers.o \
nlsml.o \
rayo_components.o \
rayo_cpa_component.o \
rayo_cpa_detector.o \
rayo_elements.o \
rayo_fax_components.o \
......@@ -24,6 +25,7 @@ LOCAL_SOURCES= \
iks_helpers.c \
nlsml.c \
rayo_components.c \
rayo_cpa_component.c \
rayo_cpa_detector.c \
rayo_elements.c \
rayo_fax_components.c \
......
......@@ -109,6 +109,9 @@
<!-- IQ request aliases. Used mainly for testing purposes or for controlling a rayo call via the console -->
<aliases>
<alias name="detect" target="call" args="1"><![CDATA[<input xmlns="urn:xmpp:rayo:input:1" mode="cpa"><grammar url="urn:xmpp:rayo:cpa:$1:1"/></input>]]></alias>
<alias name="detect-once" target="call" args="1"><![CDATA[<input xmlns="urn:xmpp:rayo:input:1" mode="cpa"><grammar url="urn:xmpp:rayo:cpa:$1:1?terminate=true"/></input>]]></alias>
<alias name="detect-tones" target="call"><![CDATA[<input xmlns="urn:xmpp:rayo:input:1" mode="cpa"><grammar url="urn:xmpp:rayo:cpa:busy:1"/><grammar url="urn:xmpp:rayo:cpa:congestion:1"/><grammar url="urn:xmpp:rayo:cpa:sit:1"/></input>]]></alias>
<alias name="ping" target="external"><![CDATA[<iq type="get"><ping xmlns="urn:xmpp:ping"/></iq>]]></alias>
<alias name="dial" target="server" args="2"><![CDATA[<dial xmlns="urn:xmpp:rayo:1" from="$1" to="$2"/>]]></alias>
<alias name="answer" target="call"><![CDATA[<answer xmlns="urn:xmpp:rayo:1"/>]]></alias>
......
......@@ -1191,6 +1191,10 @@ static struct rayo_mixer *_rayo_mixer_create(const char *name, const char *file,
*/
static void rayo_component_cleanup(struct rayo_actor *actor)
{
if (RAYO_COMPONENT(actor)->cleanup_fn) {
RAYO_COMPONENT(actor)->cleanup_fn(actor);
}
/* parent can now be destroyed */
RAYO_UNLOCK(RAYO_COMPONENT(actor)->parent);
}
......@@ -1202,9 +1206,12 @@ static void rayo_component_cleanup(struct rayo_actor *actor)
* @param id internal ID of this component
* @param parent the parent that owns this component
* @param client_jid the client that created this component
* @param cleanup optional cleanup function
* @param file file that called this function
* @param line line number that called this function
* @return the component
*/
struct rayo_component *_rayo_component_init(struct rayo_component *component, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, struct rayo_actor *parent, const char *client_jid, const char *file, int line)
struct rayo_component *_rayo_component_init(struct rayo_component *component, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, struct rayo_actor *parent, const char *client_jid, rayo_actor_cleanup_fn cleanup, const char *file, int line)
{
char *ref = switch_mprintf("%s-%d", subtype, rayo_actor_seq_next(parent));
char *jid = switch_mprintf("%s/%s", RAYO_JID(parent), ref);
......@@ -1218,6 +1225,7 @@ struct rayo_component *_rayo_component_init(struct rayo_component *component, sw
component->client_jid = switch_core_strdup(pool, client_jid);
component->ref = switch_core_strdup(pool, ref);
component->parent = parent;
component->cleanup_fn = cleanup;
switch_safe_free(ref);
switch_safe_free(jid);
......@@ -2443,6 +2451,8 @@ static iks *on_iq_get_xmpp_disco(struct rayo_actor *server, struct rayo_message
feature = iks_insert(x, "feature");
iks_insert_attrib(feature, "var", RAYO_NS);
feature = iks_insert(x, "feature");
iks_insert_attrib(feature, "var", RAYO_CPA_NS);
feature = iks_insert(x, "feature");
iks_insert_attrib(feature, "var", RAYO_FAX_NS);
/* TODO The response MUST also include features for the application formats and transport methods supported by
......
......@@ -42,6 +42,9 @@
#define RAYO_CALL_NS RAYO_BASE "call:" RAYO_VERSION
#define RAYO_MIXER_NS RAYO_BASE "mixer:" RAYO_VERSION
#define RAYO_CPA_BASE RAYO_BASE "cpa:"
#define RAYO_CPA_NS RAYO_CPA_BASE RAYO_VERSION
#define RAT_CALL "CALL"
#define RAT_COMPONENT "COMPONENT"
#define RAT_CALL_COMPONENT RAT_COMPONENT"_CALL"
......@@ -119,6 +122,8 @@ struct rayo_component {
const char *client_jid;
/** external ref */
const char *ref;
/** optional cleanup */
rayo_actor_cleanup_fn cleanup_fn;
};
#define RAYO_ACTOR(x) ((struct rayo_actor *)x)
......@@ -160,8 +165,9 @@ extern const char *rayo_call_get_dcp_jid(struct rayo_call *call);
#define rayo_mixer_get_name(mixer) RAYO_ID(mixer)
#define rayo_component_init(component, pool, type, subtype, id, parent, client_jid) _rayo_component_init(component, pool, type, subtype, id, parent, client_jid, __FILE__, __LINE__)
extern struct rayo_component *_rayo_component_init(struct rayo_component *component, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, struct rayo_actor *parent, const char *client_jid, const char *file, int line);
#define rayo_component_init(component, pool, type, subtype, id, parent, client_jid) _rayo_component_init(component, pool, type, subtype, id, parent, client_jid, NULL, __FILE__, __LINE__)
#define rayo_component_init_cleanup(component, pool, type, subtype, id, parent, client_jid, cleanup) _rayo_component_init(component, pool, type, subtype, id, parent, client_jid, cleanup, __FILE__, __LINE__)
extern struct rayo_component *_rayo_component_init(struct rayo_component *component, switch_memory_pool_t *pool, const char *type, const char *subtype, const char *id, struct rayo_actor *parent, const char *client_jid, rayo_actor_cleanup_fn cleanup, const char *file, int line);
extern switch_bool_t is_component_actor(struct rayo_actor *);
typedef iks *(*rayo_actor_xmpp_handler)(struct rayo_actor *, struct rayo_message *, void *);
......
/*
* mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2014, Grasshopper
*
* 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 mod_rayo for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
*
* The Initial Developer of the Original Code is Grasshopper
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Chris Rienzo <chris.rienzo@grasshopper.com>
*
* rayo_cpa_component.h -- Rayo call progress analysis component
*
*/
#ifndef RAYO_CPA_COMPONENT_H
#define RAYO_CPA_COMPONENT_H
#include <switch.h>
#include <iksemel.h>
#include "mod_rayo.h"
extern switch_status_t rayo_cpa_component_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
extern void rayo_cpa_component_shutdown(void);
extern iks *rayo_cpa_component_start(struct rayo_actor *call, struct rayo_message *msg, void *session_data);
#endif
/* 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 noet
*/
......@@ -155,21 +155,27 @@ static void rayo_cpa_detector_event(switch_event_t *event)
}
if (!zstr(signal_type)) {
switch_event_t *cpa_event;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got Rayo CPA event %s\n", signal_type);
const char *uuid = switch_event_get_header(event, "Unique-ID");
if (zstr(uuid)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Detector %s %s event is missing call UUID!\n", detector->name, signal_type);
return;
}
switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Got Rayo CPA event %s\n", signal_type);
if (switch_event_create_subclass(&cpa_event, SWITCH_EVENT_CUSTOM, "rayo::cpa") == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "detector-name", detector->name);
switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "detector-uuid", detector->uuid);
switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "signal-type", signal_type);
switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "Unique-ID", uuid);
switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "detector-name", detector->name);
switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "detector-uuid", detector->uuid);
switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "signal-type", "%s%s:%s", RAYO_CPA_BASE, signal_type, RAYO_VERSION);
if (!zstr(detector->signal_value_header)) {
const char *value = switch_event_get_header(event, detector->signal_value_header);
if (!zstr(value)) {
switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "value", value);
switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "value", value);
}
}
if (!zstr(detector->signal_duration_header)) {
const char *duration = switch_event_get_header(event, detector->signal_duration_header);
if (!zstr(duration)) {
switch_event_add_header(cpa_event, SWITCH_STACK_BOTTOM, "duration", duration);
switch_event_add_header_string(cpa_event, SWITCH_STACK_BOTTOM, "duration", duration);
}
}
switch_event_fire(&cpa_event);
......
......@@ -33,21 +33,6 @@
#include "mod_rayo.h"
#define RAYO_CPA_BASE RAYO_BASE "cpa:"
#define RAYO_CPA_NS RAYO_CPA_BASE RAYO_VERSION
#define RAYO_CPA_BEEP_NS RAYO_CPA_BASE "beep:" RAYO_VERSION
#define RAYO_CPA_DTMF_NS RAYO_CPA_BASE "dtmf:" RAYO_VERSION
#define RAYO_CPA_SPEECH_NS RAYO_CPA_BASE "speech:" RAYO_VERSION
#define RAYO_CPA_FAX_CED_NS RAYO_CPA_BASE "fax-ced:" RAYO_VERSION
#define RAYO_CPA_FAX_CNG_NS RAYO_CPA_BASE "fax-cng:" RAYO_VERSION
#define RAYO_CPA_RING_NS RAYO_CPA_BASE "ring:" RAYO_VERSION
#define RAYO_CPA_BUSY_NS RAYO_CPA_BASE "busy:" RAYO_VERSION
#define RAYO_CPA_CONGESTION_NS RAYO_CPA_BASE "congestion:" RAYO_VERSION
#define RAYO_CPA_SIT_NS RAYO_CPA_BASE "sit:" RAYO_VERSION
#define RAYO_CPA_MODEM_NS RAYO_CPA_BASE "modem:" RAYO_VERSION
#define RAYO_CPA_OFFHOOK_NS RAYO_CPA_BASE "offhook:" RAYO_VERSION
extern switch_status_t rayo_cpa_detector_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool, const char *config_file);
extern void rayo_cpa_detector_shutdown(void);
extern int rayo_cpa_detector_start(const char *call_uuid, const char *signal_ns, const char **error_detail);
......
......@@ -33,7 +33,7 @@
*/
ELEMENT(RAYO_INPUT)
ATTRIB(xmlns,, any)
STRING_ATTRIB(mode, any, "any,dtmf,voice")
STRING_ATTRIB(mode, any, "any,dtmf,voice,cpa")
OPTIONAL_ATTRIB(terminator,, dtmf_digit)
ATTRIB(recognizer,, any)
ATTRIB(language, en-US, any)
......
......@@ -27,7 +27,7 @@
*
*/
#include "rayo_components.h"
#include "rayo_cpa_detector.h"
#include "rayo_cpa_component.h"
#include "rayo_elements.h"
#include "srgs.h"
#include "nlsml.h"
......@@ -360,10 +360,14 @@ static iks *start_call_input(struct input_component *component, switch_core_sess
component->speech_mode = strcmp(iks_find_attrib_soft(input, "mode"), "dtmf");
if (component->speech_mode && handler->voice_component) {
/* don't allow multi voice input */
RAYO_UNLOCK(component);
RAYO_DESTROY(component);
return iks_new_error_detailed(iq, STANZA_ERROR_CONFLICT, "Multiple voice input is not allowed");
}
if (!component->speech_mode && handler->dtmf_component) {
/* don't allow multi dtmf input */
RAYO_UNLOCK(component);
RAYO_DESTROY(component);
return iks_new_error_detailed(iq, STANZA_ERROR_CONFLICT, "Multiple dtmf input is not allowed");
}
......@@ -538,17 +542,20 @@ static iks *start_call_input_component(struct rayo_actor *call, struct rayo_mess
struct input_component *input_component = NULL;
const char *error = NULL;
/* Start CPA */
if (!strcmp(iks_find_attrib_soft(input, "mode"), "cpa")) {
return rayo_cpa_component_start(call, msg, session_data);
}
/* start input */
if (!validate_call_input(input, &error)) {
return iks_new_error_detailed(iq, STANZA_ERROR_BAD_REQUEST, error);
}
/* create component */
switch_core_new_memory_pool(&pool);
input_component = switch_core_alloc(pool, sizeof(*input_component));
rayo_component_init(RAYO_COMPONENT(input_component), pool, RAT_CALL_COMPONENT, "input", component_id, call, iks_find_attrib(iq, "from"));
/* start input */
return start_call_input(input_component, session, iks_find(iq, "input"), iq, NULL, 0);
return start_call_input(input_component, session, input, iq, NULL, 0);
}
/**
......@@ -761,7 +768,7 @@ switch_status_t rayo_input_component_load(switch_loadable_module_interface_t **m
rayo_actor_command_handler_add(RAT_CALL_COMPONENT, "input", "set:"RAYO_INPUT_NS":start-timers", start_timers_call_input_component);
switch_event_bind("rayo_input_component", SWITCH_EVENT_DETECTED_SPEECH, SWITCH_EVENT_SUBCLASS_ANY, on_detected_speech_event, NULL);
return rayo_cpa_detector_load(module_interface, pool, config_file);
return rayo_cpa_component_load(module_interface, pool, config_file);
}
/**
......@@ -773,7 +780,7 @@ switch_status_t rayo_input_component_shutdown(void)
srgs_parser_destroy(globals.parser);
switch_event_unbind_callback(on_detected_speech_event);
rayo_cpa_detector_shutdown();
rayo_cpa_component_shutdown();
return SWITCH_STATUS_SUCCESS;
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论