Skip to content
项目
群组
代码片段
帮助
正在加载...
登录
切换导航
F
freeswitch
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
张华
freeswitch
Commits
15218697
提交
15218697
authored
8月 16, 2011
作者:
Marc Olivier Chouinard
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
mod_protovm: Removal of the proto vm. Might reinclude it under a different name in the future.
上级
d48edc53
隐藏空白字符变更
内嵌
并排
正在显示
12 个修改的文件
包含
0 行增加
和
2149 行删除
+0
-2149
Makefile
src/mod/applications/mod_protovm/Makefile
+0
-3
config.c
src/mod/applications/mod_protovm/config.c
+0
-135
config.h
src/mod/applications/mod_protovm/config.h
+0
-53
ivr.c
src/mod/applications/mod_protovm/ivr.c
+0
-250
ivr.h
src/mod/applications/mod_protovm/ivr.h
+0
-30
menu.c
src/mod/applications/mod_protovm/menu.c
+0
-743
menu.h
src/mod/applications/mod_protovm/menu.h
+0
-32
mod_protovm.c
src/mod/applications/mod_protovm/mod_protovm.c
+0
-139
protovm.conf.xml
src/mod/applications/mod_protovm/protovm.conf.xml
+0
-176
sounds.xml
src/mod/applications/mod_protovm/sounds.xml
+0
-397
util.c
src/mod/applications/mod_protovm/util.c
+0
-175
util.h
src/mod/applications/mod_protovm/util.h
+0
-16
没有找到文件。
src/mod/applications/mod_protovm/Makefile
deleted
100644 → 0
浏览文件 @
d48edc53
BASE
=
../../../..
LOCAL_OBJS
=
ivr.o util.o config.o menu.o
include
$(BASE)/build/modmake.rules
src/mod/applications/mod_protovm/config.c
deleted
100644 → 0
浏览文件 @
d48edc53
/* Copy paste from FS mod_voicemail */
#include <switch.h>
#include "config.h"
const
char
*
global_cf
=
"protovm.conf"
;
void
populate_profile_menu_event
(
vmivr_profile_t
*
profile
,
vmivr_menu_profile_t
*
menu
)
{
switch_xml_t
cfg
,
xml
,
x_profiles
,
x_profile
,
x_keys
,
x_phrases
,
x_menus
,
x_menu
;
free_profile_menu_event
(
menu
);
if
(
!
(
xml
=
switch_xml_open_cfg
(
global_cf
,
&
cfg
,
NULL
)))
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Open of %s failed
\n
"
,
global_cf
);
goto
end
;
}
if
(
!
(
x_profiles
=
switch_xml_child
(
cfg
,
"profiles"
)))
{
goto
end
;
}
if
((
x_profile
=
switch_xml_find_child
(
x_profiles
,
"profile"
,
"name"
,
profile
->
name
)))
{
if
((
x_menus
=
switch_xml_child
(
x_profile
,
"menus"
)))
{
if
((
x_menu
=
switch_xml_find_child
(
x_menus
,
"menu"
,
"name"
,
menu
->
name
)))
{
if
((
x_keys
=
switch_xml_child
(
x_menu
,
"keys"
)))
{
switch_event_import_xml
(
switch_xml_child
(
x_keys
,
"key"
),
"dtmf"
,
"action"
,
&
menu
->
event_keys_dtmf
);
switch_event_import_xml
(
switch_xml_child
(
x_keys
,
"key"
),
"action"
,
"dtmf"
,
&
menu
->
event_keys_action
);
switch_event_import_xml
(
switch_xml_child
(
x_keys
,
"key"
),
"action"
,
"variable"
,
&
menu
->
event_keys_varname
);
}
if
((
x_phrases
=
switch_xml_child
(
x_menu
,
"phrases"
)))
{
switch_event_import_xml
(
switch_xml_child
(
x_phrases
,
"phrase"
),
"name"
,
"value"
,
&
menu
->
event_phrases
);
}
}
}
}
end:
if
(
xml
)
switch_xml_free
(
xml
);
return
;
}
void
free_profile_menu_event
(
vmivr_menu_profile_t
*
menu
)
{
if
(
menu
->
event_keys_dtmf
)
{
switch_event_destroy
(
&
menu
->
event_keys_dtmf
);
}
if
(
menu
->
event_keys_action
)
{
switch_event_destroy
(
&
menu
->
event_keys_action
);
}
if
(
menu
->
event_keys_varname
)
{
switch_event_destroy
(
&
menu
->
event_keys_varname
);
}
if
(
menu
->
event_phrases
)
{
switch_event_destroy
(
&
menu
->
event_phrases
);
}
}
vmivr_profile_t
*
get_profile
(
switch_core_session_t
*
session
,
const
char
*
profile_name
)
{
vmivr_profile_t
*
profile
=
NULL
;
switch_xml_t
cfg
,
xml
,
x_profiles
,
x_profile
,
x_apis
,
param
;
if
(
!
(
xml
=
switch_xml_open_cfg
(
global_cf
,
&
cfg
,
NULL
)))
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Open of %s failed
\n
"
,
global_cf
);
return
profile
;
}
if
(
!
(
x_profiles
=
switch_xml_child
(
cfg
,
"profiles"
)))
{
goto
end
;
}
if
((
x_profile
=
switch_xml_find_child
(
x_profiles
,
"profile"
,
"name"
,
profile_name
)))
{
if
(
!
(
profile
=
switch_core_session_alloc
(
session
,
sizeof
(
vmivr_profile_t
))))
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_CRIT
,
"Alloc Failure
\n
"
);
goto
end
;
}
profile
->
name
=
profile_name
;
profile
->
current_msg
=
0
;
profile
->
current_msg_uuid
=
NULL
;
/* TODO Make the following configurable */
profile
->
api_profile
=
profile
->
name
;
profile
->
menu_check_auth
=
"std_authenticate"
;
profile
->
menu_check_main
=
"std_navigator"
;
profile
->
menu_check_terminate
=
"std_purge"
;
if
((
x_apis
=
switch_xml_child
(
x_profile
,
"apis"
)))
{
int
total_options
=
0
;
int
total_invalid_options
=
0
;
for
(
param
=
switch_xml_child
(
x_apis
,
"api"
);
param
;
param
=
param
->
next
)
{
char
*
var
,
*
val
;
if
((
var
=
(
char
*
)
switch_xml_attr_soft
(
param
,
"name"
))
&&
(
val
=
(
char
*
)
switch_xml_attr_soft
(
param
,
"value"
)))
{
if
(
!
strcasecmp
(
var
,
"msg_undelete"
)
&&
!
profile
->
api_msg_undelete
)
profile
->
api_msg_undelete
=
switch_core_session_strdup
(
session
,
val
);
else
if
(
!
strcasecmp
(
var
,
"msg_delete"
)
&&
!
profile
->
api_msg_delete
)
profile
->
api_msg_delete
=
switch_core_session_strdup
(
session
,
val
);
else
if
(
!
strcasecmp
(
var
,
"msg_list"
)
&&
!
profile
->
api_msg_list
)
profile
->
api_msg_list
=
switch_core_session_strdup
(
session
,
val
);
else
if
(
!
strcasecmp
(
var
,
"msg_count"
)
&&
!
profile
->
api_msg_count
)
profile
->
api_msg_count
=
switch_core_session_strdup
(
session
,
val
);
else
if
(
!
strcasecmp
(
var
,
"msg_save"
)
&&
!
profile
->
api_msg_save
)
profile
->
api_msg_save
=
switch_core_session_strdup
(
session
,
val
);
else
if
(
!
strcasecmp
(
var
,
"msg_purge"
)
&&
!
profile
->
api_msg_purge
)
profile
->
api_msg_purge
=
switch_core_session_strdup
(
session
,
val
);
else
if
(
!
strcasecmp
(
var
,
"msg_get"
)
&&
!
profile
->
api_msg_get
)
profile
->
api_msg_get
=
switch_core_session_strdup
(
session
,
val
);
else
if
(
!
strcasecmp
(
var
,
"msg_forward"
)
&&
!
profile
->
api_msg_forward
)
profile
->
api_msg_forward
=
switch_core_session_strdup
(
session
,
val
);
else
if
(
!
strcasecmp
(
var
,
"pref_greeting_set"
)
&&
!
profile
->
api_pref_greeting_set
)
profile
->
api_pref_greeting_set
=
switch_core_session_strdup
(
session
,
val
);
else
if
(
!
strcasecmp
(
var
,
"pref_recname_set"
)
&&
!
profile
->
api_pref_recname_set
)
profile
->
api_pref_recname_set
=
switch_core_session_strdup
(
session
,
val
);
else
if
(
!
strcasecmp
(
var
,
"pref_password_set"
)
&&
!
profile
->
api_pref_password_set
)
profile
->
api_pref_password_set
=
switch_core_session_strdup
(
session
,
val
);
else
if
(
!
strcasecmp
(
var
,
"auth_login"
)
&&
!
profile
->
api_auth_login
)
profile
->
api_auth_login
=
switch_core_session_strdup
(
session
,
val
);
else
total_invalid_options
++
;
total_options
++
;
}
}
if
(
total_options
-
total_invalid_options
!=
12
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Missing api definition for profile '%s'
\n
"
,
profile_name
);
profile
=
NULL
;
}
}
}
end:
switch_xml_free
(
xml
);
return
profile
;
}
src/mod/applications/mod_protovm/config.h
deleted
100644 → 0
浏览文件 @
d48edc53
#ifndef _CONFIG_H_
#define _CONFIG_H_
extern
const
char
*
global_cf
;
struct
vmivr_profile
{
const
char
*
name
;
const
char
*
domain
;
const
char
*
id
;
int
current_msg
;
const
char
*
current_msg_uuid
;
const
char
*
menu_check_auth
;
const
char
*
menu_check_main
;
const
char
*
menu_check_terminate
;
switch_bool_t
authorized
;
const
char
*
api_profile
;
const
char
*
api_auth_login
;
const
char
*
api_msg_delete
;
const
char
*
api_msg_undelete
;
const
char
*
api_msg_list
;
const
char
*
api_msg_count
;
const
char
*
api_msg_save
;
const
char
*
api_msg_purge
;
const
char
*
api_msg_get
;
const
char
*
api_msg_forward
;
const
char
*
api_pref_greeting_set
;
const
char
*
api_pref_recname_set
;
const
char
*
api_pref_password_set
;
};
typedef
struct
vmivr_profile
vmivr_profile_t
;
struct
vmivr_menu_profile
{
const
char
*
name
;
switch_event_t
*
event_keys_action
;
switch_event_t
*
event_keys_dtmf
;
switch_event_t
*
event_keys_varname
;
switch_event_t
*
event_phrases
;
};
typedef
struct
vmivr_menu_profile
vmivr_menu_profile_t
;
vmivr_profile_t
*
get_profile
(
switch_core_session_t
*
session
,
const
char
*
profile_name
);
void
free_profile_menu_event
(
vmivr_menu_profile_t
*
menu
);
void
populate_profile_menu_event
(
vmivr_profile_t
*
profile
,
vmivr_menu_profile_t
*
menu
);
#endif
/* _CONFIG_H_ */
src/mod/applications/mod_protovm/ivr.c
deleted
100644 → 0
浏览文件 @
d48edc53
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
*
* 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 <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Marc Olivier Chouinard <mochouinard@moctel.com>
*
*
* ivr.c -- MT IVR System Interface
*
*/
#include <switch.h>
#include "ivr.h"
int
match_dtmf
(
switch_core_session_t
*
session
,
dtmf_ss_t
*
loc
)
{
switch_bool_t
is_invalid
[
128
]
=
{
SWITCH_FALSE
};
int
i
;
loc
->
potentialMatch
=
NULL
;
loc
->
completeMatch
=
NULL
;
loc
->
potentialMatchCount
=
0
;
for
(
i
=
0
;
i
<
loc
->
dtmf_received
;
i
++
)
{
int
j
;
loc
->
potentialMatchCount
=
0
;
for
(
j
=
0
;
!
zstr
(
loc
->
dtmf_accepted
[
j
])
&&
j
<
128
;
j
++
)
{
switch_bool_t
cMatch
=
SWITCH_FALSE
;
char
test
[
2
]
=
{
0
};
if
(
is_invalid
[
j
])
continue
;
test
[
0
]
=
loc
->
dtmf_stored
[
i
];
if
(
loc
->
dtmf_accepted
[
j
][
i
]
==
'N'
&&
atoi
(
test
)
>=
2
&&
atoi
(
test
)
<=
9
)
cMatch
=
SWITCH_TRUE
;
if
(
loc
->
dtmf_accepted
[
j
][
i
]
==
'X'
&&
atoi
(
test
)
>=
0
&&
atoi
(
test
)
<=
9
)
{
cMatch
=
SWITCH_TRUE
;
}
if
(
i
>=
strlen
(
loc
->
dtmf_accepted
[
j
])
-
1
&&
loc
->
dtmf_accepted
[
j
][
strlen
(
loc
->
dtmf_accepted
[
j
])
-
1
]
==
'.'
)
cMatch
=
SWITCH_TRUE
;
if
(
loc
->
dtmf_accepted
[
j
][
i
]
==
loc
->
dtmf_stored
[
i
])
cMatch
=
SWITCH_TRUE
;
if
(
cMatch
==
SWITCH_FALSE
)
{
is_invalid
[
j
]
=
SWITCH_TRUE
;
continue
;
}
if
(
i
==
strlen
(
loc
->
dtmf_accepted
[
j
])
-
1
&&
loc
->
dtmf_accepted
[
j
][
strlen
(
loc
->
dtmf_accepted
[
j
])
-
1
]
==
'.'
)
{
loc
->
completeMatch
=
loc
->
dtmf_accepted
[
j
];
}
if
(
i
==
loc
->
dtmf_received
-
1
&&
loc
->
dtmf_received
==
strlen
(
loc
->
dtmf_accepted
[
j
])
&&
loc
->
dtmf_accepted
[
j
][
strlen
(
loc
->
dtmf_accepted
[
j
])
-
1
]
!=
'.'
)
{
loc
->
completeMatch
=
loc
->
dtmf_accepted
[
j
];
continue
;
}
loc
->
potentialMatchCount
++
;
}
}
return
1
;
}
static
switch_status_t
cb_on_dtmf_ignore
(
switch_core_session_t
*
session
,
void
*
input
,
switch_input_type_t
itype
,
void
*
buf
,
unsigned
int
buflen
)
{
switch
(
itype
)
{
case
SWITCH_INPUT_TYPE_DTMF
:
{
switch_channel_t
*
channel
=
switch_core_session_get_channel
(
session
);
switch_dtmf_t
*
dtmf
=
(
switch_dtmf_t
*
)
input
;
switch_channel_queue_dtmf
(
channel
,
dtmf
);
return
SWITCH_STATUS_BREAK
;
}
default:
break
;
}
return
SWITCH_STATUS_SUCCESS
;
}
static
switch_status_t
cb_on_dtmf
(
switch_core_session_t
*
session
,
void
*
input
,
switch_input_type_t
itype
,
void
*
buf
,
unsigned
int
buflen
)
{
dtmf_ss_t
*
loc
=
(
dtmf_ss_t
*
)
buf
;
switch
(
itype
)
{
case
SWITCH_INPUT_TYPE_DTMF
:
{
switch_dtmf_t
*
dtmf
=
(
switch_dtmf_t
*
)
input
;
switch_bool_t
audio_was_stopped
=
loc
->
audio_stopped
;
loc
->
audio_stopped
=
SWITCH_TRUE
;
if
(
loc
->
dtmf_received
>=
sizeof
(
loc
->
dtmf_stored
))
{
loc
->
result
=
RES_BUFFER_OVERFLOW
;
break
;
}
if
(
!
loc
->
terminate_key
||
dtmf
->
digit
!=
loc
->
terminate_key
)
loc
->
dtmf_stored
[
loc
->
dtmf_received
++
]
=
dtmf
->
digit
;
match_dtmf
(
session
,
loc
);
if
(
loc
->
terminate_key
&&
dtmf
->
digit
==
loc
->
terminate_key
&&
loc
->
result
==
RES_WAITFORMORE
)
{
if
(
loc
->
potentialMatchCount
==
1
&&
loc
->
completeMatch
!=
NULL
)
{
loc
->
result
=
RES_FOUND
;
}
else
{
loc
->
result
=
RES_INVALID
;
}
return
SWITCH_STATUS_BREAK
;
}
else
{
if
(
loc
->
potentialMatchCount
==
0
&&
loc
->
completeMatch
!=
NULL
)
{
loc
->
result
=
RES_FOUND
;
return
SWITCH_STATUS_BREAK
;
}
else
if
(
loc
->
potentialMatchCount
>
0
)
{
loc
->
result
=
RES_WAITFORMORE
;
if
(
!
audio_was_stopped
)
return
SWITCH_STATUS_BREAK
;
}
else
{
loc
->
result
=
RES_INVALID
;
return
SWITCH_STATUS_BREAK
;
}
}
}
break
;
default:
break
;
}
return
SWITCH_STATUS_SUCCESS
;
}
switch_status_t
captureMenuInitialize
(
dtmf_ss_t
*
loc
,
char
**
dtmf_accepted
)
{
int
i
;
memset
(
loc
,
0
,
sizeof
(
*
loc
));
for
(
i
=
0
;
dtmf_accepted
[
i
]
&&
i
<
16
;
i
++
)
{
strncpy
(
loc
->
dtmf_accepted
[
i
],
dtmf_accepted
[
i
],
128
);
}
return
SWITCH_STATUS_SUCCESS
;
}
switch_status_t
playbackBufferDTMF
(
switch_core_session_t
*
session
,
const
char
*
macro_name
,
const
char
*
data
,
switch_event_t
*
event
,
const
char
*
lang
,
int
timeout
)
{
switch_status_t
status
=
SWITCH_STATUS_SUCCESS
;
switch_channel_t
*
channel
=
switch_core_session_get_channel
(
session
);
if
(
switch_channel_ready
(
channel
))
{
switch_input_args_t
args
=
{
0
};
args
.
input_callback
=
cb_on_dtmf_ignore
;
if
(
macro_name
)
{
status
=
switch_ivr_phrase_macro_event
(
session
,
macro_name
,
data
,
event
,
lang
,
&
args
);
}
}
else
{
status
=
SWITCH_STATUS_BREAK
;
}
return
status
;
}
switch_status_t
captureMenu
(
switch_core_session_t
*
session
,
dtmf_ss_t
*
loc
,
const
char
*
macro_name
,
const
char
*
data
,
switch_event_t
*
event
,
const
char
*
lang
,
int
timeout
)
{
switch_status_t
status
=
SWITCH_STATUS_SUCCESS
;
switch_channel_t
*
channel
=
switch_core_session_get_channel
(
session
);
if
(
switch_channel_ready
(
channel
))
{
switch_input_args_t
args
=
{
0
};
args
.
input_callback
=
cb_on_dtmf
;
args
.
buf
=
loc
;
if
(
macro_name
&&
loc
->
audio_stopped
==
SWITCH_FALSE
&&
loc
->
result
==
RES_WAITFORMORE
)
{
status
=
switch_ivr_phrase_macro_event
(
session
,
macro_name
,
data
,
event
,
lang
,
&
args
);
}
if
(
switch_channel_ready
(
channel
)
&&
(
status
==
SWITCH_STATUS_SUCCESS
||
status
==
SWITCH_STATUS_BREAK
)
&&
timeout
&&
loc
->
result
==
RES_WAITFORMORE
)
{
loc
->
audio_stopped
=
SWITCH_TRUE
;
switch_ivr_collect_digits_callback
(
session
,
&
args
,
timeout
,
0
);
if
(
loc
->
result
==
RES_WAITFORMORE
)
{
if
(
loc
->
potentialMatchCount
==
1
&&
loc
->
completeMatch
!=
NULL
)
{
loc
->
result
=
RES_FOUND
;
}
else
{
loc
->
result
=
RES_TIMEOUT
;
}
}
}
}
else
{
status
=
SWITCH_STATUS_BREAK
;
}
return
status
;
}
switch_status_t
captureMenuRecord
(
switch_core_session_t
*
session
,
dtmf_ss_t
*
loc
,
switch_event_t
*
event
,
const
char
*
file_path
,
switch_file_handle_t
*
fh
,
int
max_record_len
)
{
switch_status_t
status
=
SWITCH_STATUS_SUCCESS
;
switch_channel_t
*
channel
=
switch_core_session_get_channel
(
session
);
if
(
switch_channel_ready
(
channel
))
{
switch_input_args_t
args
=
{
0
};
args
.
input_callback
=
cb_on_dtmf
;
args
.
buf
=
loc
;
if
(
loc
->
audio_stopped
==
SWITCH_FALSE
&&
loc
->
result
==
RES_WAITFORMORE
)
{
loc
->
recorded_audio
=
SWITCH_TRUE
;
switch_ivr_gentones
(
session
,
"%(1000, 0, 640)"
,
0
,
NULL
);
/* TODO Make this optional and configurable */
status
=
switch_ivr_record_file
(
session
,
fh
,
file_path
,
&
args
,
max_record_len
);
}
if
(
loc
->
result
==
RES_WAITFORMORE
)
{
loc
->
result
=
RES_TIMEOUT
;
}
}
else
{
status
=
SWITCH_STATUS_BREAK
;
}
return
status
;
}
/* 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
*/
src/mod/applications/mod_protovm/ivr.h
deleted
100644 → 0
浏览文件 @
d48edc53
struct
dtmf_ss
{
char
dtmf_stored
[
128
];
int
dtmf_received
;
char
dtmf_accepted
[
16
][
128
];
int
result
;
switch_bool_t
audio_stopped
;
switch_bool_t
recorded_audio
;
const
char
*
potentialMatch
;
int
potentialMatchCount
;
const
char
*
completeMatch
;
char
terminate_key
;
};
typedef
struct
dtmf_ss
dtmf_ss_t
;
#define RES_WAITFORMORE 0
#define RES_FOUND 1
#define RES_INVALID 3
#define RES_TIMEOUT 4
#define RES_BREAK 5
#define RES_RECORD 6
#define RES_BUFFER_OVERFLOW 99
#define MAX_DTMF_SIZE_OPTION 32
switch_status_t
captureMenu
(
switch_core_session_t
*
session
,
dtmf_ss_t
*
loc
,
const
char
*
macro_name
,
const
char
*
data
,
switch_event_t
*
event
,
const
char
*
lang
,
int
timeout
);
switch_status_t
captureMenuRecord
(
switch_core_session_t
*
session
,
dtmf_ss_t
*
loc
,
switch_event_t
*
event
,
const
char
*
file_path
,
switch_file_handle_t
*
fh
,
int
max_record_len
);
switch_status_t
captureMenuInitialize
(
dtmf_ss_t
*
loc
,
char
**
dtmf_accepted
);
switch_status_t
playbackBufferDTMF
(
switch_core_session_t
*
session
,
const
char
*
macro_name
,
const
char
*
data
,
switch_event_t
*
event
,
const
char
*
lang
,
int
timeout
);
src/mod/applications/mod_protovm/menu.c
deleted
100644 → 0
浏览文件 @
d48edc53
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
*
* 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 <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Marc Olivier Chouinard <mochouinard@moctel.com>
*
*
* menu.c -- VoiceMail Menu
*
*/
#include <switch.h>
#include "ivr.h"
#include "menu.h"
#include "util.h"
#include "config.h"
/* List of available menu */
vmivr_menu_function_t
menu_list
[]
=
{
{
"std_authenticate"
,
mtvm_menu_authenticate
},
{
"std_navigator"
,
mtvm_menu_main
},
{
"std_record_name"
,
mtvm_menu_record_name
},
{
"std_set_password"
,
mtvm_menu_set_password
},
{
"std_select_greeting_slot"
,
mtvm_menu_select_greeting_slot
},
{
"std_record_greeting_with_slot"
,
mtvm_menu_record_greeting_with_slot
},
{
"std_preference"
,
mtvm_menu_preference
},
{
"std_purge"
,
mtvm_menu_purge
},
{
"std_forward"
,
mtvm_menu_forward
},
{
NULL
,
NULL
}
};
#define MAX_ATTEMPT 3
/* TODO Make these fields configurable */
#define DEFAULT_IVR_TIMEOUT 3000
void
mtvm_menu_purge
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
{
if
(
profile
->
id
&&
profile
->
authorized
)
{
if
(
1
==
1
/* TODO make Purge email on exit optional ??? */
)
{
const
char
*
cmd
=
switch_core_session_sprintf
(
session
,
"%s %s %s"
,
profile
->
api_profile
,
profile
->
domain
,
profile
->
id
);
mt_api_execute
(
session
,
profile
->
api_msg_purge
,
cmd
);
}
}
}
void
mtvm_menu_main
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
{
switch_channel_t
*
channel
=
switch_core_session_get_channel
(
session
);
switch_event_t
*
msg_list_params
=
NULL
;
size_t
msg_count
=
0
;
size_t
current_msg
=
1
;
size_t
next_msg
=
current_msg
;
size_t
previous_msg
=
current_msg
;
char
*
cmd
=
NULL
;
int
retry
;
/* Different switch to control playback of phrases */
switch_bool_t
initial_count_played
=
SWITCH_FALSE
;
switch_bool_t
skip_header
=
SWITCH_FALSE
;
switch_bool_t
msg_deleted
=
SWITCH_FALSE
;
switch_bool_t
msg_undeleted
=
SWITCH_FALSE
;
switch_bool_t
msg_saved
=
SWITCH_FALSE
;
vmivr_menu_profile_t
menu
=
{
"std_navigator"
};
/* Initialize Menu Configs */
populate_profile_menu_event
(
profile
,
&
menu
);
if
(
!
menu
.
event_keys_dtmf
||
!
menu
.
event_phrases
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Missing Menu Phrases or Keys
\n
"
);
return
;
}
/* Get VoiceMail List And update msg count */
cmd
=
switch_core_session_sprintf
(
session
,
"json %s %s %s"
,
profile
->
api_profile
,
profile
->
domain
,
profile
->
id
);
msg_list_params
=
jsonapi2event
(
session
,
NULL
,
profile
->
api_msg_list
,
cmd
);
msg_count
=
atol
(
switch_event_get_header
(
msg_list_params
,
"VM-List-Count"
));
/* TODO Add Detection of new message and notify the user */
for
(
retry
=
MAX_ATTEMPT
;
switch_channel_ready
(
channel
)
&&
retry
>
0
;
retry
--
)
{
switch_core_session_message_t
msg
=
{
0
};
char
cid_buf
[
1024
]
=
""
;
dtmf_ss_t
loc
;
char
*
dtmfa
[
16
]
=
{
0
};
switch_event_t
*
phrase_params
=
NULL
;
switch_event_create
(
&
phrase_params
,
SWITCH_EVENT_REQUEST_PARAMS
);
append_event_profile
(
phrase_params
,
profile
,
menu
);
populate_dtmfa_from_event
(
phrase_params
,
profile
,
menu
,
dtmfa
);
previous_msg
=
current_msg
;
/* Simple Protection to not go out of msg list scope */
/* TODO: Add Prompt to notify they reached the begining or the end */
if
(
next_msg
==
0
)
{
next_msg
=
1
;
}
else
if
(
next_msg
>
msg_count
)
{
next_msg
=
msg_count
;
}
current_msg
=
next_msg
;
captureMenuInitialize
(
&
loc
,
dtmfa
);
/* Prompt related to previous Message here */
append_event_message
(
session
,
profile
,
phrase_params
,
msg_list_params
,
previous_msg
);
if
(
msg_deleted
)
{
msg_deleted
=
SWITCH_FALSE
;
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"ack"
),
"deleted"
,
phrase_params
,
NULL
,
0
);
}
if
(
msg_undeleted
)
{
msg_undeleted
=
SWITCH_FALSE
;
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"ack"
),
"undeleted"
,
phrase_params
,
NULL
,
0
);
}
if
(
msg_saved
)
{
msg_saved
=
SWITCH_FALSE
;
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"ack"
),
"saved"
,
phrase_params
,
NULL
,
0
);
}
/* Prompt related the current message */
append_event_message
(
session
,
profile
,
phrase_params
,
msg_list_params
,
current_msg
);
/* Save in profile the current msg info for other menu processing AND restoration of our current position */
switch_snprintf
(
cid_buf
,
sizeof
(
cid_buf
),
"%s|%s"
,
switch_str_nil
(
switch_event_get_header
(
phrase_params
,
"VM-Message-Caller-Number"
)),
switch_str_nil
(
switch_event_get_header
(
phrase_params
,
"VM-Message-Caller-Name"
)));
/* Display MSG CID/Name to caller */
msg
.
from
=
__FILE__
;
msg
.
string_arg
=
cid_buf
;
msg
.
message_id
=
SWITCH_MESSAGE_INDICATE_DISPLAY
;
switch_core_session_receive_message
(
session
,
&
msg
);
profile
->
current_msg
=
current_msg
;
profile
->
current_msg_uuid
=
switch_core_session_strdup
(
session
,
switch_event_get_header
(
phrase_params
,
"VM-Message-UUID"
));
/* TODO check if msg is gone (purged by another session, notify user and auto jump to next message or something) */
if
(
!
skip_header
)
{
if
(
!
initial_count_played
)
{
cmd
=
switch_core_session_sprintf
(
session
,
"json %s %s %s"
,
profile
->
api_profile
,
profile
->
domain
,
profile
->
id
);
jsonapi2event
(
session
,
phrase_params
,
profile
->
api_msg_count
,
cmd
);
initial_count_played
=
SWITCH_TRUE
;
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"msg_count"
),
NULL
,
phrase_params
,
NULL
,
0
);
}
if
(
msg_count
>
0
)
{
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"say_msg_number"
),
NULL
,
phrase_params
,
NULL
,
0
);
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"say_date"
),
NULL
,
phrase_params
,
NULL
,
0
);
}
}
if
(
msg_count
>
0
)
{
/* TODO Update the Read date of a message (When msg start, or when it listen compleatly ??? To be determined */
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"play_message"
),
NULL
,
phrase_params
,
NULL
,
0
);
}
skip_header
=
SWITCH_FALSE
;
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"menu_options"
),
NULL
,
phrase_params
,
NULL
,
DEFAULT_IVR_TIMEOUT
);
if
(
loc
.
result
==
RES_TIMEOUT
)
{
/* TODO Ask for the prompt Again IF retry != 0 */
}
else
if
(
loc
.
result
==
RES_INVALID
)
{
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
}
else
if
(
loc
.
result
==
RES_FOUND
)
{
/* Matching DTMF Key Pressed */
const
char
*
action
=
switch_event_get_header
(
menu
.
event_keys_dtmf
,
loc
.
dtmf_stored
);
/* Reset the try count */
retry
=
MAX_ATTEMPT
;
if
(
action
)
{
if
(
!
strcasecmp
(
action
,
"skip_intro"
))
{
/* Skip Header / Play the recording again */
skip_header
=
SWITCH_TRUE
;
}
else
if
(
!
strcasecmp
(
action
,
"next_msg"
))
{
/* Next Message */
next_msg
++
;
}
else
if
(
!
strcasecmp
(
action
,
"prev_msg"
))
{
/* Previous Message */
next_msg
--
;
}
else
if
(
!
strcasecmp
(
action
,
"delete_msg"
))
{
/* Delete / Undelete Message */
const
char
*
msg_flags
=
switch_event_get_header
(
phrase_params
,
"VM-Message-Flags"
);
if
(
!
msg_flags
||
strncasecmp
(
msg_flags
,
"delete"
,
6
))
{
cmd
=
switch_core_session_sprintf
(
session
,
"%s %s %s %s"
,
profile
->
api_profile
,
profile
->
domain
,
profile
->
id
,
switch_event_get_header
(
phrase_params
,
"VM-Message-UUID"
));
mt_api_execute
(
session
,
profile
->
api_msg_delete
,
cmd
);
msg_deleted
=
SWITCH_TRUE
;
/* TODO Option for auto going to next message or just return to the menu (So user used to do 76 to delete and next message wont be confused) */
next_msg
++
;
}
else
{
cmd
=
switch_core_session_sprintf
(
session
,
"%s %s %s %s"
,
profile
->
api_profile
,
profile
->
domain
,
profile
->
id
,
switch_event_get_header
(
phrase_params
,
"VM-Message-UUID"
));
mt_api_execute
(
session
,
profile
->
api_msg_undelete
,
cmd
);
msg_undeleted
=
SWITCH_TRUE
;
}
}
else
if
(
!
strcasecmp
(
action
,
"save_msg"
))
{
/* Save Message */
cmd
=
switch_core_session_sprintf
(
session
,
"%s %s %s %s"
,
profile
->
api_profile
,
profile
->
domain
,
profile
->
id
,
switch_event_get_header
(
phrase_params
,
"VM-Message-UUID"
));
mt_api_execute
(
session
,
profile
->
api_msg_save
,
cmd
);
msg_saved
=
SWITCH_TRUE
;
}
else
if
(
!
strcasecmp
(
action
,
"callback"
))
{
/* CallBack caller */
const
char
*
cid_num
=
switch_event_get_header
(
phrase_params
,
"VM-Message-Caller-Number"
);
if
(
cid_num
)
{
/* TODO add detection for private number */
switch_core_session_execute_exten
(
session
,
cid_num
,
"XML"
,
profile
->
domain
);
}
else
{
/* TODO Some error msg that the msg doesn't contain a caller number */
}
}
else
if
(
!
strncasecmp
(
action
,
"menu:"
,
5
))
{
/* Sub Menu */
void
(
*
fPtr
)(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
=
mtvm_get_menu_function
(
action
+
5
);
if
(
fPtr
)
{
fPtr
(
session
,
profile
);
}
}
else
if
(
!
strcasecmp
(
action
,
"return"
))
{
/* Return */
retry
=
-
1
;
}
}
}
/* IF the API to get the message returned us a COPY of the file locally (temp file create from a DB or from a web server), delete it */
if
(
switch_true
(
switch_event_get_header
(
phrase_params
,
"VM-Message-Private-Local-Copy"
)))
{
const
char
*
file_path
=
switch_event_get_header
(
phrase_params
,
"VM-Message-File-Path"
);
if
(
file_path
&&
unlink
(
file_path
)
!=
0
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_WARNING
,
"Failed to delete temp file [%s]
\n
"
,
file_path
);
}
}
switch_event_destroy
(
&
phrase_params
);
}
switch_event_destroy
(
&
msg_list_params
);
free_profile_menu_event
(
&
menu
);
return
;
}
void
mtvm_menu_forward
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
{
vmivr_menu_profile_t
menu
=
{
"std_forward_ask_prepend"
};
switch_channel_t
*
channel
=
switch_core_session_get_channel
(
session
);
const
char
*
prepend_filepath
=
NULL
;
int
retry
;
switch_bool_t
forward_msg
=
SWITCH_FALSE
;
/* Initialize Menu Configs */
populate_profile_menu_event
(
profile
,
&
menu
);
if
(
!
menu
.
event_keys_dtmf
||
!
menu
.
event_phrases
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Missing Menu Phrases and Keys
\n
"
);
return
;
}
for
(
retry
=
MAX_ATTEMPT
;
switch_channel_ready
(
channel
)
&&
retry
>
0
;
retry
--
)
{
dtmf_ss_t
loc
;
char
*
dtmfa
[
16
]
=
{
0
};
switch_event_t
*
phrase_params
=
NULL
;
switch_event_create
(
&
phrase_params
,
SWITCH_EVENT_REQUEST_PARAMS
);
append_event_profile
(
phrase_params
,
profile
,
menu
);
populate_dtmfa_from_event
(
phrase_params
,
profile
,
menu
,
dtmfa
);
captureMenuInitialize
(
&
loc
,
dtmfa
);
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"menu_options"
),
NULL
,
phrase_params
,
NULL
,
DEFAULT_IVR_TIMEOUT
);
if
(
loc
.
result
==
RES_TIMEOUT
)
{
/* TODO Ask for the prompt Again IF retry != 0 */
}
else
if
(
loc
.
result
==
RES_INVALID
)
{
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
}
else
if
(
loc
.
result
==
RES_FOUND
)
{
/* Matching DTMF Key Pressed */
const
char
*
action
=
switch_event_get_header
(
menu
.
event_keys_dtmf
,
loc
.
dtmf_stored
);
/* Reset the try count */
retry
=
MAX_ATTEMPT
;
if
(
action
)
{
if
(
!
strcasecmp
(
action
,
"return"
))
{
/* Return to the previous menu */
retry
=
-
1
;
forward_msg
=
SWITCH_FALSE
;
}
else
if
(
!
strcasecmp
(
action
,
"prepend"
))
{
/* Prepend record msg */
vmivr_menu_profile_t
sub_menu
=
{
"std_record_message"
};
char
*
tmp_filepath
=
generate_random_file_name
(
session
,
"protovm"
,
"wav"
/* TODO make it configurable */
);
switch_status_t
status
;
/* Initialize Menu Configs */
populate_profile_menu_event
(
profile
,
&
sub_menu
);
status
=
mtvm_menu_record
(
session
,
profile
,
sub_menu
,
tmp_filepath
);
if
(
status
==
SWITCH_STATUS_SUCCESS
)
{
//char *cmd = switch_core_session_sprintf(session, "%s %s %s %d %s", profile->api_profile, profile->domain, profile->id, gnum, tmp_filepath);
//char *str_num = switch_core_session_sprintf(session, "%d", gnum);
//mt_api_execute(session, profile->api_pref_greeting_set, cmd);
//playbackBufferDTMF(session, switch_event_get_header(menu.event_phrases, "selected_slot"), str_num, NULL, NULL, 0);
prepend_filepath
=
tmp_filepath
;
retry
=
-
1
;
forward_msg
=
SWITCH_TRUE
;
}
else
{
/* TODO Error Recording msg */
}
free_profile_menu_event
(
&
sub_menu
);
}
else
if
(
!
strcasecmp
(
action
,
"forward"
))
{
/* Forward without prepend msg */
retry
=
-
1
;
forward_msg
=
SWITCH_TRUE
;
}
else
if
(
!
strncasecmp
(
action
,
"menu:"
,
5
))
{
/* Sub Menu */
void
(
*
fPtr
)(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
=
mtvm_get_menu_function
(
action
+
5
);
if
(
fPtr
)
{
fPtr
(
session
,
profile
);
}
}
}
}
switch_event_destroy
(
&
phrase_params
);
}
/* Ask Extension to Forward */
if
(
forward_msg
)
{
for
(
retry
=
MAX_ATTEMPT
;
switch_channel_ready
(
channel
)
&&
retry
>
0
;
retry
--
)
{
const
char
*
id
=
NULL
;
vmivr_menu_profile_t
sub_menu
=
{
"std_forward_ask_extension"
};
/* Initialize Menu Configs */
populate_profile_menu_event
(
profile
,
&
sub_menu
);
id
=
mtvm_menu_get_input_set
(
session
,
profile
,
sub_menu
,
"X."
);
if
(
id
)
{
const
char
*
cmd
=
switch_core_session_sprintf
(
session
,
"%s %s %s %s %s %s %s%s%s"
,
profile
->
api_profile
,
profile
->
domain
,
profile
->
id
,
profile
->
current_msg_uuid
,
profile
->
domain
,
id
,
prepend_filepath
?
" "
:
""
,
prepend_filepath
?
prepend_filepath
:
""
);
if
(
mt_api_execute
(
session
,
profile
->
api_msg_forward
,
cmd
)
==
SWITCH_STATUS_SUCCESS
)
{
playbackBufferDTMF
(
session
,
switch_event_get_header
(
sub_menu
.
event_phrases
,
"ack"
),
"saved"
,
NULL
,
NULL
,
0
);
retry
=
-
1
;
}
else
{
playbackBufferDTMF
(
session
,
switch_event_get_header
(
sub_menu
.
event_phrases
,
"invalid_extension"
),
NULL
,
NULL
,
NULL
,
0
);
}
}
else
{
/* TODO Prompt about input not valid */
}
free_profile_menu_event
(
&
sub_menu
);
/* TODO add Confirmation of the transfered number */
}
/* TODO Ask if we want to transfer the msg to more person */
}
free_profile_menu_event
(
&
menu
);
}
void
mtvm_menu_record_name
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
{
switch_status_t
status
;
vmivr_menu_profile_t
menu
=
{
"std_record_name"
};
char
*
tmp_filepath
=
generate_random_file_name
(
session
,
"protovm"
,
"wav"
/* TODO make it configurable */
);
/* Initialize Menu Configs */
populate_profile_menu_event
(
profile
,
&
menu
);
status
=
mtvm_menu_record
(
session
,
profile
,
menu
,
tmp_filepath
);
if
(
status
==
SWITCH_STATUS_SUCCESS
)
{
char
*
cmd
=
switch_core_session_sprintf
(
session
,
"%s %s %s %s"
,
profile
->
api_profile
,
profile
->
domain
,
profile
->
id
,
tmp_filepath
);
mt_api_execute
(
session
,
profile
->
api_pref_recname_set
,
cmd
);
}
}
void
mtvm_menu_set_password
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
{
char
*
password
;
vmivr_menu_profile_t
menu
=
{
"std_set_password"
};
/* Initialize Menu Configs */
populate_profile_menu_event
(
profile
,
&
menu
);
password
=
mtvm_menu_get_input_set
(
session
,
profile
,
menu
,
"XXX."
/* TODO Conf Min 3 Digit */
);
/* TODO Add Prompts to tell if password was set and if it was not */
if
(
password
)
{
char
*
cmd
=
switch_core_session_sprintf
(
session
,
"%s %s %s %s"
,
profile
->
api_profile
,
profile
->
domain
,
profile
->
id
,
password
);
mt_api_execute
(
session
,
profile
->
api_pref_password_set
,
cmd
);
}
free_profile_menu_event
(
&
menu
);
}
void
mtvm_menu_authenticate
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
{
switch_channel_t
*
channel
=
switch_core_session_get_channel
(
session
);
vmivr_menu_profile_t
menu
=
{
"std_authenticate"
};
int
retry
;
const
char
*
auth_var
=
NULL
;
/* Initialize Menu Configs */
populate_profile_menu_event
(
profile
,
&
menu
);
if
(
profile
->
id
&&
(
auth_var
=
switch_channel_get_variable
(
channel
,
"voicemail_authorized"
))
&&
switch_true
(
auth_var
))
{
profile
->
authorized
=
SWITCH_TRUE
;
}
for
(
retry
=
MAX_ATTEMPT
;
switch_channel_ready
(
channel
)
&&
retry
>
0
&&
profile
->
authorized
==
SWITCH_FALSE
;
retry
--
)
{
const
char
*
id
=
profile
->
id
,
*
password
=
NULL
;
char
*
cmd
=
NULL
;
if
(
!
id
)
{
vmivr_menu_profile_t
sub_menu
=
{
"std_authenticate_ask_user"
};
/* Initialize Menu Configs */
populate_profile_menu_event
(
profile
,
&
sub_menu
);
id
=
mtvm_menu_get_input_set
(
session
,
profile
,
sub_menu
,
"X."
/* TODO Conf Min 3 Digit */
);
free_profile_menu_event
(
&
sub_menu
);
}
if
(
!
password
)
{
vmivr_menu_profile_t
sub_menu
=
{
"std_authenticate_ask_password"
};
/* Initialize Menu Configs */
populate_profile_menu_event
(
profile
,
&
sub_menu
);
password
=
mtvm_menu_get_input_set
(
session
,
profile
,
sub_menu
,
"X."
/* TODO Conf Min 3 Digit */
);
free_profile_menu_event
(
&
sub_menu
);
}
cmd
=
switch_core_session_sprintf
(
session
,
"%s %s %s %s"
,
profile
->
api_profile
,
profile
->
domain
,
id
,
password
);
if
(
mt_api_execute
(
session
,
profile
->
api_auth_login
,
cmd
)
==
SWITCH_STATUS_SUCCESS
)
{
profile
->
id
=
id
;
profile
->
authorized
=
SWITCH_TRUE
;
}
else
{
playbackBufferDTMF
(
session
,
switch_event_get_header
(
menu
.
event_phrases
,
"fail_auth"
),
NULL
,
NULL
,
NULL
,
0
);
}
}
free_profile_menu_event
(
&
menu
);
}
void
mtvm_menu_select_greeting_slot
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
{
vmivr_menu_profile_t
menu
=
{
"std_select_greeting_slot"
};
const
char
*
result
;
int
gnum
=
-
1
;
/* Initialize Menu Configs */
populate_profile_menu_event
(
profile
,
&
menu
);
result
=
mtvm_menu_get_input_set
(
session
,
profile
,
menu
,
"X"
);
if
(
result
)
gnum
=
atoi
(
result
);
if
(
gnum
!=
-
1
)
{
char
*
cmd
=
switch_core_session_sprintf
(
session
,
"%s %s %s %d"
,
profile
->
api_profile
,
profile
->
domain
,
profile
->
id
,
gnum
);
if
(
mt_api_execute
(
session
,
profile
->
api_pref_greeting_set
,
cmd
)
==
SWITCH_STATUS_SUCCESS
)
{
char
*
str_num
=
switch_core_session_sprintf
(
session
,
"%d"
,
gnum
);
playbackBufferDTMF
(
session
,
switch_event_get_header
(
menu
.
event_phrases
,
"selected_slot"
),
str_num
,
NULL
,
NULL
,
0
);
}
else
{
playbackBufferDTMF
(
session
,
switch_event_get_header
(
menu
.
event_phrases
,
"invalid_slot"
),
NULL
,
NULL
,
NULL
,
0
);
}
}
free_profile_menu_event
(
&
menu
);
}
void
mtvm_menu_record_greeting_with_slot
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
{
vmivr_menu_profile_t
menu
=
{
"std_record_greeting_with_slot"
};
const
char
*
result
;
int
gnum
=
-
1
;
/* Initialize Menu Configs */
populate_profile_menu_event
(
profile
,
&
menu
);
result
=
mtvm_menu_get_input_set
(
session
,
profile
,
menu
,
"X"
);
if
(
result
)
gnum
=
atoi
(
result
);
/* If user entered 0, we don't accept it */
if
(
gnum
>
0
)
{
vmivr_menu_profile_t
sub_menu
=
{
"std_record_greeting"
};
char
*
tmp_filepath
=
generate_random_file_name
(
session
,
"protovm"
,
"wav"
/* TODO make it configurable */
);
switch_status_t
status
;
/* Initialize Menu Configs */
populate_profile_menu_event
(
profile
,
&
sub_menu
);
status
=
mtvm_menu_record
(
session
,
profile
,
sub_menu
,
tmp_filepath
);
if
(
status
==
SWITCH_STATUS_SUCCESS
)
{
char
*
cmd
=
switch_core_session_sprintf
(
session
,
"%s %s %s %d %s"
,
profile
->
api_profile
,
profile
->
domain
,
profile
->
id
,
gnum
,
tmp_filepath
);
char
*
str_num
=
switch_core_session_sprintf
(
session
,
"%d"
,
gnum
);
mt_api_execute
(
session
,
profile
->
api_pref_greeting_set
,
cmd
);
playbackBufferDTMF
(
session
,
switch_event_get_header
(
menu
.
event_phrases
,
"selected_slot"
),
str_num
,
NULL
,
NULL
,
0
);
}
free_profile_menu_event
(
&
sub_menu
);
}
free_profile_menu_event
(
&
menu
);
}
void
mtvm_menu_preference
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
{
switch_channel_t
*
channel
=
switch_core_session_get_channel
(
session
);
int
retry
;
vmivr_menu_profile_t
menu
=
{
"std_preference"
};
/* Initialize Menu Configs */
populate_profile_menu_event
(
profile
,
&
menu
);
if
(
!
menu
.
event_keys_dtmf
||
!
menu
.
event_phrases
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Missing Menu Phrases and Keys
\n
"
);
return
;
}
for
(
retry
=
MAX_ATTEMPT
;
switch_channel_ready
(
channel
)
&&
retry
>
0
;
retry
--
)
{
dtmf_ss_t
loc
;
char
*
dtmfa
[
16
]
=
{
0
};
switch_event_t
*
phrase_params
=
NULL
;
switch_event_create
(
&
phrase_params
,
SWITCH_EVENT_REQUEST_PARAMS
);
append_event_profile
(
phrase_params
,
profile
,
menu
);
populate_dtmfa_from_event
(
phrase_params
,
profile
,
menu
,
dtmfa
);
captureMenuInitialize
(
&
loc
,
dtmfa
);
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"menu_options"
),
NULL
,
phrase_params
,
NULL
,
DEFAULT_IVR_TIMEOUT
);
if
(
loc
.
result
==
RES_TIMEOUT
)
{
/* TODO Ask for the prompt Again IF retry != 0 */
}
else
if
(
loc
.
result
==
RES_INVALID
)
{
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
}
else
if
(
loc
.
result
==
RES_FOUND
)
{
/* Matching DTMF Key Pressed */
const
char
*
action
=
switch_event_get_header
(
menu
.
event_keys_dtmf
,
loc
.
dtmf_stored
);
/* Reset the try count */
retry
=
MAX_ATTEMPT
;
if
(
action
)
{
if
(
!
strcasecmp
(
action
,
"return"
))
{
/* Return to the previous menu */
retry
=
-
1
;
}
else
if
(
!
strncasecmp
(
action
,
"menu:"
,
5
))
{
/* Sub Menu */
void
(
*
fPtr
)(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
=
mtvm_get_menu_function
(
action
+
5
);
if
(
fPtr
)
{
fPtr
(
session
,
profile
);
}
}
}
}
switch_event_destroy
(
&
phrase_params
);
}
free_profile_menu_event
(
&
menu
);
}
char
*
mtvm_menu_get_input_set
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
,
vmivr_menu_profile_t
menu
,
const
char
*
input_mask
)
{
char
*
result
=
NULL
;
int
retry
;
const
char
*
terminate_key
=
NULL
;
switch_channel_t
*
channel
=
switch_core_session_get_channel
(
session
);
if
(
!
menu
.
event_keys_dtmf
||
!
menu
.
event_phrases
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Missing Menu Phrases and Keys : %s
\n
"
,
menu
.
name
);
return
result
;
}
terminate_key
=
switch_event_get_header
(
menu
.
event_keys_action
,
"ivrengine:terminate_entry"
);
for
(
retry
=
MAX_ATTEMPT
;
switch_channel_ready
(
channel
)
&&
retry
>
0
;
retry
--
)
{
dtmf_ss_t
loc
;
char
*
dtmfa
[
16
]
=
{
0
};
int
i
;
switch_event_t
*
phrase_params
=
NULL
;
switch_event_create
(
&
phrase_params
,
SWITCH_EVENT_REQUEST_PARAMS
);
append_event_profile
(
phrase_params
,
profile
,
menu
);
populate_dtmfa_from_event
(
phrase_params
,
profile
,
menu
,
dtmfa
);
/* Find the last entry and append this one to it */
for
(
i
=
0
;
dtmfa
[
i
]
&&
i
<
16
;
i
++
){
}
dtmfa
[
i
]
=
(
char
*
)
input_mask
;
captureMenuInitialize
(
&
loc
,
dtmfa
);
if
(
terminate_key
)
{
loc
.
terminate_key
=
terminate_key
[
0
];
}
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"instructions"
),
NULL
,
phrase_params
,
NULL
,
DEFAULT_IVR_TIMEOUT
);
if
(
loc
.
result
==
RES_TIMEOUT
)
{
/* TODO Ask for the prompt Again IF retry != 0 */
}
else
if
(
loc
.
result
==
RES_INVALID
)
{
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
}
else
if
(
loc
.
result
==
RES_FOUND
)
{
/* Matching DTMF Key Pressed */
/* Reset the try count */
retry
=
MAX_ATTEMPT
;
if
(
!
strncasecmp
(
loc
.
completeMatch
,
input_mask
,
1
))
{
result
=
switch_core_session_strdup
(
session
,
loc
.
dtmf_stored
);
retry
=
-
1
;
}
}
switch_event_destroy
(
&
phrase_params
);
}
return
result
;
}
switch_status_t
mtvm_menu_record
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
,
vmivr_menu_profile_t
menu
,
const
char
*
file_name
)
{
switch_status_t
status
=
SWITCH_STATUS_FALSE
;
switch_channel_t
*
channel
=
switch_core_session_get_channel
(
session
);
int
retry
;
switch_bool_t
record_prompt
=
SWITCH_TRUE
;
switch_bool_t
listen_recording
=
SWITCH_FALSE
;
switch_bool_t
play_instruction
=
SWITCH_TRUE
;
if
(
!
menu
.
event_keys_dtmf
||
!
menu
.
event_phrases
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Missing Menu Phrases and Keys
\n
"
);
return
status
;
}
for
(
retry
=
MAX_ATTEMPT
;
switch_channel_ready
(
channel
)
&&
retry
>
0
;
retry
--
)
{
dtmf_ss_t
loc
;
char
*
dtmfa
[
16
]
=
{
0
};
switch_event_t
*
phrase_params
=
NULL
;
switch_file_handle_t
fh
=
{
0
};
/* TODO Make the following configurable */
fh
.
thresh
=
200
;
fh
.
silence_hits
=
4
;
//fh.samplerate = 8000;
switch_event_create
(
&
phrase_params
,
SWITCH_EVENT_REQUEST_PARAMS
);
append_event_profile
(
phrase_params
,
profile
,
menu
);
populate_dtmfa_from_event
(
phrase_params
,
profile
,
menu
,
dtmfa
);
captureMenuInitialize
(
&
loc
,
dtmfa
);
if
(
record_prompt
)
{
if
(
play_instruction
)
{
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"instructions"
),
NULL
,
phrase_params
,
NULL
,
0
);
}
play_instruction
=
SWITCH_TRUE
;
captureMenuRecord
(
session
,
&
loc
,
phrase_params
,
file_name
,
&
fh
,
30
/* TODO Make max recording configurable */
);
}
else
{
if
(
listen_recording
)
{
switch_event_add_header
(
phrase_params
,
SWITCH_STACK_BOTTOM
,
"VM-Record-File-Path"
,
"%s"
,
file_name
);
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"play_recording"
),
NULL
,
phrase_params
,
NULL
,
0
);
listen_recording
=
SWITCH_FALSE
;
}
captureMenu
(
session
,
&
loc
,
switch_event_get_header
(
menu
.
event_phrases
,
"menu_options"
),
NULL
,
phrase_params
,
NULL
,
DEFAULT_IVR_TIMEOUT
);
}
if
(
loc
.
recorded_audio
)
{
/* Reset the try count */
retry
=
MAX_ATTEMPT
;
/* TODO Check if message is too short */
record_prompt
=
SWITCH_FALSE
;
}
else
if
(
loc
.
result
==
RES_TIMEOUT
)
{
/* TODO Ask for the prompt Again IF retry != 0 */
}
else
if
(
loc
.
result
==
RES_INVALID
)
{
/* TODO Say invalid option, and ask for the prompt again IF retry != 0 */
}
else
if
(
loc
.
result
==
RES_FOUND
)
{
/* Matching DTMF Key Pressed */
const
char
*
action
=
switch_event_get_header
(
menu
.
event_keys_dtmf
,
loc
.
dtmf_stored
);
/* Reset the try count */
retry
=
MAX_ATTEMPT
;
if
(
action
)
{
if
(
!
strcasecmp
(
action
,
"listen"
))
{
/* Listen */
listen_recording
=
SWITCH_TRUE
;
}
else
if
(
!
strcasecmp
(
action
,
"save"
))
{
retry
=
-
1
;
/* TODO ALLOW SAVE ONLY IF FILE IS RECORDED AND HIGHER THAN MIN SIZE */
status
=
SWITCH_STATUS_SUCCESS
;
}
else
if
(
!
strcasecmp
(
action
,
"rerecord"
))
{
record_prompt
=
SWITCH_TRUE
;
}
else
if
(
!
strcasecmp
(
action
,
"skip_instruction"
))
{
/* Skip Recording Greeting */
play_instruction
=
SWITCH_FALSE
;
}
else
if
(
!
strncasecmp
(
action
,
"menu:"
,
5
))
{
/* Sub Menu */
void
(
*
fPtr
)(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
=
mtvm_get_menu_function
(
action
+
5
);
if
(
fPtr
)
{
fPtr
(
session
,
profile
);
}
}
else
if
(
!
strcasecmp
(
action
,
"return"
))
{
/* Return */
retry
=
-
1
;
}
}
}
switch_event_destroy
(
&
phrase_params
);
}
return
status
;
}
void
(
*
mtvm_get_menu_function
(
const
char
*
menu_name
))(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
{
int
i
=
0
;
if
(
menu_name
)
{
for
(
i
=
0
;
menu_list
[
i
].
name
;
i
++
)
{
if
(
!
strcasecmp
(
menu_list
[
i
].
name
,
menu_name
))
{
return
menu_list
[
i
].
pt2Func
;
}
}
}
return
NULL
;
}
/* 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
*/
src/mod/applications/mod_protovm/menu.h
deleted
100644 → 0
浏览文件 @
d48edc53
#ifndef _MENU_H_
#define _MENU_H_
#include "config.h"
void
mtvm_menu_purge
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
);
void
mtvm_menu_authenticate
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
);
void
mtvm_menu_main
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
);
void
mtvm_menu_record_name
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
);
void
mtvm_menu_set_password
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
);
void
mtvm_menu_select_greeting_slot
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
);
void
mtvm_menu_record_greeting_with_slot
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
);
void
mtvm_menu_preference
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
);
void
mtvm_menu_forward
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
);
switch_status_t
mtvm_menu_record
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
,
vmivr_menu_profile_t
menu
,
const
char
*
file_name
);
char
*
mtvm_menu_get_input_set
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
,
vmivr_menu_profile_t
menu
,
const
char
*
input_mask
);
struct
vmivr_menu_function
{
const
char
*
name
;
void
(
*
pt2Func
)(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
);
};
typedef
struct
vmivr_menu_function
vmivr_menu_function_t
;
extern
vmivr_menu_function_t
menu_list
[];
void
(
*
mtvm_get_menu_function
(
const
char
*
menu_name
))(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
);
#endif
/* _MENU_H_ */
src/mod/applications/mod_protovm/mod_protovm.c
deleted
100644 → 0
浏览文件 @
d48edc53
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
*
* 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 <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Marc Olivier Chouinard <mochouinard@moctel.com>
*
*
* mod_protovm.c -- MT VoiceMail System
*
*/
#include <switch.h>
#include "config.h"
#include "menu.h"
/* Prototypes */
SWITCH_MODULE_SHUTDOWN_FUNCTION
(
mod_protovm_shutdown
);
SWITCH_MODULE_RUNTIME_FUNCTION
(
mod_protovm_runtime
);
SWITCH_MODULE_LOAD_FUNCTION
(
mod_protovm_load
);
/* SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime)
* Defines a switch_loadable_module_function_table_t and a static const char[] modname
*/
SWITCH_MODULE_DEFINITION
(
mod_protovm
,
mod_protovm_load
,
mod_protovm_shutdown
,
NULL
);
#define MTVM_DESC "protovm"
#define MTVM_USAGE "<check> profile domain [id]"
SWITCH_STANDARD_APP
(
protovm_function
)
{
const
char
*
id
=
NULL
;
const
char
*
domain
=
NULL
;
const
char
*
profile_name
=
NULL
;
vmivr_profile_t
*
profile
=
NULL
;
int
argc
=
0
;
char
*
argv
[
6
]
=
{
0
};
char
*
mydata
=
NULL
;
if
(
!
zstr
(
data
))
{
mydata
=
switch_core_session_strdup
(
session
,
data
);
argc
=
switch_separate_string
(
mydata
,
' '
,
argv
,
(
sizeof
(
argv
)
/
sizeof
(
argv
[
0
])));
}
if
(
argv
[
1
])
profile_name
=
argv
[
1
];
if
(
argv
[
2
])
domain
=
argv
[
2
];
if
(
!
strcasecmp
(
argv
[
0
],
"check"
))
{
if
(
argv
[
3
])
id
=
argv
[
3
];
if
(
domain
&&
profile_name
)
{
profile
=
get_profile
(
session
,
profile_name
);
if
(
profile
)
{
void
(
*
fPtrAuth
)(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
=
mtvm_get_menu_function
(
profile
->
menu_check_auth
);
void
(
*
fPtrMain
)(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
=
mtvm_get_menu_function
(
profile
->
menu_check_main
);
void
(
*
fPtrTerminate
)(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
)
=
mtvm_get_menu_function
(
profile
->
menu_check_terminate
);
profile
->
domain
=
domain
;
profile
->
id
=
id
;
if
(
fPtrAuth
&&
!
profile
->
authorized
)
{
fPtrAuth
(
session
,
profile
);
}
if
(
fPtrMain
&&
profile
->
authorized
)
{
fPtrMain
(
session
,
profile
);
}
if
(
fPtrTerminate
)
{
fPtrTerminate
(
session
,
profile
);
}
}
else
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Profile '%s' not found
\n
"
,
profile_name
);
}
}
}
return
;
}
/* Macro expands to: switch_status_t mod_protovm_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */
SWITCH_MODULE_LOAD_FUNCTION
(
mod_protovm_load
)
{
switch_application_interface_t
*
app_interface
;
switch_status_t
status
=
SWITCH_STATUS_SUCCESS
;
/* 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
,
"protovm"
,
"protovm"
,
MTVM_DESC
,
protovm_function
,
MTVM_USAGE
,
SAF_NONE
);
/* indicate that the module should continue to be loaded */
return
status
;
}
/*
Called when the system shuts down
Macro expands to: switch_status_t mod_protovm_shutdown() */
SWITCH_MODULE_SHUTDOWN_FUNCTION
(
mod_protovm_shutdown
)
{
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
*/
src/mod/applications/mod_protovm/protovm.conf.xml
deleted
100644 → 0
浏览文件 @
d48edc53
<configuration
name=
"protovm.conf"
description=
"ProtoVoicemailIVR"
>
<profiles>
<profile
name=
"default"
>
<apis>
<api
name=
"auth_login"
value=
"vm_fsdb_auth_login"
/>
<api
name=
"msg_list"
value=
"vm_fsdb_msg_list"
/>
<api
name=
"msg_count"
value=
"vm_fsdb_msg_count"
/>
<api
name=
"msg_delete"
value=
"vm_fsdb_msg_delete"
/>
<api
name=
"msg_undelete"
value=
"vm_fsdb_msg_undelete"
/>
<api
name=
"msg_save"
value=
"vm_fsdb_msg_save"
/>
<api
name=
"msg_purge"
value=
"vm_fsdb_msg_purge"
/>
<api
name=
"msg_get"
value=
"vm_fsdb_msg_get"
/>
<api
name=
"msg_forward"
value=
"vm_fsdb_msg_forward"
/>
<api
name=
"pref_greeting_set"
value=
"vm_fsdb_pref_greeting_set"
/>
<api
name=
"pref_recname_set"
value=
"vm_fsdb_pref_recname_set"
/>
<api
name=
"pref_password_set"
value=
"vm_fsdb_pref_password_set"
/>
</apis>
<menus>
<menu
name=
"std_authenticate"
>
<phrases>
<phrase
name=
"fail_auth"
value=
"fail_auth@protovm"
/>
</phrases>
<keys>
</keys>
</menu>
<menu
name=
"std_authenticate_ask_user"
>
<phrases>
<phrase
name=
"instructions"
value=
"enter_id@protovm"
/>
</phrases>
<keys>
<key
dtmf=
"#"
action=
"ivrengine:terminate_entry"
variable=
"VM-Key-Terminator"
/>
</keys>
</menu>
<menu
name=
"std_authenticate_ask_password"
>
<phrases>
<phrase
name=
"instructions"
value=
"enter_pass@protovm"
/>
</phrases>
<keys>
<key
dtmf=
"#"
action=
"ivrengine:terminate_entry"
variable=
"VM-Key-Terminator"
/>
</keys>
</menu>
<menu
name=
"std_navigator"
>
<phrases>
<phrase
name=
"msg_count"
value=
"message_count@protovm"
/>
<phrase
name=
"say_date"
value=
"say_date_event@protovm"
/>
<phrase
name=
"say_msg_number"
value=
"say_message_number@protovm"
/>
<phrase
name=
"menu_options"
value=
"listen_file_check@protovm"
/>
<phrase
name=
"ack"
value=
"ack@protovm"
/>
<phrase
name=
"play_message"
value=
"play_message@protovm"
/>
</phrases>
<keys>
<key
dtmf=
"1"
action=
"skip_intro"
variable=
"VM-Key-Main-Listen-File"
/>
<key
dtmf=
"6"
action=
"next_msg"
variable=
"VM-Key-Main-Next-Msg"
/>
<key
dtmf=
"4"
action=
"prev_msg"
/>
<key
dtmf=
"7"
action=
"delete_msg"
variable=
"VM-Key-Main-Delete-File"
/>
<!-- Same key for undelete if it already deleted -->
<key
dtmf=
"8"
action=
"menu:std_forward"
variable=
"VM-Key-Main-Forward"
/>
<key
dtmf=
"3"
action=
"save_msg"
variable=
"VM-Key-Main-Save-File"
/>
<key
dtmf=
"2"
action=
"callback"
variable=
"VM-Key-Main-Callback"
/>
<key
dtmf=
"5"
action=
"menu:std_preference"
/>
<key
dtmf=
"#"
action=
"return"
/>
<!-- TODO Might Conflict with future fast-forward -->
</keys>
</menu>
<menu
name=
"std_preference"
>
<phrases>
<phrase
name=
"menu_options"
value=
"config_menu@protovm"
/>
</phrases>
<keys>
<key
dtmf=
"1"
action=
"menu:std_record_greeting_with_slot"
variable=
"VM-Key-Record-Greeting"
/>
<key
dtmf=
"2"
action=
"menu:std_select_greeting_slot"
variable=
"VM-Key-Choose-Greeting"
/>
<key
dtmf=
"3"
action=
"menu:std_record_name"
variable=
"VM-Key-Record-Name"
/>
<key
dtmf=
"6"
action=
"menu:std_set_password"
variable=
"VM-Key-Change-Password"
/>
<key
dtmf=
"#"
action=
"return"
variable=
"VM-Key-Main-Menu"
/>
</keys>
</menu>
<menu
name=
"std_record_greeting"
>
<phrases>
<phrase
name=
"instructions"
value=
"record_greeting@protovm"
/>
<phrase
name=
"play_recording"
value=
"play_recording@protovm"
/>
<phrase
name=
"menu_options"
value=
"record_file_check@protovm"
/>
</phrases>
<keys>
<key
dtmf=
"1"
action=
"listen"
variable=
"VM-Key-Listen-File"
/>
<key
dtmf=
"3"
action=
"save"
variable=
"VM-Key-Save-File"
/>
<key
dtmf=
"4"
action=
"rerecord"
variable=
"VM-Key-ReRecord-File"
/>
<key
dtmf=
"#"
action=
"skip_instruction"
/>
</keys>
</menu>
<menu
name=
"std_record_name"
>
<phrases>
<phrase
name=
"instructions"
value=
"record_name@protovm"
/>
<phrase
name=
"play_recording"
value=
"play_recording@protovm"
/>
<phrase
name=
"menu_options"
value=
"record_file_check@protovm"
/>
</phrases>
<keys>
<key
dtmf=
"1"
action=
"listen"
variable=
"VM-Key-Listen-File"
/>
<key
dtmf=
"3"
action=
"save"
variable=
"VM-Key-Save-File"
/>
<key
dtmf=
"4"
action=
"rerecord"
variable=
"VM-Key-ReRecord-File"
/>
<key
dtmf=
"#"
action=
"skip_instruction"
/>
</keys>
</menu>
<menu
name=
"std_record_message"
>
<phrases>
<phrase
name=
"instructions"
value=
"record_message@protovm"
/>
<phrase
name=
"play_recording"
value=
"play_recording@protovm"
/>
<phrase
name=
"menu_options"
value=
"record_file_check@protovm"
/>
</phrases>
<keys>
<key
dtmf=
"1"
action=
"listen"
variable=
"VM-Key-Listen-File"
/>
<key
dtmf=
"3"
action=
"save"
variable=
"VM-Key-Save-File"
/>
<key
dtmf=
"4"
action=
"rerecord"
variable=
"VM-Key-ReRecord-File"
/>
<key
dtmf=
"#"
action=
"skip_instruction"
/>
</keys>
</menu>
<menu
name=
"std_forward_ask_prepend"
>
<phrases>
<phrase
name=
"menu_options"
value=
"forward_ask_prepend@protovm"
/>
</phrases>
<keys>
<key
dtmf=
"1"
action=
"prepend"
variable=
"VM-Key-Prepend"
/>
<key
dtmf=
"8"
action=
"forward"
variable=
"VM-Key-Forward"
/>
<key
dtmf=
"#"
action=
"return"
variable=
"VM-Key-Return"
/>
</keys>
</menu>
<menu
name=
"std_forward_ask_extension"
>
<phrases>
<phrase
name=
"instructions"
value=
"forward_ask_extension@protovm"
/>
<phrase
name=
"ack"
value=
"ack@protovm"
/>
<phrase
name=
"invalid_extension"
value=
"invalid_extension@protovm"
/>
</phrases>
<keys>
<key
dtmf=
"#"
action=
"ivrengine:terminate_entry"
variable=
"VM-Key-Terminator"
/>
</keys>
</menu>
<menu
name=
"std_select_greeting_slot"
>
<phrases>
<phrase
name=
"instructions"
value=
"choose_greeting@protovm"
/>
<phrase
name=
"invalid_slot"
value=
"choose_greeting_fail@protovm"
/>
<phrase
name=
"selected_slot"
value=
"greeting_selected@protovm"
/>
</phrases>
<keys>
</keys>
</menu>
<menu
name=
"std_record_greeting_with_slot"
>
<phrases>
<phrase
name=
"instructions"
value=
"choose_greeting@protovm"
/>
</phrases>
<keys>
</keys>
</menu>
<menu
name=
"std_set_password"
>
<phrases>
<phrase
name=
"instructions"
value=
"enter_pass@protovm"
/>
</phrases>
<keys>
<key
dtmf=
"#"
action=
"ivrengine:terminate_entry"
variable=
"VM-Key-Terminator"
/>
</keys>
</menu>
</menus>
</profile>
</profiles>
</configuration>
src/mod/applications/mod_protovm/sounds.xml
deleted
100644 → 0
浏览文件 @
d48edc53
<include>
<!--This line will be ignored it's here to validate the xml and is optional -->
<macros
name=
"protovm"
sound-prefix=
"$${sounds_dir}/en/us/callie"
>
<macro
name=
"press_key"
>
<input
pattern=
"^(.*):(.*)$"
>
<match>
<action
function=
"play-file"
data=
"$2"
/>
<action
function=
"play-file"
data=
"voicemail/vm-press.wav"
/>
<action
function=
"say"
data=
"$1"
method=
"pronounced"
type=
"name_spelled"
/>
</match>
</input>
</macro>
<macro
name=
"plurial_msg"
>
<input
pattern=
"^[01]:(.*):(.*)$"
break_on_match=
"true"
>
<match>
<action
function=
"play-file"
data=
"$1"
/>
</match>
</input>
<input
pattern=
"^.*:(.*):(.*)$"
break_on_match=
"true"
>
<match>
<action
function=
"play-file"
data=
"$2"
/>
</match>
</input>
</macro>
<macro
name=
"enter_id"
>
<input
pattern=
"(.+)"
>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-enter_id.wav"
/>
<action
function=
"say"
data=
"$1"
method=
"pronounced"
type=
"name_spelled"
/>
</match>
<nomatch>
<action
function=
"play-file"
data=
"voicemail/vm-enter_id.wav"
/>
<action
function=
"say"
data=
"${VM-Key-Terminator}"
method=
"pronounced"
type=
"name_spelled"
/>
</nomatch>
</input>
</macro>
<macro
name=
"enter_pass"
>
<input
pattern=
"(.+)"
>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-enter_pass.wav"
/>
<action
function=
"say"
data=
"$1"
method=
"pronounced"
type=
"name_spelled"
/>
</match>
<nomatch>
<action
function=
"play-file"
data=
"voicemail/vm-enter_pass.wav"
/>
<action
function=
"say"
data=
"${VM-Key-Terminator}"
method=
"pronounced"
type=
"name_spelled"
/>
</nomatch>
</input>
</macro>
<macro
name=
"fail_auth"
>
<input>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-fail_auth.wav"
/>
</match>
</input>
</macro>
<macro
name=
"hello"
>
<input>
<match>
<!--<action function="play-file" data="voicemail/vm-hello.wav"/> -->
</match>
</input>
</macro>
<macro
name=
"goodbye"
>
<input>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-goodbye.wav"
/>
</match>
</input>
</macro>
<macro
name=
"abort"
>
<input>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-abort.wav"
/>
</match>
</input>
</macro>
<macro
name=
"message_count"
>
<input
field=
"${VM-Total-New-Urgent-Messages}"
pattern=
"^(0)$"
>
<nomatch>
<action
function=
"play-file"
data=
"voicemail/vm-you_have.wav"
/>
<action
function=
"say"
data=
"${VM-Total-New-Urgent-Messages}"
method=
"pronounced"
type=
"items"
/>
<action
function=
"play-file"
data=
"voicemail/vm-urgent-new.wav"
/>
<action
function=
"phrase"
phrase=
"plurial_msg@protovm"
data=
"${VM-Total-New-Urgent-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"
/>
</nomatch>
</input>
<input
field=
"${VM-Total-New-Messages}"
pattern=
"^(\d+)$"
>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-you_have.wav"
/>
<action
function=
"say"
data=
"${VM-Total-New-Messages}"
method=
"pronounced"
type=
"items"
/>
<action
function=
"play-file"
data=
"voicemail/vm-new.wav"
/>
<action
function=
"phrase"
phrase=
"plurial_msg@protovm"
data=
"${VM-Total-New-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"
/>
</match>
</input>
<input
field=
"${VM-Total-Saved-Messages}"
pattern=
"^(0)$"
>
<nomatch>
<action
function=
"play-file"
data=
"currency/and.wav"
/>
<action
function=
"say"
data=
"${VM-Total-Saved-Messages}"
method=
"pronounced"
type=
"items"
/>
<action
function=
"play-file"
data=
"voicemail/vm-saved.wav"
/>
<action
function=
"phrase"
phrase=
"plurial_msg@protovm"
data=
"${VM-Total-Saved-Messages}:voicemail/vm-message.wav:voicemail/vm-messages.wav"
/>
</nomatch>
</input>
</macro>
<macro
name=
"menu"
>
<input>
<match>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Play-New-Messages}:voicemail/vm-listen_new.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Play-Saved-Messages}:voicemail/vm-listen_saved.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Config-Menu}:voicemail/vm-advanced.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Terminator}:voicemail/vm-to_exit.wav"
/>
</match>
</input>
</macro>
<macro
name=
"config_menu"
>
<input>
<match>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Record-Greeting}:voicemail/vm-to_record_greeting.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Choose-Greeting}:voicemail/vm-choose_greeting.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Record-Name}:voicemail/vm-record_name2.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Change-Password}:voicemail/vm-change_password.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Main-Menu}:voicemail/vm-main_menu.wav"
/>
</match>
</input>
</macro>
<macro
name=
"record_name"
>
<input>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-record_name1.wav"
/>
</match>
</input>
</macro>
<macro
name=
"forward_ask_prepend"
>
<input>
<match>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Prepend}:voicemail/vm-forward_add_intro.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Forward}:voicemail/vm-send_message_now.wav"
/>
</match>
</input>
</macro>
<macro
name=
"forward_ask_extension"
>
<input>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-forward_enter_ext.wav"
/>
<!-- <action function="phrase" phrase="play-file" data="voicemail/vm-followed_by.wav"/>
<action function="say" data="${VM-Key-Terminate}" method="pronounced" type="name_spelled"/>-->
</match>
</input>
</macro>
<macro
name=
"record_file_check"
>
<input>
<match>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Listen-File}:voicemail/vm-listen_to_recording.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Save-File}:voicemail/vm-save_recording.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Record-File}:voicemail/vm-rerecord.wav"
/>
</match>
</input>
</macro>
<macro
name=
"record_urgent_check"
>
<input>
<match>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Urgent}:voicemail/vm-mark-urgent.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Terminator}:voicemail/vm-continue.wav"
/>
</match>
</input>
</macro>
<macro
name=
"forward_prepend"
>
<input>
<match>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Prepend}:voicemail/vm-forward_add_intro.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Forward}:voicemail/vm-send_message_now.wav"
/>
</match>
</input>
</macro>
<macro
name=
"forward_message_enter_extension"
>
<input
pattern=
"^([0-9#*])$"
>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-forward_enter_ext.wav"
/>
<action
function=
"play-file"
data=
"voicemail/vm-followed_by.wav"
/>
<action
function=
"say"
data=
"$1"
method=
"pronounced"
type=
"name_spelled"
/>
</match>
</input>
</macro>
<macro
name=
"invalid_extension"
>
<input>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-that_was_an_invalid_ext.wav"
/>
</match>
</input>
</macro>
<macro
name=
"listen_file_check"
>
<input>
<match>
<!--<action function="phrase" phrase="press_key@protovm" data="${VM-Key-Main-Next-Msg}:voicemail/vm-for_next_msg.wav"/>-->
<!-- Not existant in callie recordings -->
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Main-Listen-File}:voicemail/vm-listen_to_recording.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Main-Save-File}:voicemail/vm-save_recording.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Main-Delete-File}:voicemail/vm-delete_recording.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Main-Forward}:voicemail/vm-to_forward.wav"
/>
</match>
</input>
<input
field=
"${VM-Message-Email}"
pattern=
"^$"
>
<nomatch>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Main-Email}:voicemail/vm-forward_to_email.wav"
/>
</nomatch>
</input>
<input>
<match>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Main-Callback}:voicemail/vm-return_call.wav"
/>
<action
function=
"phrase"
phrase=
"press_key@protovm"
data=
"${VM-Key-Main-Forward}:voicemail/vm-to_forward.wav"
/>
</match>
</input>
</macro>
<macro
name=
"choose_greeting"
>
<input>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-choose_greeting_choose.wav"
/>
</match>
</input>
</macro>
<macro
name=
"choose_greeting_fail"
>
<input>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-choose_greeting_fail.wav"
/>
</match>
</input>
</macro>
<macro
name=
"record_greeting"
>
<input>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-record_greeting.wav"
/>
</match>
</input>
</macro>
<macro
name=
"record_message"
>
<input>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-record_message.wav"
/>
</match>
</input>
</macro>
<macro
name=
"greeting_selected"
>
<input
pattern=
"^(\d+)$"
>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-greeting.wav"
/>
<action
function=
"say"
data=
"$1"
method=
"pronounced"
type=
"items"
/>
<action
function=
"play-file"
data=
"voicemail/vm-selected.wav"
/>
</match>
</input>
</macro>
<macro
name=
"play_greeting"
>
<input
pattern=
"^(.*)$"
>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-person.wav"
/>
<action
function=
"say"
data=
"$1"
method=
"pronounced"
type=
"name_spelled"
/>
<action
function=
"play-file"
data=
"voicemail/vm-not_available.wav"
/>
</match>
</input>
</macro>
<macro
name=
"say_number"
>
<input
pattern=
"^(\d+)$"
>
<match>
<action
function=
"say"
data=
"$1"
method=
"pronounced"
type=
"items"
/>
</match>
</input>
</macro>
<macro
name=
"say_message_number"
>
<input>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-${VM-Message-Type}.wav"
/>
<action
function=
"play-file"
data=
"voicemail/vm-message_number.wav"
/>
<action
function=
"say"
data=
"${VM-Message-Number}"
method=
"pronounced"
type=
"items"
/>
</match>
</input>
</macro>
<macro
name=
"say_phone_number"
>
<input
pattern=
"^(.*)$"
>
<match>
<action
function=
"say"
data=
"$1"
method=
"pronounced"
type=
"name_spelled"
/>
</match>
</input>
</macro>
<macro
name=
"say_name"
>
<input
pattern=
"^(.*)$"
>
<match>
<action
function=
"say"
data=
"$1"
method=
"pronounced"
type=
"name_spelled"
/>
</match>
</input>
</macro>
<!-- Note: Update this to marked-urgent,emailed and saved once new sound files are recorded -->
<macro
name=
"ack"
>
<input
pattern=
"^(too-small)$"
>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-too-small.wav"
/>
</match>
</input>
<input
pattern=
"^(undeleted)$"
>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-message.wav"
/>
<action
function=
"play-file"
data=
"voicemail/vm-$1.wav"
/>
</match>
</input>
<input
pattern=
"^(deleted)$"
>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-message.wav"
/>
<action
function=
"play-file"
data=
"voicemail/vm-$1.wav"
/>
</match>
</input>
<input
pattern=
"^(saved)$"
>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-message.wav"
/>
<action
function=
"play-file"
data=
"voicemail/vm-$1.wav"
/>
</match>
</input>
<input
pattern=
"^(emailed)$"
>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-message.wav"
/>
<action
function=
"play-file"
data=
"voicemail/vm-$1.wav"
/>
</match>
</input>
<input
pattern=
"^(marked-urgent)$"
>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-message.wav"
/>
<action
function=
"play-file"
data=
"voicemail/vm-$1.wav"
/>
</match>
</input>
</macro>
<macro
name=
"say_date"
>
<input
pattern=
"^(.*)$"
>
<match>
<action
function=
"say"
data=
"$1"
method=
"pronounced"
type=
"short_date_time"
/>
</match>
</input>
</macro>
<macro
name=
"say_date_event"
>
<input>
<match>
<action
function=
"say"
data=
"${VM-Message-Received-Epoch}"
method=
"pronounced"
type=
"short_date_time"
/>
</match>
</input>
</macro>
<macro
name=
"play_message"
>
<input>
<match>
<action
function=
"play-file"
data=
"${VM-Message-File-Path}"
/>
</match>
</input>
</macro>
<macro
name=
"play_recording"
>
<input>
<match>
<action
function=
"play-file"
data=
"${VM-Record-File-Path}"
/>
</match>
</input>
</macro>
<macro
name=
"disk_quota_exceeded"
>
<input>
<match>
<action
function=
"play-file"
data=
"voicemail/vm-mailbox_full.wav"
/>
</match>
</input>
</macro>
</macros>
</include>
<!--This line will be ignored it's here to validate the xml and is optional -->
src/mod/applications/mod_protovm/util.c
deleted
100644 → 0
浏览文件 @
d48edc53
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
*
* 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 <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Marc Olivier Chouinard <mochouinard@moctel.com>
*
*
* utils.c -- MT VoiceMail / Different utility that might need to go into the core (after cleanup)
*
*/
#include <switch.h>
#include "util.h"
switch_status_t
mt_merge_media_files
(
const
char
**
inputs
,
const
char
*
output
)
{
switch_status_t
status
=
SWITCH_STATUS_SUCCESS
;
switch_file_handle_t
fh_output
=
{
0
};
int
channels
=
1
;
int
rate
=
8000
;
/* TODO Make this configurable */
int
j
=
0
;
if
(
switch_core_file_open
(
&
fh_output
,
output
,
channels
,
rate
,
SWITCH_FILE_FLAG_WRITE
|
SWITCH_FILE_DATA_SHORT
,
NULL
)
!=
SWITCH_STATUS_SUCCESS
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Couldn't open %s
\n
"
,
output
);
goto
end
;
}
for
(
j
=
0
;
inputs
[
j
]
!=
NULL
&&
j
<
128
&&
status
==
SWITCH_STATUS_SUCCESS
;
j
++
)
{
switch_file_handle_t
fh_input
=
{
0
};
char
buf
[
2048
];
switch_size_t
len
=
sizeof
(
buf
)
/
2
;
if
(
switch_core_file_open
(
&
fh_input
,
inputs
[
j
],
channels
,
rate
,
SWITCH_FILE_FLAG_READ
|
SWITCH_FILE_DATA_SHORT
,
NULL
)
!=
SWITCH_STATUS_SUCCESS
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Couldn't open %s
\n
"
,
inputs
[
j
]);
status
=
SWITCH_STATUS_GENERR
;
break
;
}
while
(
switch_core_file_read
(
&
fh_input
,
buf
,
&
len
)
==
SWITCH_STATUS_SUCCESS
)
{
if
(
switch_core_file_write
(
&
fh_output
,
buf
,
&
len
)
!=
SWITCH_STATUS_SUCCESS
)
{
switch_log_printf
(
SWITCH_CHANNEL_LOG
,
SWITCH_LOG_ERROR
,
"Write error
\n
"
);
status
=
SWITCH_STATUS_GENERR
;
break
;
}
}
if
(
fh_input
.
file_interface
)
{
switch_core_file_close
(
&
fh_input
);
}
}
if
(
fh_output
.
file_interface
)
{
switch_core_file_close
(
&
fh_output
);
}
end:
return
status
;
}
switch_event_t
*
jsonapi2event
(
switch_core_session_t
*
session
,
switch_event_t
*
apply_event
,
const
char
*
api
,
const
char
*
data
)
{
switch_event_t
*
phrases_event
=
NULL
;
switch_stream_handle_t
stream
=
{
0
};
SWITCH_STANDARD_STREAM
(
stream
);
switch_api_execute
(
api
,
data
,
session
,
&
stream
);
switch_event_create_json
(
&
phrases_event
,
(
char
*
)
stream
.
data
);
switch_safe_free
(
stream
.
data
);
if
(
apply_event
)
{
switch_event_header_t
*
hp
;
for
(
hp
=
phrases_event
->
headers
;
hp
;
hp
=
hp
->
next
)
{
if
(
!
strncasecmp
(
hp
->
name
,
"VM-"
,
3
))
{
switch_event_add_header
(
apply_event
,
SWITCH_STACK_BOTTOM
,
hp
->
name
,
"%s"
,
hp
->
value
);
}
}
switch_event_destroy
(
&
phrases_event
);
phrases_event
=
apply_event
;
}
return
phrases_event
;
}
char
*
generate_random_file_name
(
switch_core_session_t
*
session
,
const
char
*
mod_name
,
char
*
file_extension
)
{
char
rand_uuid
[
SWITCH_UUID_FORMATTED_LENGTH
+
1
]
=
""
;
switch_uuid_t
srand_uuid
;
switch_uuid_get
(
&
srand_uuid
);
switch_uuid_format
(
rand_uuid
,
&
srand_uuid
);
return
switch_core_session_sprintf
(
session
,
"%s%s%s_%s.%s"
,
SWITCH_GLOBAL_dirs
.
temp_dir
,
SWITCH_PATH_SEPARATOR
,
mod_name
,
rand_uuid
,
file_extension
);
}
switch_status_t
mt_api_execute
(
switch_core_session_t
*
session
,
const
char
*
apiname
,
const
char
*
arguments
)
{
switch_status_t
status
=
SWITCH_STATUS_SUCCESS
;
switch_stream_handle_t
stream
=
{
0
};
SWITCH_STANDARD_STREAM
(
stream
);
switch_api_execute
(
apiname
,
arguments
,
session
,
&
stream
);
if
(
!
strncasecmp
(
stream
.
data
,
"-ERR"
,
4
))
{
status
=
SWITCH_STATUS_GENERR
;
}
switch_safe_free
(
stream
.
data
);
return
status
;
}
void
append_event_profile
(
switch_event_t
*
phrase_params
,
vmivr_profile_t
*
profile
,
vmivr_menu_profile_t
menu
)
{
/* Used for some appending function */
if
(
profile
->
name
&&
profile
->
id
&&
profile
->
domain
)
{
switch_event_add_header
(
phrase_params
,
SWITCH_STACK_BOTTOM
,
"VM-Profile"
,
"%s"
,
profile
->
name
);
switch_event_add_header
(
phrase_params
,
SWITCH_STACK_BOTTOM
,
"VM-Account-ID"
,
"%s"
,
profile
->
id
);
switch_event_add_header
(
phrase_params
,
SWITCH_STACK_BOTTOM
,
"VM-Account-Domain"
,
"%s"
,
profile
->
domain
);
}
}
void
populate_dtmfa_from_event
(
switch_event_t
*
phrase_params
,
vmivr_profile_t
*
profile
,
vmivr_menu_profile_t
menu
,
char
**
dtmfa
)
{
int
i
=
0
;
if
(
menu
.
event_keys_dtmf
)
{
switch_event_header_t
*
hp
;
for
(
hp
=
menu
.
event_keys_dtmf
->
headers
;
hp
;
hp
=
hp
->
next
)
{
if
(
strlen
(
hp
->
name
)
<
3
&&
hp
->
value
)
{
/* TODO This is a hack to discard default FS Events ! */
const
char
*
varphrasename
=
switch_event_get_header
(
menu
.
event_keys_varname
,
hp
->
value
);
dtmfa
[
i
++
]
=
hp
->
name
;
if
(
varphrasename
&&
!
zstr
(
varphrasename
))
{
switch_event_add_header
(
phrase_params
,
SWITCH_STACK_BOTTOM
,
varphrasename
,
"%s"
,
hp
->
name
);
}
}
}
}
}
void
append_event_message
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
,
switch_event_t
*
phrase_params
,
switch_event_t
*
msg_list_event
,
size_t
current_msg
)
{
char
*
varname
;
char
*
apicmd
;
varname
=
switch_mprintf
(
"VM-List-Message-%"
SWITCH_SIZE_T_FMT
"-UUID"
,
current_msg
);
apicmd
=
switch_mprintf
(
"json %s %s %s %s"
,
profile
->
api_profile
,
profile
->
domain
,
profile
->
id
,
switch_event_get_header
(
msg_list_event
,
varname
));
switch_safe_free
(
varname
);
jsonapi2event
(
session
,
phrase_params
,
profile
->
api_msg_get
,
apicmd
);
/* TODO Set these 2 header correctly */
switch_event_add_header
(
phrase_params
,
SWITCH_STACK_BOTTOM
,
"VM-Message-Type"
,
"%s"
,
"new"
);
switch_event_add_header
(
phrase_params
,
SWITCH_STACK_BOTTOM
,
"VM-Message-Number"
,
"%"
SWITCH_SIZE_T_FMT
,
current_msg
);
switch_event_add_header_string
(
phrase_params
,
SWITCH_STACK_BOTTOM
,
"VM-Message-Private-Local-Copy"
,
"False"
);
switch_safe_free
(
apicmd
);
}
src/mod/applications/mod_protovm/util.h
deleted
100644 → 0
浏览文件 @
d48edc53
#ifndef _UTIL_H_
#define _UTIL_H_
#include "config.h"
switch_status_t
mt_merge_files
(
const
char
**
inputs
,
const
char
*
output
);
void
append_event_message
(
switch_core_session_t
*
session
,
vmivr_profile_t
*
profile
,
switch_event_t
*
phrase_params
,
switch_event_t
*
msg_list_event
,
size_t
current_msg
);
void
append_event_profile
(
switch_event_t
*
phrase_params
,
vmivr_profile_t
*
profile
,
vmivr_menu_profile_t
menu
);
char
*
generate_random_file_name
(
switch_core_session_t
*
session
,
const
char
*
mod_name
,
char
*
file_extension
);
switch_event_t
*
jsonapi2event
(
switch_core_session_t
*
session
,
switch_event_t
*
apply_event
,
const
char
*
api
,
const
char
*
data
);
switch_status_t
mt_merge_media_files
(
const
char
**
inputs
,
const
char
*
output
);
switch_status_t
mt_api_execute
(
switch_core_session_t
*
session
,
const
char
*
apiname
,
const
char
*
arguments
);
void
populate_dtmfa_from_event
(
switch_event_t
*
phrase_params
,
vmivr_profile_t
*
profile
,
vmivr_menu_profile_t
menu
,
char
**
dtmfa
);
#endif
/* _UTIL_H_ */
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论