703 lines
23 KiB
C
Raw Normal View History

/*
* Copyright 2008 Arsen Chaloyan
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
commit 027047ed7b07832456cd5d13f4c85da24aca26b5 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Tue Jul 14 18:17:37 2009 +0000 Added missing UNIMRCP_APU_INCLUDES in pkg-config files git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1054 f001bc3a-424a-0410-80a0-a715b8f413a8 commit b0e1c8251f8039a8a22662120e5a362340733a9e Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Mon Jul 13 17:25:34 2009 +0000 if state != RECOGNIZING, there is nothing to do on deactivation git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1053 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 3581b9d3ba59177f4aaced327e20b8dc53e234e3 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Mon Jul 13 16:14:38 2009 +0000 Do not include Completion-Cause header field in the IN-PROGRESS response sent by PocketSphinx plugin git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1052 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 831f43f9071e491169d4d5a7e3d0cb2009c3af21 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Mon Jul 13 15:27:33 2009 +0000 Using MRCP_SESSION_SID(session) macro wherever session id is logged git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1051 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 9349bd2b393ee0b300942bfa8cacc264687ecea9 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Sat Jul 11 15:17:42 2009 +0000 Sent async channel_open and channel_close responses git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1050 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 5775dfc74e8fe982735da32dfa12dc05f0d20892 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Sat Jul 11 15:15:47 2009 +0000 Sent async channel_close response git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1049 f001bc3a-424a-0410-80a0-a715b8f413a8 commit efa4d10b2dc3de238dfb4a26b25ef3a580fb0bf0 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Sat Jul 11 12:54:47 2009 +0000 Enhanced state machine to STOP in-progress SPEAK or RECOGNIZE requests on session termination, thus guarantee there is no remaining request, when plugin cha nnel_close() method is called. channel_open() -> SPEAK -> STOP -> channel_close() channel_open() -> SPEAK -> SPEAK-COMPLETE -> channel_close() This allows to simplify implementation of plugins (nothing has to be changed). git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1048 f001bc3a-424a-0410-80a0-a715b8f413a8 commit aaf53907ea0705bc2a44fe785c8f7762e20e52cf Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Fri Jul 10 12:57:33 2009 +0000 Added utility function to get attributes of NLSML results such as confidence and grammar git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1047 f001bc3a-424a-0410-80a0-a715b8f413a8 commit f7c4dff83199cb9af8dc7ec6f121c384d2b6cea0 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Fri Jul 10 09:51:23 2009 +0000 Added missing includes for <stdlib.h> and <stdio.h> required on some platforms git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1046 f001bc3a-424a-0410-80a0-a715b8f413a8 commit 1cb7ccb6e63f4d34b6cfcbdc386446a36d052af1 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Thu Jul 9 19:05:18 2009 +0000 Using NLSML processor in demo git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1045 f001bc3a-424a-0410-80a0-a715b8f413a8 commit cd74eee440dd94cabe814c7d4f64dfef187b7445 Author: achaloyan <achaloyan@f001bc3a-424a-0410-80a0-a715b8f413a8> Date: Thu Jul 9 18:52:49 2009 +0000 Added basic NLSML document processor git-svn-id: https://unimrcp.googlecode.com/svn/trunk@1044 f001bc3a-424a-0410-80a0-a715b8f413a8 git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@14260 d0543943-73ff-0310-b7d9-9358b9ac24b2
2009-07-15 20:30:39 +00:00
#include <stdlib.h>
#include <apr_xml.h>
#include "unimrcp_server.h"
#include "uni_version.h"
#include "mrcp_default_factory.h"
#include "mpf_engine.h"
#include "mpf_codec_manager.h"
#include "mpf_rtp_termination_factory.h"
#include "mrcp_sofiasip_server_agent.h"
#include "mrcp_unirtsp_server_agent.h"
#include "mrcp_server_connection.h"
#include "apt_net.h"
#include "apt_log.h"
#define CONF_FILE_NAME "unimrcpserver.xml"
#define DEFAULT_CONF_DIR_PATH "../conf"
#define DEFAULT_PLUGIN_DIR_PATH "../plugin"
#ifdef WIN32
#define DEFAULT_PLUGIN_EXT "dll"
#else
#define DEFAULT_PLUGIN_EXT "so"
#endif
#define DEFAULT_IP_ADDRESS "127.0.0.1"
#define DEFAULT_SIP_PORT 8060
#define DEFAULT_RTSP_PORT 1554
#define DEFAULT_MRCP_PORT 1544
#define DEFAULT_RTP_PORT_MIN 5000
#define DEFAULT_RTP_PORT_MAX 6000
#define DEFAULT_SOFIASIP_UA_NAME "UniMRCP SofiaSIP"
#define DEFAULT_SDP_ORIGIN "UniMRCPServer"
#define XML_FILE_BUFFER_LENGTH 2000
static apr_xml_doc* unimrcp_server_config_parse(const char *path, apr_pool_t *pool);
static apt_bool_t unimrcp_server_config_load(mrcp_server_t *server, const char *plugin_dir_path, const apr_xml_doc *doc, apr_pool_t *pool);
/** Start UniMRCP server */
MRCP_DECLARE(mrcp_server_t*) unimrcp_server_start(apt_dir_layout_t *dir_layout)
{
apr_pool_t *pool;
apr_xml_doc *doc;
mrcp_resource_factory_t *resource_factory;
mpf_codec_manager_t *codec_manager;
mrcp_server_t *server;
if(!dir_layout) {
return NULL;
}
apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"UniMRCP Server ["UNI_VERSION_STRING"]");
apt_log(APT_LOG_MARK,APT_PRIO_INFO,"APR ["APR_VERSION_STRING"]");
server = mrcp_server_create(dir_layout);
if(!server) {
return NULL;
}
pool = mrcp_server_memory_pool_get(server);
if(!pool) {
return NULL;
}
resource_factory = mrcp_default_factory_create(pool);
if(resource_factory) {
mrcp_server_resource_factory_register(server,resource_factory);
}
codec_manager = mpf_engine_codec_manager_create(pool);
if(codec_manager) {
mrcp_server_codec_manager_register(server,codec_manager);
}
doc = unimrcp_server_config_parse(dir_layout->conf_dir_path,pool);
if(doc) {
unimrcp_server_config_load(server,dir_layout->plugin_dir_path,doc,pool);
}
mrcp_server_start(server);
return server;
}
/** Shutdown UniMRCP server */
MRCP_DECLARE(apt_bool_t) unimrcp_server_shutdown(mrcp_server_t *server)
{
if(mrcp_server_shutdown(server) == FALSE) {
return FALSE;
}
return mrcp_server_destroy(server);
}
/** Parse config file */
static apr_xml_doc* unimrcp_server_config_parse(const char *dir_path, apr_pool_t *pool)
{
apr_xml_parser *parser = NULL;
apr_xml_doc *doc = NULL;
apr_file_t *fd = NULL;
apr_status_t rv;
const char *file_path;
if(!dir_path) {
dir_path = DEFAULT_CONF_DIR_PATH;
}
if(*dir_path == '\0') {
file_path = CONF_FILE_NAME;
}
else {
file_path = apr_psprintf(pool,"%s/%s",dir_path,CONF_FILE_NAME);
}
apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Open Config File [%s]",file_path);
rv = apr_file_open(&fd,file_path,APR_READ|APR_BINARY,0,pool);
if(rv != APR_SUCCESS) {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Open Config File [%s]",file_path);
return NULL;
}
rv = apr_xml_parse_file(pool,&parser,&doc,fd,XML_FILE_BUFFER_LENGTH);
if(rv != APR_SUCCESS) {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Parse Config File [%s]",file_path);
return NULL;
}
apr_file_close(fd);
return doc;
}
static apt_bool_t param_name_value_get(const apr_xml_elem *elem, const apr_xml_attr **name, const apr_xml_attr **value)
{
const apr_xml_attr *attr;
if(!name || !value) {
return FALSE;
}
*name = NULL;
*value = NULL;
for(attr = elem->attr; attr; attr = attr->next) {
if(strcasecmp(attr->name,"name") == 0) {
*name = attr;
}
else if(strcasecmp(attr->name,"value") == 0) {
*value = attr;
}
}
return (*name && *value) ? TRUE : FALSE;
}
static char* ip_addr_get(const char *value, apr_pool_t *pool)
{
if(!value || strcasecmp(value,"auto") == 0) {
char *addr = DEFAULT_IP_ADDRESS;
apt_ip_get(&addr,pool);
return addr;
}
return apr_pstrdup(pool,value);
}
/** Load map of MRCP resource names */
static apt_bool_t resource_map_load(apr_table_t *resource_map, const apr_xml_elem *root, apr_pool_t *pool)
{
const apr_xml_attr *attr_name;
const apr_xml_attr *attr_value;
const apr_xml_elem *elem;
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Resource Map");
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"param") == 0) {
if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) {
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value);
apr_table_set(resource_map,attr_name->value,attr_value->value);
}
}
}
return TRUE;
}
/** Load map of plugins */
static apt_bool_t plugin_map_load(apr_table_t *plugin_map, const apr_xml_elem *root, apr_pool_t *pool)
{
const apr_xml_attr *attr_name;
const apr_xml_attr *attr_value;
const apr_xml_elem *elem;
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Plugin Map");
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"param") == 0) {
if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) {
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value);
apr_table_set(plugin_map,attr_name->value,attr_value->value);
}
}
}
return TRUE;
}
/** Load SofiaSIP signaling agent */
static mrcp_sig_agent_t* unimrcp_server_sofiasip_agent_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool)
{
const apr_xml_elem *elem;
mrcp_sofia_server_config_t *config = mrcp_sofiasip_server_config_alloc(pool);
config->local_ip = DEFAULT_IP_ADDRESS;
config->local_port = DEFAULT_SIP_PORT;
config->ext_ip = NULL;
config->user_agent_name = DEFAULT_SOFIASIP_UA_NAME;
config->origin = DEFAULT_SDP_ORIGIN;
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading SofiaSIP Agent");
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"param") == 0) {
const apr_xml_attr *attr_name;
const apr_xml_attr *attr_value;
if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) {
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value);
if(strcasecmp(attr_name->value,"sip-ip") == 0) {
config->local_ip = ip_addr_get(attr_value->value,pool);
}
else if(strcasecmp(attr_name->value,"sip-ext-ip") == 0) {
config->ext_ip = ip_addr_get(attr_value->value,pool);
}
else if(strcasecmp(attr_name->value,"sip-port") == 0) {
config->local_port = (apr_port_t)atol(attr_value->value);
}
else if(strcasecmp(attr_name->value,"sip-transport") == 0) {
config->transport = apr_pstrdup(pool,attr_value->value);
}
else if(strcasecmp(attr_name->value,"ua-name") == 0) {
config->user_agent_name = apr_pstrdup(pool,attr_value->value);
}
else if(strcasecmp(attr_name->value,"sdp-origin") == 0) {
config->origin = apr_pstrdup(pool,attr_value->value);
}
else if(strcasecmp(attr_name->value,"force-destination") == 0) {
config->force_destination = atoi(attr_value->value);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value);
}
}
}
}
return mrcp_sofiasip_server_agent_create(config,pool);
}
/** Load UniRTSP signaling agent */
static mrcp_sig_agent_t* unimrcp_server_rtsp_agent_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool)
{
const apr_xml_elem *elem;
rtsp_server_config_t *config = mrcp_unirtsp_server_config_alloc(pool);
config->local_ip = DEFAULT_IP_ADDRESS;
config->local_port = DEFAULT_RTSP_PORT;
config->origin = DEFAULT_SDP_ORIGIN;
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading UniRTSP Agent");
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"param") == 0) {
const apr_xml_attr *attr_name;
const apr_xml_attr *attr_value;
if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) {
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value);
if(strcasecmp(attr_name->value,"rtsp-ip") == 0) {
config->local_ip = ip_addr_get(attr_value->value,pool);
}
else if(strcasecmp(attr_name->value,"rtsp-port") == 0) {
config->local_port = (apr_port_t)atol(attr_value->value);
}
else if(strcasecmp(attr_name->value,"sdp-origin") == 0) {
config->origin = apr_pstrdup(pool,attr_value->value);
}
else if(strcasecmp(attr_name->value,"max-connection-count") == 0) {
config->max_connection_count = atol(attr_value->value);
}
else if(strcasecmp(attr_name->value,"force-destination") == 0) {
config->force_destination = atoi(attr_value->value);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value);
}
}
}
else if(strcasecmp(elem->name,"resourcemap") == 0) {
resource_map_load(config->resource_map,elem,pool);
}
}
return mrcp_unirtsp_server_agent_create(config,pool);
}
/** Load signaling agents */
static apt_bool_t unimrcp_server_signaling_agents_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool)
{
const apr_xml_elem *elem;
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Signaling Agents");
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"agent") == 0) {
mrcp_sig_agent_t *sig_agent = NULL;
const char *name = NULL;
const apr_xml_attr *attr;
for(attr = elem->attr; attr; attr = attr->next) {
if(strcasecmp(attr->name,"name") == 0) {
name = apr_pstrdup(pool,attr->value);
}
else if(strcasecmp(attr->name,"class") == 0) {
if(strcasecmp(attr->value,"SofiaSIP") == 0) {
sig_agent = unimrcp_server_sofiasip_agent_load(server,elem,pool);
}
else if(strcasecmp(attr->value,"UniRTSP") == 0) {
sig_agent = unimrcp_server_rtsp_agent_load(server,elem,pool);
}
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name);
}
}
if(sig_agent) {
mrcp_server_signaling_agent_register(server,sig_agent,name);
}
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name);
}
}
return TRUE;
}
/** Load MRCPv2 connection agent */
static mrcp_connection_agent_t* unimrcp_server_connection_agent_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool)
{
const apr_xml_elem *elem;
char *mrcp_ip = DEFAULT_IP_ADDRESS;
apr_port_t mrcp_port = DEFAULT_MRCP_PORT;
apr_size_t max_connection_count = 100;
apt_bool_t force_new_connection = FALSE;
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading MRCPv2 Agent");
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"param") == 0) {
const apr_xml_attr *attr_name;
const apr_xml_attr *attr_value;
if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) {
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value);
if(strcasecmp(attr_name->value,"mrcp-ip") == 0) {
mrcp_ip = ip_addr_get(attr_value->value,pool);
}
else if(strcasecmp(attr_name->value,"mrcp-port") == 0) {
mrcp_port = (apr_port_t)atol(attr_value->value);
}
else if(strcasecmp(attr_name->value,"max-connection-count") == 0) {
max_connection_count = atol(attr_value->value);
}
else if(strcasecmp(attr_name->value,"force-new-connection") == 0) {
force_new_connection = atoi(attr_value->value);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value);
}
}
}
}
return mrcp_server_connection_agent_create(mrcp_ip,mrcp_port,max_connection_count,force_new_connection,pool);
}
/** Load MRCPv2 conection agents */
static apt_bool_t unimrcp_server_connection_agents_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool)
{
const apr_xml_elem *elem;
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Connection Agents");
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"agent") == 0) {
mrcp_connection_agent_t *connection_agent;
const char *name = NULL;
const apr_xml_attr *attr;
for(attr = elem->attr; attr; attr = attr->next) {
if(strcasecmp(attr->name,"name") == 0) {
name = apr_pstrdup(pool,attr->value);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name);
}
}
connection_agent = unimrcp_server_connection_agent_load(server,elem,pool);
if(connection_agent) {
mrcp_server_connection_agent_register(server,connection_agent,name);
}
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name);
}
}
return TRUE;
}
/** Load RTP termination factory */
static mpf_termination_factory_t* unimrcp_server_rtp_factory_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool)
{
const apr_xml_elem *elem;
char *rtp_ip = DEFAULT_IP_ADDRESS;
char *rtp_ext_ip = NULL;
mpf_rtp_config_t *rtp_config = mpf_rtp_config_create(pool);
rtp_config->rtp_port_min = DEFAULT_RTP_PORT_MIN;
rtp_config->rtp_port_max = DEFAULT_RTP_PORT_MAX;
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading RTP Termination Factory");
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"param") == 0) {
const apr_xml_attr *attr_name;
const apr_xml_attr *attr_value;
if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) {
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Param %s:%s",attr_name->value,attr_value->value);
if(strcasecmp(attr_name->value,"rtp-ip") == 0) {
rtp_ip = ip_addr_get(attr_value->value,pool);
}
else if(strcasecmp(attr_name->value,"rtp-ext-ip") == 0) {
rtp_ext_ip = ip_addr_get(attr_value->value,pool);
}
else if(strcasecmp(attr_name->value,"rtp-port-min") == 0) {
rtp_config->rtp_port_min = (apr_port_t)atol(attr_value->value);
}
else if(strcasecmp(attr_name->value,"rtp-port-max") == 0) {
rtp_config->rtp_port_max = (apr_port_t)atol(attr_value->value);
}
else if(strcasecmp(attr_name->value,"playout-delay") == 0) {
rtp_config->jb_config.initial_playout_delay = atol(attr_value->value);
}
else if(strcasecmp(attr_name->value,"min-playout-delay") == 0) {
rtp_config->jb_config.min_playout_delay = atol(attr_value->value);
}
else if(strcasecmp(attr_name->value,"max-playout-delay") == 0) {
rtp_config->jb_config.max_playout_delay = atol(attr_value->value);
}
else if(strcasecmp(attr_name->value,"codecs") == 0) {
const mpf_codec_manager_t *codec_manager = mrcp_server_codec_manager_get(server);
if(codec_manager) {
mpf_codec_manager_codec_list_load(codec_manager,&rtp_config->codec_list,attr_value->value,pool);
}
}
else if(strcasecmp(attr_name->value,"ptime") == 0) {
rtp_config->ptime = (apr_uint16_t)atol(attr_value->value);
}
else if(strcasecmp(attr_name->value,"own-preference") == 0) {
rtp_config->own_preferrence = atoi(attr_value->value);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value);
}
}
}
}
apt_string_set(&rtp_config->ip,rtp_ip);
if(rtp_ext_ip) {
apt_string_set(&rtp_config->ext_ip,rtp_ext_ip);
}
return mpf_rtp_termination_factory_create(rtp_config,pool);
}
/** Load media engines */
static apt_bool_t unimrcp_server_media_engines_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool)
{
const apr_xml_elem *elem;
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Media Engines");
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"engine") == 0) {
mpf_engine_t *media_engine;
const char *name = NULL;
const apr_xml_attr *attr;
for(attr = elem->attr; attr; attr = attr->next) {
if(strcasecmp(attr->name,"name") == 0) {
name = apr_pstrdup(pool,attr->value);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name);
}
}
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Media Engine");
media_engine = mpf_engine_create(pool);
if(media_engine) {
mrcp_server_media_engine_register(server,media_engine,name);
}
}
else if(strcasecmp(elem->name,"rtp") == 0) {
mpf_termination_factory_t *rtp_factory;
const char *name = NULL;
const apr_xml_attr *attr;
for(attr = elem->attr; attr; attr = attr->next) {
if(strcasecmp(attr->name,"name") == 0) {
name = apr_pstrdup(pool,attr->value);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name);
}
}
rtp_factory = unimrcp_server_rtp_factory_load(server,elem,pool);
if(rtp_factory) {
mrcp_server_rtp_factory_register(server,rtp_factory,name);
}
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name);
}
}
return TRUE;
}
/** Load plugin */
static apt_bool_t unimrcp_server_plugin_load(mrcp_server_t *server, const char *plugin_dir_path, const apr_xml_elem *root, apr_pool_t *pool)
{
const char *plugin_name = NULL;
const char *plugin_class = NULL;
const char *plugin_ext = NULL;
const char *plugin_path = NULL;
apt_bool_t plugin_enabled = TRUE;
const apr_xml_attr *attr;
for(attr = root->attr; attr; attr = attr->next) {
if(strcasecmp(attr->name,"name") == 0) {
plugin_name = apr_pstrdup(pool,attr->value);
}
else if(strcasecmp(attr->name,"class") == 0) {
plugin_class = attr->value;
}
else if(strcasecmp(attr->name,"ext") == 0) {
plugin_ext = attr->value;
}
else if(strcasecmp(attr->name,"enable") == 0) {
plugin_enabled = atoi(attr->value);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name);
}
}
if(!plugin_class || !plugin_enabled) {
return FALSE;
}
if(!plugin_dir_path) {
plugin_dir_path = DEFAULT_PLUGIN_DIR_PATH;
}
if(!plugin_ext) {
plugin_ext = DEFAULT_PLUGIN_EXT;
}
if(*plugin_dir_path == '\0') {
plugin_path = apr_psprintf(pool,"%s.%s",plugin_class,plugin_ext);
}
else {
plugin_path = apr_psprintf(pool,"%s/%s.%s",plugin_dir_path,plugin_class,plugin_ext);
}
return mrcp_server_plugin_register(server,plugin_path,plugin_name);
}
/** Load plugins */
static apt_bool_t unimrcp_server_plugins_load(mrcp_server_t *server, const char *plugin_dir_path, const apr_xml_elem *root, apr_pool_t *pool)
{
const apr_xml_elem *elem;
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Plugins (Resource Engines)");
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"engine") == 0) {
unimrcp_server_plugin_load(server,plugin_dir_path,elem,pool);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name);
}
}
return TRUE;
}
/** Load settings */
static apt_bool_t unimrcp_server_settings_load(mrcp_server_t *server, const char *plugin_dir_path, const apr_xml_elem *root, apr_pool_t *pool)
{
const apr_xml_elem *elem;
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Settings");
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"signaling") == 0) {
unimrcp_server_signaling_agents_load(server,elem,pool);
}
else if(strcasecmp(elem->name,"connection") == 0) {
unimrcp_server_connection_agents_load(server,elem,pool);
}
else if(strcasecmp(elem->name,"media") == 0) {
unimrcp_server_media_engines_load(server,elem,pool);
}
else if(strcasecmp(elem->name,"plugin") == 0) {
unimrcp_server_plugins_load(server,plugin_dir_path,elem,pool);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name);
}
}
return TRUE;
}
/** Load profile */
static apt_bool_t unimrcp_server_profile_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool)
{
const char *name = NULL;
mrcp_profile_t *profile;
mrcp_sig_agent_t *sig_agent = NULL;
mrcp_connection_agent_t *cnt_agent = NULL;
mpf_engine_t *media_engine = NULL;
mpf_termination_factory_t *rtp_factory = NULL;
apr_table_t *plugin_map = NULL;
const apr_xml_elem *elem;
const apr_xml_attr *attr;
for(attr = root->attr; attr; attr = attr->next) {
if(strcasecmp(attr->name,"name") == 0) {
name = apr_pstrdup(pool,attr->value);
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Profile [%s]",name);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr->name);
}
}
if(!name) {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Failed to Load Profile: no profile name specified");
return FALSE;
}
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"param") == 0) {
const apr_xml_attr *attr_name;
const apr_xml_attr *attr_value;
if(param_name_value_get(elem,&attr_name,&attr_value) == TRUE) {
apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Loading Profile %s [%s]",attr_name->value,attr_value->value);
if(strcasecmp(attr_name->value,"signaling-agent") == 0) {
sig_agent = mrcp_server_signaling_agent_get(server,attr_value->value);
}
else if(strcasecmp(attr_name->value,"connection-agent") == 0) {
cnt_agent = mrcp_server_connection_agent_get(server,attr_value->value);
}
else if(strcasecmp(attr_name->value,"media-engine") == 0) {
media_engine = mrcp_server_media_engine_get(server,attr_value->value);
}
else if(strcasecmp(attr_name->value,"rtp-factory") == 0) {
rtp_factory = mrcp_server_rtp_factory_get(server,attr_value->value);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Attribute <%s>",attr_name->value);
}
}
}
else if(strcasecmp(elem->name,"pluginmap") == 0) {
plugin_map = apr_table_make(pool,2);
plugin_map_load(plugin_map,elem,pool);
}
}
apt_log(APT_LOG_MARK,APT_PRIO_NOTICE,"Create Profile [%s]",name);
profile = mrcp_server_profile_create(NULL,sig_agent,cnt_agent,media_engine,rtp_factory,pool);
return mrcp_server_profile_register(server,profile,plugin_map,name);
}
/** Load profiles */
static apt_bool_t unimrcp_server_profiles_load(mrcp_server_t *server, const apr_xml_elem *root, apr_pool_t *pool)
{
const apr_xml_elem *elem;
apt_log(APT_LOG_MARK,APT_PRIO_DEBUG,"Loading Profiles");
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"profile") == 0) {
unimrcp_server_profile_load(server,elem,pool);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name);
}
}
return TRUE;
}
/** Load configuration (settings and profiles) */
static apt_bool_t unimrcp_server_config_load(mrcp_server_t *server, const char *plugin_dir_path, const apr_xml_doc *doc, apr_pool_t *pool)
{
const apr_xml_elem *elem;
const apr_xml_elem *root = doc->root;
if(!root || strcasecmp(root->name,"unimrcpserver") != 0) {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Document");
return FALSE;
}
for(elem = root->first_child; elem; elem = elem->next) {
if(strcasecmp(elem->name,"settings") == 0) {
unimrcp_server_settings_load(server,plugin_dir_path,elem,pool);
}
else if(strcasecmp(elem->name,"profiles") == 0) {
unimrcp_server_profiles_load(server,elem,pool);
}
else {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"Unknown Element <%s>",elem->name);
}
}
return TRUE;
}