mirror of https://github.com/sipwise/sems.git
We have to stop using patches for the sems CE, because it makes no sense anymore - upstream project is dead. This commit sets a goal to: - change compilation procedure so we do not consider patches anymore; Change-Id: Ifa4b4aabcc05802deff87f7a92ce857cc7d60d1emr11.2.1
parent
544c77403c
commit
6c054d35d1
@ -1,130 +0,0 @@
|
||||
From efbb87f805fcf4325060c9dbfd6c92c01537886b Mon Sep 17 00:00:00 2001
|
||||
From: Guillem Jover <gjover@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:13 +0100
|
||||
Subject: MT#55831 Make the code build again
|
||||
|
||||
Due to the build system not failing on compilation/link errors, parts of
|
||||
the code base has suffered bit rot.
|
||||
|
||||
(real ticket number: TT#6850)
|
||||
|
||||
---
|
||||
|
||||
--- ngcp-sems-1.6.0.orig/apps/examples/b2b_connect/b2b_connect.cpp
|
||||
+++ ngcp-sems-1.6.0/apps/examples/b2b_connect/b2b_connect.cpp
|
||||
@@ -251,10 +251,11 @@ inline UACAuthCred* b2b_connectCalleeSes
|
||||
return &credentials;
|
||||
}
|
||||
|
||||
-void b2b_connectCalleeSession::onSipReply(const AmSipReply& reply,
|
||||
+void b2b_connectCalleeSession::onSipReply(const AmSipRequest& req,
|
||||
+ const AmSipReply& reply,
|
||||
AmSipDialog::Status old_dlg_status) {
|
||||
|
||||
- AmB2ABCalleeSession::onSipReply(reply, old_dlg_status);
|
||||
+ AmB2ABCalleeSession::onSipReply(req, reply, old_dlg_status);
|
||||
|
||||
if ((old_dlg_status < AmSipDialog::Connected) &&
|
||||
(dlg->getStatus() == AmSipDialog::Disconnected)) {
|
||||
--- ngcp-sems-1.6.0.orig/apps/examples/b2b_connect/b2b_connect.h
|
||||
+++ ngcp-sems-1.6.0/apps/examples/b2b_connect/b2b_connect.h
|
||||
@@ -84,7 +84,7 @@ class b2b_connectCalleeSession
|
||||
AmSipRequest invite_req;
|
||||
|
||||
protected:
|
||||
- void onSipReply(const AmSipReply& reply, AmSipDialog::Status old_dlg_status);
|
||||
+ void onSipReply(const AmSipRequest& req, const AmSipReply& reply, AmSipDialog::Status old_dlg_status);
|
||||
|
||||
public:
|
||||
b2b_connectCalleeSession(const string& other_tag,
|
||||
--- ngcp-sems-1.6.0.orig/apps/examples/cacheannounce/CacheAnnounce.cpp
|
||||
+++ ngcp-sems-1.6.0/apps/examples/cacheannounce/CacheAnnounce.cpp
|
||||
@@ -120,7 +120,7 @@ void CacheAnnounceDialog::process(AmEven
|
||||
|
||||
AmAudioEvent* audio_event = dynamic_cast<AmAudioEvent*>(event);
|
||||
if(audio_event && (audio_event->event_id == AmAudioEvent::cleared)){
|
||||
- dlg.bye();
|
||||
+ dlg->bye();
|
||||
setStopped();
|
||||
return;
|
||||
}
|
||||
--- ngcp-sems-1.6.0.orig/apps/examples/jukecall/Jukecall.cpp
|
||||
+++ ngcp-sems-1.6.0/apps/examples/jukecall/Jukecall.cpp
|
||||
@@ -128,10 +128,10 @@ void JukecallSession::process(AmEvent* e
|
||||
switch(state) {
|
||||
case JC_initial_announcement: {
|
||||
state = JC_connect;
|
||||
- string callee = "sip:" + dlg->user.substr(3) + "@" + dlg->domain;
|
||||
+ string callee = "sip:" + dlg->getUser().substr(3) + "@" + dlg->getDomain();
|
||||
DBG("-------------------------- connecting %s ------------------------\n", callee.c_str());
|
||||
connectCallee(callee, callee,
|
||||
- dlg->remote_party, dlg->remote_uri);
|
||||
+ dlg->getRemoteParty(), dlg->getRemoteUri());
|
||||
|
||||
return;
|
||||
|
||||
--- ngcp-sems-1.6.0.orig/apps/examples/pinauthconference/PinAuthConference.cpp
|
||||
+++ ngcp-sems-1.6.0/apps/examples/pinauthconference/PinAuthConference.cpp
|
||||
@@ -123,7 +123,7 @@ void PinAuthConferenceDialog::connectCon
|
||||
changeCallgroup(conf_id);
|
||||
|
||||
// get a channel from the status
|
||||
- channel.reset(AmConferenceStatus::getChannel(conf_id,getLocalTag()));
|
||||
+ channel.reset(AmConferenceStatus::getChannel(conf_id,getLocalTag(),RTPStream()->getSampleRate()));
|
||||
|
||||
// clear the playlist
|
||||
play_list.flush();
|
||||
--- ngcp-sems-1.6.0.orig/apps/examples/simple_conference/SimpleConference.cpp
|
||||
+++ ngcp-sems-1.6.0/apps/examples/simple_conference/SimpleConference.cpp
|
||||
@@ -66,13 +66,13 @@ SimpleConferenceDialog::SimpleConference
|
||||
SimpleConferenceDialog::~SimpleConferenceDialog()
|
||||
{
|
||||
// clean playlist items
|
||||
- play_list.close(false);
|
||||
+ play_list.flush();
|
||||
}
|
||||
|
||||
void SimpleConferenceDialog::onSessionStart()
|
||||
{
|
||||
// set the conference id ('conference room') to user part of ruri
|
||||
- conf_id = dlg->user;
|
||||
+ conf_id = dlg->getUser();
|
||||
|
||||
// open the beep file
|
||||
BeepSound.reset(new AmAudioFile());
|
||||
@@ -81,7 +81,7 @@ void SimpleConferenceDialog::onSessionSt
|
||||
}
|
||||
|
||||
// get a channel from the status
|
||||
- channel.reset(AmConferenceStatus::getChannel(conf_id,getLocalTag()));
|
||||
+ channel.reset(AmConferenceStatus::getChannel(conf_id,getLocalTag(),RTPStream()->getSampleRate()));
|
||||
|
||||
// add the channel to our playlist
|
||||
play_list.addToPlaylist(new AmPlaylistItem(channel.get(),
|
||||
@@ -100,7 +100,7 @@ void SimpleConferenceDialog::onSessionSt
|
||||
|
||||
void SimpleConferenceDialog::onBye(const AmSipRequest& req)
|
||||
{
|
||||
- play_list.close();
|
||||
+ play_list.flush();
|
||||
setInOut(NULL,NULL);
|
||||
channel.reset(NULL);
|
||||
setStopped();
|
||||
--- ngcp-sems-1.6.0.orig/apps/examples/urlcatcher/UrlCatcher.cpp
|
||||
+++ ngcp-sems-1.6.0/apps/examples/urlcatcher/UrlCatcher.cpp
|
||||
@@ -63,8 +63,14 @@ int UrlCatcherFactory::onLoad()
|
||||
AmSession* UrlCatcherFactory::onInvite(const AmSipRequest& req, const string& app_name,
|
||||
const map<string,string>& app_params)
|
||||
{
|
||||
+ const AmMimeBody* body = req.body.hasContentType(SIP_APPLICATION_SDP);
|
||||
+ if (!body) {
|
||||
+ ERROR("Missing MIME body\n");
|
||||
+ throw AmSession::Exception(404, "Not Found Here (Missing MIME body)");
|
||||
+ }
|
||||
+
|
||||
AmSdp sdp;
|
||||
- if (sdp.parse(req.body.c_str())) {
|
||||
+ if (sdp.parse((const char *)body->getPayload())) {
|
||||
ERROR("SDP parsing error\n");
|
||||
throw AmSession::Exception(404, "Not Found Here (SDP parse error)");
|
||||
}
|
||||
@ -1,74 +0,0 @@
|
||||
From efbb87f805fcf4325060c9dbfd6c92c01537886d Mon Sep 17 00:00:00 2001
|
||||
From: Guillem Jover <gjover@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:15 +0100
|
||||
Subject: MT#55831 Fix module exclusion logic
|
||||
|
||||
Fix module exclusion logic
|
||||
Several of the modules cannot be compiled because they miss Makefiles,
|
||||
others require additional dependencies or similar. So encode this in the
|
||||
build system so that people building do not have to figure this out, even
|
||||
if they pass an explicit list of modules to include or exclude.
|
||||
|
||||
(real ticket number: TT#6850)
|
||||
|
||||
---
|
||||
|
||||
--- ngcp-sems-1.6.0.orig/apps/Makefile
|
||||
+++ ngcp-sems-1.6.0/apps/Makefile
|
||||
@@ -1,7 +1,7 @@
|
||||
COREPATH ?= ../core
|
||||
.DEFAULT_GOAL := all
|
||||
|
||||
-local_exclude_app_modules=$(exclude_app_modules)
|
||||
+local_exclude_app_modules=confpin early_dbprompt mobile_push py_sems gateway twit
|
||||
|
||||
include $(COREPATH)/../Makefile.defs
|
||||
|
||||
@@ -12,28 +12,22 @@ include $(COREPATH)/../Makefile.defs
|
||||
# make $(app_modules)
|
||||
# else
|
||||
# if exclude_app_modules is set
|
||||
-# make * - $(exclude_app_modules)
|
||||
+# make * - $(exclude_app_modules) + local excludes
|
||||
# else
|
||||
# make * - Makefile.defs:exclude_app_modules + local excludes
|
||||
#
|
||||
|
||||
-ifneq ($(app_modules),)
|
||||
- app_modules = $(app_modules)
|
||||
-else
|
||||
- ifneq ($(local_exclude_app_modules),)
|
||||
- exclude_app_modules = $(local_exclude_app_modules)
|
||||
- else
|
||||
- exclude_app_modules += mp3 examples py_sems gateway jsonrpc twit db_reg_agent
|
||||
-
|
||||
- ifneq ($(USE_MONITORING), yes)
|
||||
- exclude_app_modules += monitoring
|
||||
- endif
|
||||
+ifeq ($(app_modules),)
|
||||
+ exclude_modules = $(exclude_app_modules)
|
||||
+ exclude_modules += $(local_exclude_app_modules)
|
||||
|
||||
+ ifneq ($(USE_MONITORING), yes)
|
||||
+ exclude_modules += monitoring
|
||||
endif
|
||||
|
||||
$(info local_exclude_app_modules: $(local_exclude_app_modules))
|
||||
$(info exclude_app_modules: $(exclude_app_modules))
|
||||
- app_modules = $(filter-out $(subst ;, ,$(exclude_app_modules))\
|
||||
+ app_modules = $(filter-out $(subst ;, ,$(exclude_modules)) \
|
||||
$(wildcard Makefile*) CVS CMakeLists.txt, \
|
||||
$(wildcard *) examples/tutorial/cc_acc )
|
||||
|
||||
--- ngcp-sems-1.6.0.orig/apps/examples/Makefile
|
||||
+++ ngcp-sems-1.6.0/apps/examples/Makefile
|
||||
@@ -3,7 +3,7 @@ COREPATH ?= ../../core
|
||||
|
||||
include $(COREPATH)/../Makefile.defs
|
||||
|
||||
-exclude_modules ?=
|
||||
+exclude_modules = ivr_examples
|
||||
modules = $(filter-out $(subst ;, ,$(exclude_modules)) \
|
||||
$(wildcard Makefile*) $(wildcard Readme*) CVS, \
|
||||
$(wildcard *) )
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
From efbb87f805fcf4325060c9dbfd6c92c01537886c Mon Sep 17 00:00:00 2001
|
||||
From: Guillem Jover <gjover@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:14 +0100
|
||||
Subject: MT#55831 Build the library as shared
|
||||
|
||||
Build the library as shared.
|
||||
Otherwise we are trying to link a static library built as PIE into a
|
||||
shared library.
|
||||
|
||||
(real ticket number: TT#6850)
|
||||
|
||||
---
|
||||
|
||||
--- ngcp-sems-1.6.0.orig/apps/rtmp/librtmp/Makefile
|
||||
+++ ngcp-sems-1.6.0/apps/rtmp/librtmp/Makefile
|
||||
@@ -30,7 +30,7 @@ SO_posix=so.0
|
||||
SO_mingw=dll
|
||||
SO_EXT=$(SO_$(SYS))
|
||||
|
||||
-SHARED=no
|
||||
+SHARED=yes
|
||||
SODEF_yes=-fPIC
|
||||
SOLIB_yes=librtmp.$(SO_EXT)
|
||||
SOINST_yes=install_$(SO_EXT)
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,24 +0,0 @@
|
||||
From 5634f22d2b3423b7988d7ca932846d8daa5e34f2 Mon Sep 17 00:00:00 2001
|
||||
From: Guillem Jover <gjover@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:17 +0100
|
||||
Subject: MT#55831 Use a proper accessor instead of messing with the struc directly
|
||||
|
||||
Use a proper accessor instead of messing with the struc directly
|
||||
which has become opaque in latest OpenSSL versions.
|
||||
(real ticket number: TT#12308)
|
||||
|
||||
---
|
||||
apps/diameter_client/lib_dbase/tcp_comm.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/apps/diameter_client/lib_dbase/tcp_comm.c
|
||||
+++ b/apps/diameter_client/lib_dbase/tcp_comm.c
|
||||
@@ -74,7 +74,7 @@ long tcp_ssl_dbg_cb(BIO *bio, int oper,
|
||||
switch (oper) {
|
||||
case BIO_CB_WRITE: {
|
||||
char buf[256];
|
||||
- snprintf(buf, 256, "%s: %s", argp, bio->method->name);
|
||||
+ snprintf(buf, 256, "%s: %s", argp, BIO_method_name(bio));
|
||||
INFO("%s", buf);
|
||||
} break;
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
From e580ff5ca6db1d455d6dc8e8942b8f29e0913ca7 Mon Sep 17 00:00:00 2001
|
||||
From: Victor Seva <vseva@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:06 +0100
|
||||
Subject: MT#55831 No config patch
|
||||
|
||||
No config patch
|
||||
|
||||
--- a/apps/Makefile
|
||||
+++ b/apps/Makefile
|
||||
@@ -69,7 +69,7 @@
|
||||
done
|
||||
|
||||
.PHONY: install
|
||||
-install: install-bin install-cfg
|
||||
+install: install-bin
|
||||
|
||||
.PHONY: install-bin
|
||||
install-bin:
|
||||
--- a/apps/dsm/mods/Makefile
|
||||
+++ b/apps/dsm/mods/Makefile
|
||||
@@ -45,7 +45,7 @@
|
||||
done
|
||||
|
||||
.PHONY: install
|
||||
-install: install-bin install-cfg
|
||||
+install: install-bin
|
||||
|
||||
.PHONY: install-bin
|
||||
install-bin:
|
||||
--- a/apps/examples/Makefile
|
||||
+++ b/apps/examples/Makefile
|
||||
@@ -33,7 +33,7 @@
|
||||
done
|
||||
|
||||
.PHONY: install
|
||||
-install: install-bin install-cfg
|
||||
+install: install-bin
|
||||
|
||||
.PHONY: install-bin
|
||||
install-bin:
|
||||
--- a/apps/examples/tutorial/Makefile
|
||||
+++ b/apps/examples/tutorial/Makefile
|
||||
@@ -33,7 +33,7 @@
|
||||
done
|
||||
|
||||
.PHONY: install
|
||||
-install: install-bin install-cfg
|
||||
+install: install-bin
|
||||
|
||||
.PHONY: install-bin
|
||||
install-bin:
|
||||
--- a/core/Makefile
|
||||
+++ b/core/Makefile
|
||||
@@ -117,8 +117,6 @@
|
||||
|
||||
install: all mk-install-dirs \
|
||||
install-audio \
|
||||
- install-modules-cfg \
|
||||
- install-cfg \
|
||||
install-bin \
|
||||
install-modules
|
||||
|
||||
@ -1,16 +0,0 @@
|
||||
From cc61483b348ea0a5aa0c6effa0d2961aee5bcb57 Mon Sep 17 00:00:00 2001
|
||||
From: Victor Seva <vseva@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:07 +0100
|
||||
Subject: MT#55831 fix py_sems install dir properly
|
||||
|
||||
fix py_sems install dir properly
|
||||
(real ticket number: MT#7349)
|
||||
|
||||
--- a/apps/py_sems/Makefile.defs
|
||||
+++ b/apps/py_sems/Makefile.defs
|
||||
@@ -15,4 +15,4 @@
|
||||
PYTHON_LIBDIR = $(shell $(PY_EXE) ./python_lib.py)
|
||||
|
||||
#
|
||||
-py-sems-modules-dir?=lib/sems/py_sems
|
||||
+py-sems-modules-dir?=lib/$(APP_NAME)/py_sems
|
||||
@ -1,45 +0,0 @@
|
||||
sipwise/tt52455.patch
|
||||
upstream/0000-b-f-sbc-fixed-reading-encoding-param-in-readPayload.patch
|
||||
upstream/0001-b-f-sbc-codecs-compare-encoding_param-only-if-both-0.patch
|
||||
upstream/0002-core-codec-init-support-for-fmt-params-negotiation-f.patch
|
||||
upstream/0003-core-amci-call-codec-module-init-function-with-mod_c.patch
|
||||
upstream/0004-core-rtp-stream-take-fmt-params-in-payload-initializ.patch
|
||||
upstream/0005-opus-configurable-codec-settings-for-OPUS-codec.patch
|
||||
upstream/0006-b-f-fixes-c7800ea-remove-leftover-stacktrace-in-setC.patch
|
||||
upstream/0007-b-f-fix-bbb13a1-remove-excessive-debug-info.patch
|
||||
upstream/0008-fix-for-c++11.patch
|
||||
#
|
||||
sipwise/sw_vcs.patch
|
||||
sipwise/0006-rename_xdigits.patch
|
||||
sipwise/0008-dsm-helper-functions-macros-for-modules-replaceParam.patch
|
||||
sipwise/0015-confpin-simple-pin-conference-app.patch
|
||||
sipwise/0017-MT-13599-don-t-create-CF-map-if-CF-is-denied-by-prof.patch
|
||||
no_config.patch
|
||||
py_sems_path.patch
|
||||
sipwise/MT-20649-add-vsc-for-block-in-clir
|
||||
sipwise/MT-20649-change-config-validation
|
||||
sipwise/MT-20649-use-macros
|
||||
sipwise/0002-b-f-dsm-mod_conference-set-callgroup-to-conference-c.patch
|
||||
sipwise/0018-db_reg_agent-add-username_with_domain-option-to-use-.patch
|
||||
sipwise/0019-TT-1640-core_increase-max-config-line.patch
|
||||
build-fix-bit-rot.patch
|
||||
build-fix-pie.patch
|
||||
build-fix-excludes.patch
|
||||
build-system-revamp.patch
|
||||
fix-build-with-newer-openssl.patch
|
||||
sipwise/0020-TT-9521-fix-200OK-without-SPD.patch
|
||||
sipwise/usage-reporting.patch
|
||||
sipwise/session_timers
|
||||
sipwise/introduce_forcesdp_from_pbx.patch
|
||||
sipwise/0001-TT-34704-Fix-sems-and-sems-pbx-to-write-pid-file-whe.patch
|
||||
sipwise/0001-TT-53685-add_header_pattern_match_support.patch
|
||||
sipwise/add-vsc-to-disable_all_cf.patch
|
||||
sipwise/handle_bye_after_180.patch
|
||||
sipwise/upgrade_to_bullseye.patch
|
||||
sipwise/port_to_py3k.patch
|
||||
sipwise/db_reg_agent_auth_header.patch
|
||||
sipwise/skip_outbound_auth_if_credentials_empty.patch
|
||||
sipwise/add_support_for_peering_outbound_registration.patch
|
||||
sipwise/cpslimit_detect_emergency_calls_and_let_them_pass.patch
|
||||
sipwise/dsm_modutils_fix_utils_get_count_files.patch
|
||||
sipwise/dsm_mod_curl_fix_ordered_comparison.patch
|
||||
@ -1,67 +0,0 @@
|
||||
From 12ea81babb899cd637426afd13740dc9729ca8d3 Mon Sep 17 00:00:00 2001
|
||||
From: Roman Romanchenko <rromanchenko@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:22 +0100
|
||||
Subject: MT#55831 Fix sems and sems-pbx to write pid file when running with -E option
|
||||
|
||||
- now pid file written with -E as well
|
||||
(real ticket number: TT#34704)
|
||||
|
||||
---
|
||||
core/sems.cpp | 15 +++++++--------
|
||||
1 file changed, 7 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/core/sems.cpp b/core/sems.cpp
|
||||
index 6f03e5cd..a1814d32 100644
|
||||
--- a/core/sems.cpp
|
||||
+++ b/core/sems.cpp
|
||||
@@ -207,11 +207,11 @@ static bool apply_args(std::map<char,string>& args)
|
||||
AmConfig::PlugInPath = it->second;
|
||||
break;
|
||||
|
||||
-#ifndef DISABLE_DAEMON_MODE
|
||||
case 'P':
|
||||
AmConfig::DaemonPidFile = it->second;
|
||||
break;
|
||||
|
||||
+#ifndef DISABLE_DAEMON_MODE
|
||||
case 'u':
|
||||
AmConfig::DaemonUid = it->second;
|
||||
break;
|
||||
@@ -535,10 +535,6 @@ int main(int argc, char* argv[])
|
||||
DBG("I'm out. pid: %d", main_pid);
|
||||
return 0;
|
||||
}
|
||||
-
|
||||
- if(write_pid_file()<0) {
|
||||
- goto error;
|
||||
- }
|
||||
|
||||
#ifdef PROPAGATE_COREDUMP_SETTINGS
|
||||
if (have_limit) {
|
||||
@@ -566,6 +562,10 @@ int main(int argc, char* argv[])
|
||||
};
|
||||
}
|
||||
|
||||
+ if(write_pid_file()<0) {
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
#endif /* DISABLE_DAEMON_MODE */
|
||||
|
||||
main_pid = getpid();
|
||||
@@ -661,10 +661,9 @@ int main(int argc, char* argv[])
|
||||
async_file_writer::instance()->stop();
|
||||
async_file_writer::instance()->join();
|
||||
|
||||
+ unlink(AmConfig::DaemonPidFile.c_str());
|
||||
+
|
||||
#ifndef DISABLE_DAEMON_MODE
|
||||
- if (AmConfig::DaemonMode) {
|
||||
- unlink(AmConfig::DaemonPidFile.c_str());
|
||||
- }
|
||||
if(fd[1]){
|
||||
main_pid = -1;
|
||||
DBG("send -1 to parent\n");
|
||||
--
|
||||
2.17.1
|
||||
|
||||
@ -1,39 +0,0 @@
|
||||
From e3f342754ac8c736b551c8b52376c15cb6e7f8dd Mon Sep 17 00:00:00 2001
|
||||
From: Kirill Solomko <ksolomko@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:23 +0100
|
||||
Subject: MT#55831 add header filter wildcard match support
|
||||
|
||||
'\*' \- matches 0 or more characters
|
||||
'?' \- matches any one character
|
||||
for more info, refer to <fnmatch\.h>
|
||||
(real ticket number: TT#53685)
|
||||
|
||||
--- a/apps/sbc/HeaderFilter.cpp
|
||||
+++ b/apps/sbc/HeaderFilter.cpp
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "log.h"
|
||||
#include "AmUtils.h"
|
||||
#include <algorithm>
|
||||
+#include <fnmatch.h>
|
||||
|
||||
const char* FilterType2String(FilterType ft) {
|
||||
switch(ft) {
|
||||
@@ -216,11 +217,13 @@
|
||||
}
|
||||
string hdr_name = hdrs.substr(start_pos, name_end-start_pos);
|
||||
std::transform(hdr_name.begin(), hdr_name.end(), hdr_name.begin(), ::tolower);
|
||||
- bool erase = false;
|
||||
- if (f_type == Whitelist) {
|
||||
- erase = headerfilter_list.find(hdr_name)==headerfilter_list.end();
|
||||
- } else if (f_type == Blacklist) {
|
||||
- erase = headerfilter_list.find(hdr_name)!=headerfilter_list.end();
|
||||
+ bool erase = (f_type == Whitelist);
|
||||
+ for (set<string>::iterator it = headerfilter_list.begin();
|
||||
+ it != headerfilter_list.end(); ++it) {
|
||||
+ if (fnmatch(it->c_str(), hdr_name.c_str(), 0) == 0) {
|
||||
+ erase = (f_type != Whitelist);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
if (erase) {
|
||||
DBG("erasing header '%s' by %s\n", hdr_name.c_str(), FilterType2String(f_type));
|
||||
@ -1,29 +0,0 @@
|
||||
From 5ec9bf2d042f90f0f29b7de2bb215a8cf6ba7169 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Sayer <stefan.sayer@googlemail.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:10 +0100
|
||||
Subject: MT#55831 dsm:mod_conference:set callgroup to conference channel
|
||||
|
||||
dsm:mod_conference:set callgroup to conference channel
|
||||
(real ticket number: MT#18839)
|
||||
|
||||
---
|
||||
apps/dsm/mods/mod_conference/ModConference.cpp | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/apps/dsm/mods/mod_conference/ModConference.cpp b/apps/dsm/mods/mod_conference/ModConference.cpp
|
||||
index 0028a14..8b2e2ce 100644
|
||||
--- a/apps/dsm/mods/mod_conference/ModConference.cpp
|
||||
+++ b/apps/dsm/mods/mod_conference/ModConference.cpp
|
||||
@@ -117,6 +117,9 @@ static bool ConferenceJoinChannel(DSMConfChannel** dsm_chan,
|
||||
DSMSession* sc_sess,
|
||||
const string& channel_id,
|
||||
const string& mode) {
|
||||
+ DBG("changing callgroup for session to %s\n", channel_id.c_str());
|
||||
+ sess->changeCallgroup(channel_id);
|
||||
+
|
||||
bool connect_play = false;
|
||||
bool connect_record = false;
|
||||
if (mode.empty()) {
|
||||
--
|
||||
2.6.4 (Apple Git-63)
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
From d1f87cfcb35f4fe27078f7760e9b4a5fff8e189c Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Pogrebennyk <apogrebennyk@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:02 +0100
|
||||
Subject: MT#55831 rename prompts x1..9.wav to 1..9-and.wav
|
||||
|
||||
rename prompts x1..9.wav to 1..9-and.wav
|
||||
|
||||
(real ticket number: MT#11239 MT#11219)
|
||||
|
||||
--- a/apps/dsm/mods/mod_utils/ModUtils.cpp
|
||||
+++ b/apps/dsm/mods/mod_utils/ModUtils.cpp
|
||||
@@ -97,10 +97,10 @@
|
||||
if (right) {
|
||||
// language has single digits before 10s
|
||||
res.push_back(basedir+int2str(num.quot * 10)+suffix);
|
||||
- res.push_back(basedir+("x"+int2str(num.rem))+suffix);
|
||||
+ res.push_back(basedir+(int2str(num.rem)+"-and")+suffix);
|
||||
} else {
|
||||
// language has single digits before 10s
|
||||
- res.push_back(basedir+("x"+int2str(num.rem))+suffix);
|
||||
+ res.push_back(basedir+(int2str(num.rem)+"-and")+suffix);
|
||||
res.push_back(basedir+int2str(num.quot * 10)+suffix);
|
||||
}
|
||||
|
||||
@@ -136,10 +136,10 @@
|
||||
if (right) {
|
||||
// language has single digits before 10s
|
||||
sc_sess->playFile(basedir+int2str(num.quot * 10)+suffix, false);
|
||||
- sc_sess->playFile(basedir+("x"+int2str(num.rem))+suffix, false);
|
||||
+ sc_sess->playFile(basedir+(int2str(num.rem)+"-and")+suffix, false);
|
||||
} else {
|
||||
// language has single digits before 10s
|
||||
- sc_sess->playFile(basedir+("x"+int2str(num.rem))+suffix, false);
|
||||
+ sc_sess->playFile(basedir+(int2str(num.rem)+"-and")+suffix, false);
|
||||
sc_sess->playFile(basedir+int2str(num.quot * 10)+suffix, false);
|
||||
}
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
From 4ec1e1d2d06359c599d9fc551478d443934c616c Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Sayer <stefan.sayer@googlemail.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:03 +0100
|
||||
Subject: MT#55831 dsm: helper functions / macros for modules:
|
||||
|
||||
replaceParams/SET_ERROR/CLR_ERROR
|
||||
|
||||
use resolveVars in module actions/condition to replace only one variable/param,
|
||||
use replaceParams to replace substrings as well,
|
||||
|
||||
e.g. myAction($myvar) - resolveVars
|
||||
myOtherAction("this is $(myvar) and #(myparam) replaced") - replaceParams
|
||||
---
|
||||
apps/dsm/DSMCoreModule.h | 4 ++++
|
||||
apps/dsm/DSMSession.h | 12 ++++++++++++
|
||||
2 files changed, 16 insertions(+)
|
||||
|
||||
--- a/apps/dsm/DSMCoreModule.h
|
||||
+++ b/apps/dsm/DSMCoreModule.h
|
||||
@@ -175,4 +175,8 @@
|
||||
string replaceParams(const string& q, AmSession* sess, DSMSession* sc_sess,
|
||||
map<string,string>* event_params);
|
||||
|
||||
+/** return string q with variables/params/selects replaced */
|
||||
+string replaceParams(const string& q, AmSession* sess, DSMSession* sc_sess,
|
||||
+ map<string,string>* event_params);
|
||||
+
|
||||
#endif
|
||||
--- a/apps/dsm/DSMSession.h
|
||||
+++ b/apps/dsm/DSMSession.h
|
||||
@@ -111,6 +111,18 @@
|
||||
s->CLR_STRERROR; \
|
||||
} while (0)
|
||||
|
||||
+#define SET_ERROR(s, errno, errstr) \
|
||||
+ do { \
|
||||
+ s->SET_ERRNO(errno); \
|
||||
+ s->SET_STRERROR(errstr); \
|
||||
+ } while (0)
|
||||
+
|
||||
+#define CLR_ERROR(s) \
|
||||
+ do { \
|
||||
+ s->CLR_ERRNO; \
|
||||
+ s->CLR_STRERROR; \
|
||||
+ } while (0)
|
||||
+
|
||||
typedef map<string, string> VarMapT;
|
||||
typedef map<string, AmArg> AVarMapT;
|
||||
|
||||
@ -1,559 +0,0 @@
|
||||
From fe53372de8a97d3af08dc3e54d842a4291449190 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Sayer <stefan.sayer@googlemail.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:04 +0100
|
||||
Subject: MT#55831 confpin: simple pin conference app
|
||||
|
||||
---
|
||||
apps/confpin/confpin.conf | 39 +++++
|
||||
apps/confpin/lib/confpin.dsm | 237 ++++++++++++++++++++++++++
|
||||
apps/confpin/lib/sw_audio.dsm | 50 ++++++
|
||||
apps/confpin/lib/sw_audio_api.dsm | 66 +++++++
|
||||
apps/confpin/prompts/Makefile | 22 +++
|
||||
apps/confpin/prompts/conference_first.txt | 1 +
|
||||
apps/confpin/prompts/conference_greeting.txt | 1 +
|
||||
apps/confpin/prompts/conference_join.txt | 1 +
|
||||
apps/confpin/prompts/conference_joined.txt | 1 +
|
||||
apps/confpin/prompts/conference_leave.txt | 1 +
|
||||
apps/confpin/prompts/conference_music.txt | 1 +
|
||||
apps/confpin/prompts/conference_pin_wrong.txt | 1 +
|
||||
apps/confpin/prompts/goodbye.txt | 1 +
|
||||
apps/confpin/tools/clear_file | 14 ++
|
||||
apps/confpin/tools/fetch_file | 14 ++
|
||||
apps/confpin/tools/push_file | 14 ++
|
||||
16 files changed, 464 insertions(+)
|
||||
create mode 100644 apps/confpin/confpin.conf
|
||||
create mode 100644 apps/confpin/lib/confpin.dsm
|
||||
create mode 100644 apps/confpin/lib/sw_audio.dsm
|
||||
create mode 100644 apps/confpin/lib/sw_audio_api.dsm
|
||||
create mode 100644 apps/confpin/prompts/Makefile
|
||||
create mode 100644 apps/confpin/prompts/conference_first.txt
|
||||
create mode 100644 apps/confpin/prompts/conference_greeting.txt
|
||||
create mode 100644 apps/confpin/prompts/conference_join.txt
|
||||
create mode 100644 apps/confpin/prompts/conference_joined.txt
|
||||
create mode 100644 apps/confpin/prompts/conference_leave.txt
|
||||
create mode 100644 apps/confpin/prompts/conference_music.txt
|
||||
create mode 100644 apps/confpin/prompts/conference_pin_wrong.txt
|
||||
create mode 100644 apps/confpin/prompts/goodbye.txt
|
||||
create mode 100755 apps/confpin/tools/clear_file
|
||||
create mode 100755 apps/confpin/tools/fetch_file
|
||||
create mode 100755 apps/confpin/tools/push_file
|
||||
|
||||
(real ticket number: MT#11241)
|
||||
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/confpin.conf
|
||||
@@ -0,0 +1,39 @@
|
||||
+# configuration for confpin app
|
||||
+
|
||||
+
|
||||
+# audio cache configuration
|
||||
+# audio_cache - same as cache_dir in audio_cache.conf
|
||||
+#audio_cache=/tmp
|
||||
+#audio_cache=/home/stefan/frafos/customers/sipwise/pbx/new_repo/sipwise_modules/callqueues/prompts
|
||||
+audio_cache=../apps/confpin/cache/
|
||||
+# MySQL database connection for downloading audio prompts
|
||||
+db_url=mysql://root:frafos@127.0.0.1/provisioning
|
||||
+
|
||||
+# default sound set if non provisioned with app-param
|
||||
+sound_set_id=1
|
||||
+
|
||||
+digit_collection_timeout=10
|
||||
+
|
||||
+###### digits - to be put into DB
|
||||
+#digits_right=yes or no
|
||||
+# single digits before 10s - for e.g. German: no, for eg. English: yes
|
||||
+digits_right=yes
|
||||
+# directory with digits - e.g. cache directory
|
||||
+# the language (lng app param) will be added at the end, e.g.
|
||||
+# digits_dir=../apps/callingcard/prompts/es/
|
||||
+digits_dir=../../sipwise_modules/callqueues/prompts/
|
||||
+
|
||||
+#######
|
||||
+# it's best to leave those below as-is
|
||||
+#diag_path=/usr/lib/sems/dsm/confpin
|
||||
+#mod_path=/usr/lib/sems/dsm/
|
||||
+
|
||||
+# in-tree testing:
|
||||
+diag_path=../apps/confpin/lib
|
||||
+mod_path=../apps/dsm/mods/lib/
|
||||
+
|
||||
+load_diags=confpin,sw_audio_api
|
||||
+register_apps=confpin
|
||||
+run_invite_event=yes
|
||||
+set_param_variables=yes
|
||||
+run_system_dsms=sw_audio_api
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/lib/confpin.dsm
|
||||
@@ -0,0 +1,237 @@
|
||||
+#[% TAGS [- -] %]
|
||||
+---
|
||||
+-- This DSM app
|
||||
+-- * asks caller to enter pin for conference room
|
||||
+-- * puts caller in conference room identified by roompin
|
||||
+--
|
||||
+-- Parameters (P-App-Param):
|
||||
+-- confpin - dsm app
|
||||
+-- roompin - pin from db for particular subscriber
|
||||
+-- room - conference room consists subscriber and roompin
|
||||
+-- sound_set_id - sound set to use
|
||||
+--
|
||||
+-- Example: P-App-Param: confpin;roompin="pin_from_db";room="$fU"_"pin_from_db";sound_set_id=3
|
||||
+--
|
||||
+
|
||||
+import(mod_conference);
|
||||
+import(mod_dlg);
|
||||
+import(mod_utils);
|
||||
+import(mod_groups);
|
||||
+
|
||||
+#include "sw_audio.dsm"
|
||||
+
|
||||
+function stopCall() {
|
||||
+ stop(true);
|
||||
+};
|
||||
+
|
||||
+function refuseWith500() {
|
||||
+ set(connect_session=0);
|
||||
+ dlg.reply(500, "Server Internal Error");
|
||||
+ stop(false);
|
||||
+};
|
||||
+
|
||||
+function enterConference() {
|
||||
+ set($audio_id="conference_joined");
|
||||
+ swMixInFile();
|
||||
+ info(">> entering conference in room '$room'");
|
||||
+ conference.setPlayoutType(adaptive);
|
||||
+ conference.join($room);
|
||||
+ set($joined=true);
|
||||
+ groups.postEvent($room, joined);
|
||||
+ groups.join($room);
|
||||
+ groups.getSize($roomsize=$room);
|
||||
+ if test($roomsize==1) {
|
||||
+ set($audio_id="conference_first");
|
||||
+ swMixInFile();
|
||||
+ set($audio_id="conference_music");
|
||||
+ set($sw_audio_loop="true");
|
||||
+ swMixInFile();
|
||||
+ clear($sw_audio_loop);
|
||||
+ set($lonely_user=true);
|
||||
+ }
|
||||
+ info("entered conference, $roomsize people in here<<");
|
||||
+};
|
||||
+initial state START;
|
||||
+
|
||||
+transition "DB exception" START - exception / {
|
||||
+ error("Error in initializing :");
|
||||
+ refuseWith500();
|
||||
+} -> END;
|
||||
+
|
||||
+transition "check for sound_set_id provisioning" START - invite; test($sound_set_id=="") / {
|
||||
+ error("Error in provisioning: no sound_set_id application parameter set");
|
||||
+ refuseWith500();
|
||||
+} -> END;
|
||||
+
|
||||
+transition "Fetching File exception" START - exception; test(#type=="result") / {
|
||||
+ error("error in DB query for fetching audio file:");
|
||||
+ logAll(1);
|
||||
+ stop(true);
|
||||
+} -> END;
|
||||
+
|
||||
+transition "call starts" START - invite / {
|
||||
+ -- process session establishment in DSM app
|
||||
+ set(connect_session=0);
|
||||
+ dlg.acceptInvite();
|
||||
+ connectMedia();
|
||||
+
|
||||
+ -- connect to DB
|
||||
+ mysql.connect();
|
||||
+
|
||||
+ if test($roompin=="")
|
||||
+ {
|
||||
+ info(pin is empty);
|
||||
+ set($autoEnter=1);
|
||||
+ repost();
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ info(">> start_pin_entry");
|
||||
+ set($tryAgain=0);
|
||||
+ set($pin="");
|
||||
+
|
||||
+ -- rfc4240
|
||||
+ if test($room=="") {
|
||||
+ info("room is empty");
|
||||
+ dlg.reply(404,"Not found");
|
||||
+ } else {
|
||||
+ set($audio_id="conference_greeting");
|
||||
+ swPlayFile();
|
||||
+ }
|
||||
+ info("start_pin_entry <<");
|
||||
+ }
|
||||
+} -> COLLECT_PIN;
|
||||
+
|
||||
+--------------------------------------------------------
|
||||
+state COLLECT_PIN;
|
||||
+transition "prompt ends, start collection timer" COLLECT_PIN - noAudio / setTimer(1, $config.digit_collection_timeout) -> COLLECT_PIN;
|
||||
+
|
||||
+transition "roompin empty, enter conference" COLLECT_PIN - test($autoEnter==1) / {
|
||||
+ info(">> empty_pin");
|
||||
+ enterConference();
|
||||
+} -> CONFERENCE;
|
||||
+
|
||||
+transition "timer, short pin, too many tries" COLLECT_PIN - timer(#id==1); test(len($pin)<3); test($pin_tries==$config.pin_max_retries) / {
|
||||
+ stopCall();
|
||||
+} -> END;
|
||||
+transition "timer, short pin, too many tries" COLLECT_PIN - timer(#id==1); test(len($pin)<3); test($pin_tries>$config.pin_max_retries) / {
|
||||
+ stopCall();
|
||||
+} -> END;
|
||||
+transition "hash entered, short pin, too many tries" COLLECT_PIN - key(#key==11); test(len($pin)<3); test($pin_tries>$config.pin_max_retries) / {
|
||||
+ stopCall();
|
||||
+} -> END;
|
||||
+transition "hash entered, short pin, too many tries" COLLECT_PIN - key(#key==11); test(len($pin)<3); test($pin_tries==$config.pin_max_retries) / {
|
||||
+ stopCall();
|
||||
+} -> END;
|
||||
+
|
||||
+transition "collect pin timer hit, short pin" COLLECT_PIN - timer(#id==1); test(len($pin)<3) / {
|
||||
+ set($audio_id="conference_pin_wrong");
|
||||
+ swPlayFile();
|
||||
+ inc($pin_tries);
|
||||
+} -> COLLECT_PIN;
|
||||
+
|
||||
+transition "hash entered, short pin" COLLECT_PIN - key(#key==11); test(len($pin)<3) / {
|
||||
+ set($audio_id="conference_pin_wrong");
|
||||
+ swPlayFile();
|
||||
+ inc($pin_tries);
|
||||
+} -> COLLECT_PIN;
|
||||
+
|
||||
+transition "number entered" COLLECT_PIN - key(#key<10) / {
|
||||
+ -- stop prompt
|
||||
+ closePlaylist(false);
|
||||
+ append($pin, #key);
|
||||
+ info("USER ENTERED key '#key'");
|
||||
+ setTimer(1, $config.digit_collection_timeout);
|
||||
+} -> COLLECT_PIN;
|
||||
+
|
||||
+transition "collect pin timer hit" COLLECT_PIN - timer(#id==1) -> TESTPINRESULT;
|
||||
+transition "hash entered, finished pin" COLLECT_PIN - key(#key==11) / removeTimer(1) -> TESTPINRESULT;
|
||||
+
|
||||
+--------------------------------------------------------
|
||||
+state TESTPINRESULT
|
||||
+enter {
|
||||
+ info("Key #key pressed, tryAgain is $tryAgain");
|
||||
+ repost();
|
||||
+};
|
||||
+
|
||||
+transition "incorrect_retry" TESTPINRESULT - test($pin!=$roompin); test($tryAgain<3) / {
|
||||
+ info(">> incorrect_retry, pin '$pin', tryAgain '$tryAgain'");
|
||||
+ inc($tryAgain);
|
||||
+ set($pin="");
|
||||
+ set($audio_id="conference_pin_wrong");
|
||||
+ swPlayFile();
|
||||
+ info("incorrect_retry <<");
|
||||
+} -> COLLECT_PIN;
|
||||
+
|
||||
+transition "incorrect_no_retry" TESTPINRESULT - test($pin!=$roompin); test($tryAgain==3) / {
|
||||
+ info(">> incorrect_no_retry, tryAgain '$tryAgain'");
|
||||
+ set($audio_id="goodbye");
|
||||
+ swPlayFile();
|
||||
+ info("incorrect_no_retry <<");
|
||||
+} -> PLAY_FIN;
|
||||
+
|
||||
+--------------------------------------------------------
|
||||
+state PLAY_FIN;
|
||||
+transition "bye_after_fin" PLAY_FIN - noAudio / stopCall() -> END;
|
||||
+
|
||||
+--------------------------------------------------------
|
||||
+
|
||||
+transition "correct_pin" TESTPINRESULT - test($pin==$roompin) / {
|
||||
+ info(">> correct_pin");
|
||||
+ enterConference();
|
||||
+} -> CONFERENCE;
|
||||
+
|
||||
+state CONFERENCE;
|
||||
+
|
||||
+transition "got leave event" CONFERENCE - event(#leave==true) / {
|
||||
+ logParams();
|
||||
+ set($audio_id="conference_leave");
|
||||
+ swMixInFile();
|
||||
+} -> CONFERENCE;
|
||||
+
|
||||
+transition "got join event" CONFERENCE - event(#joined==true) / {
|
||||
+ logParams();
|
||||
+ if test($lonely_user==true) {
|
||||
+ conference.flushMixInList();
|
||||
+ }
|
||||
+ set($audio_id="conference_join");
|
||||
+ swMixInFile();
|
||||
+} -> CONFERENCE;
|
||||
+
|
||||
+transition "kick_event" CONFERENCE - eventTest(#action==kick) / {
|
||||
+ info(">> kick_event");
|
||||
+ closePlaylist();
|
||||
+ conference.leave();
|
||||
+ set($leave=true);
|
||||
+ groups.leaveAll();
|
||||
+ groups.postEvent($room, leave);
|
||||
+ stop(true);
|
||||
+ info("kick_event <<");
|
||||
+} -> END;
|
||||
+
|
||||
+# is this the same as kick?
|
||||
+transition "leave_event" CONFERENCE - eventTest(#action==leave) / {
|
||||
+ info(">> leave_event");
|
||||
+ closePlaylist();
|
||||
+ conference.leave();
|
||||
+ set($leave=true);
|
||||
+ groups.leaveAll();
|
||||
+ groups.postEvent($room, leave);
|
||||
+ stop(true);
|
||||
+ info("leave_event <<");
|
||||
+} -> END;
|
||||
+
|
||||
+transition "leave_conference" CONFERENCE - hangup / {
|
||||
+ info(">> leave_conference");
|
||||
+ closePlaylist();
|
||||
+ conference.leave();
|
||||
+ set($leave=true);
|
||||
+ groups.leaveAll();
|
||||
+ groups.postEvent($room, leave);
|
||||
+ stop(false);
|
||||
+ info("leave_conference <<");
|
||||
+} -> END;
|
||||
+
|
||||
+transition "bye_recvd" (START,COLLECT_PIN,PLAY_FIN,TESTPINRESULT) - hangup / stop(false) -> END;
|
||||
+
|
||||
+state END;
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/lib/sw_audio.dsm
|
||||
@@ -0,0 +1,50 @@
|
||||
+-- sw_audio
|
||||
+--
|
||||
+-- The playFile() function plays a file with ID $audio_id from the $config.audio_cache directory.
|
||||
+-- $sound_set_id is used as subdirectory under $config.audio_cache.
|
||||
+-- If it doesn't exist, it is tried to be fetched from the MySQL DB, using the $audio_id.
|
||||
+-- If that fails, an exception with type playFile is thrown
|
||||
+--
|
||||
+-- swMixInFile() mixes the file in to a mixInList setup by the conference module. it uses
|
||||
+-- the $has_mixin variable to record that state, and setup the mixin if it's not there.
|
||||
+--
|
||||
+-- set($sw_audio_loop="true") makes the file to be looped
|
||||
+
|
||||
+import(mod_sys);
|
||||
+import(mod_mysql);
|
||||
+import(mod_conference);
|
||||
+
|
||||
+function swPlayFile() {
|
||||
+ sets($__file_cache_path="$(config.audio_cache)/$(sound_set_id)/");
|
||||
+ sets($__file_path="$(__file_cache_path)$(audio_id).wav");
|
||||
+
|
||||
+ if sys.file_not_exists($__file_path) {
|
||||
+ if sys.file_not_exists($__file_cache_path) {
|
||||
+ sys.mkdir($__file_cache_path);
|
||||
+ }
|
||||
+ -- connect to DB
|
||||
+ if not mysql.connected() {
|
||||
+ mysql.connect();
|
||||
+ throwOnError();
|
||||
+ }
|
||||
+
|
||||
+ mysql.getFileFromDB('SELECT data FROM provisioning.voip_sound_files vsf, provisioning.voip_sound_handles vsh WHERE vsh.name="$audio_id" AND vsf.set_id=$sound_set_id AND vsh.id=vsf.handle_id',$__file_path);
|
||||
+ throwOnError();
|
||||
+ }
|
||||
+ if test($mix_file==true) {
|
||||
+ conference.playMixInList($__file_path, $sw_audio_loop);
|
||||
+ } else {
|
||||
+ playFile($__file_path, $sw_audio_loop);
|
||||
+ }
|
||||
+ clear($__file_path);
|
||||
+ clear($__file_cache_path);
|
||||
+};
|
||||
+
|
||||
+function swMixInFile() {
|
||||
+ set($mix_file=true);
|
||||
+ if test($has_mixin!=true) {
|
||||
+ conference.setupMixIn(0.5, 0);
|
||||
+ set($has_mixin=true);
|
||||
+ }
|
||||
+ swPlayFile();
|
||||
+};
|
||||
\ No newline at end of file
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/lib/sw_audio_api.dsm
|
||||
@@ -0,0 +1,66 @@
|
||||
+-- sw_audio_api
|
||||
+--
|
||||
+-- this SystemDSM implements API functions to handle the prompt cache
|
||||
+--
|
||||
+
|
||||
+import(mod_sys);
|
||||
+import(mod_mysql);
|
||||
+
|
||||
+initial state SW_AUDIO_START;
|
||||
+
|
||||
+transition "server startup" SW_AUDIO_START - startup / {
|
||||
+ log(2, "sw_audio cache handler started");
|
||||
+ registerEventQueue("sw_audio");
|
||||
+ mysql.connect();
|
||||
+ logAll(3);
|
||||
+} -> SW_AUDIO_WAIT_EVENT;
|
||||
+
|
||||
+state SW_AUDIO_WAIT_EVENT;
|
||||
+
|
||||
+transition "exception in server startup" (SW_AUDIO_START,SW_AUDIO_WAIT_EVENT) - exception / {
|
||||
+ logAll(1);
|
||||
+} -> SW_AUDIO_WAIT_EVENT;
|
||||
+
|
||||
+transition "server shutdown" SW_AUDIO_WAIT_EVENT - system(#type=="ServerShutdown") / {
|
||||
+ log(2, "sw_audio cache handler stopping");
|
||||
+ unregisterEventQueue("sw_audio");
|
||||
+ stop(false);
|
||||
+} -> SW_AUDIO_END;
|
||||
+
|
||||
+transition "clear File" SW_AUDIO_WAIT_EVENT - event(#cmd=="clearFile") / {
|
||||
+ log(3, "sw_audio cache handler: clearFile");
|
||||
+ logParams(3);
|
||||
+ sets($__file_path="$(config.audio_cache)/#(sound_set_id)/#(audio_id).wav");
|
||||
+ sys.unlink($__file_path);
|
||||
+ clear($__file_path);
|
||||
+} -> SW_AUDIO_WAIT_EVENT;
|
||||
+
|
||||
+transition "fetch File" SW_AUDIO_WAIT_EVENT - event(#cmd=="fetchFile") / {
|
||||
+ log(3, "sw_audio cache handler: fetchFile");
|
||||
+ logParams(3);
|
||||
+ sets($__file_path="$(config.audio_cache)/#(sound_set_id)/#(audio_id).wav");
|
||||
+ mysql.getFileFromDB(SELECT data FROM provisioning.audio_files WHERE id="#audio_id",$__file_path);
|
||||
+ clear($__file_path);
|
||||
+} -> SW_AUDIO_WAIT_EVENT;
|
||||
+
|
||||
+transition "push File" SW_AUDIO_WAIT_EVENT - event(#cmd=="pushFile") / {
|
||||
+ log(3, "sw_audio cache handler: pushFile");
|
||||
+ log(3, "WARNING! for debug purposes only");
|
||||
+ logParams(3);
|
||||
+ sets($__file_path="$(config.audio_cache)/#(sound_set_id)/#(audio_id).wav");
|
||||
+ mysql.connect();
|
||||
+ mysql.query(SELECT id as vsh_id FROM provisioning.voip_sound_handles where name="#audio_id");
|
||||
+ logAll(3);
|
||||
+ if test($db.rows==0) {
|
||||
+ mysql.execute(INSERT INTO provisioning.voip_sound_handles (name) VALUES ("#audio_id"));
|
||||
+ set($vsh_id=$db.insert_id);
|
||||
+ } else {
|
||||
+ mysql.getResult(0);
|
||||
+ };
|
||||
+ log(3, $vsh_id);
|
||||
+ mysql.putFileToDB('INSERT INTO provisioning.voip_sound_files (handle_id,set_id,data) VALUES ($vsh_id,#sound_set_id, "__FILE__")', $__file_path);
|
||||
+ logAll(3);
|
||||
+ clear($__file_path);
|
||||
+} -> SW_AUDIO_WAIT_EVENT;
|
||||
+
|
||||
+state SW_AUDIO_END;
|
||||
\ No newline at end of file
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/prompts/Makefile
|
||||
@@ -0,0 +1,22 @@
|
||||
+SRCS=$(wildcard *.txt)
|
||||
+WAVS=$(SRCS:.txt=.wav)
|
||||
+DBS=$(SRCS:.txt=.dbs)
|
||||
+
|
||||
+all: $(WAVS)
|
||||
+
|
||||
+db_upload: $(DBS)
|
||||
+
|
||||
+%.wav : %.txt Makefile
|
||||
+ flite -f $< -o $(basename $@)_16k.wav
|
||||
+## text2wave $< -o $(basename $@)_16k.wav
|
||||
+ sox $(basename $@)_16k.wav -r 8000 $@
|
||||
+ rm $(basename $@)_16k.wav
|
||||
+
|
||||
+%.dbs: %.wav Makefile
|
||||
+ mkdir -p ../cache/1
|
||||
+ cp $(basename $@).wav ../cache/1
|
||||
+ ../tools/push_file $(basename $@) 1
|
||||
+ touch $(basename $@).dbs
|
||||
+
|
||||
+clean:
|
||||
+ rm -f *.dbs *.wav
|
||||
\ No newline at end of file
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/prompts/conference_first.txt
|
||||
@@ -0,0 +1 @@
|
||||
+you are the first participant in the conference.
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/prompts/conference_greeting.txt
|
||||
@@ -0,0 +1 @@
|
||||
+welcome to the conference, please enter your pin number
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/prompts/conference_join.txt
|
||||
@@ -0,0 +1 @@
|
||||
+someone joined the conference
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/prompts/conference_joined.txt
|
||||
@@ -0,0 +1 @@
|
||||
+you joined the conference
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/prompts/conference_leave.txt
|
||||
@@ -0,0 +1 @@
|
||||
+someone left the conference
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/prompts/conference_music.txt
|
||||
@@ -0,0 +1 @@
|
||||
+bum bada bum bum bamm, bamm bada bamm bamm bamm, hum di dum di dum dum dumm
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/prompts/conference_pin_wrong.txt
|
||||
@@ -0,0 +1 @@
|
||||
+sorry, that pin is wrong. please try again
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/prompts/goodbye.txt
|
||||
@@ -0,0 +1 @@
|
||||
+good bye
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/tools/clear_file
|
||||
@@ -0,0 +1,14 @@
|
||||
+#!/usr/bin/python
|
||||
+# -*- coding: utf-8 -*-
|
||||
+import sys
|
||||
+from xmlrpclib import *
|
||||
+
|
||||
+if len(sys.argv) != 3:
|
||||
+ print "usage: %s <prompt id> <sound set id>" % sys.argv[0]
|
||||
+ sys.exit(1)
|
||||
+
|
||||
+s = ServerProxy('http://localhost:8090')
|
||||
+print "Active calls: %d" % s.calls()
|
||||
+#p ={ 'name' : sys.argv[1], 'path' : sys.argv[2] }
|
||||
+#print s.di('sbc','loadProfile',p)
|
||||
+print s.di('dsm', 'postDSMEvent', 'sw_audio', [['cmd', 'clearFile'],['audio_id', sys.argv[1]],['sound_set_id', sys.argv[2]]])
|
||||
\ No newline at end of file
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/tools/fetch_file
|
||||
@@ -0,0 +1,14 @@
|
||||
+#!/usr/bin/python
|
||||
+# -*- coding: utf-8 -*-
|
||||
+import sys
|
||||
+from xmlrpclib import *
|
||||
+
|
||||
+if len(sys.argv) != 3:
|
||||
+ print "usage: %s <prompt id> <sound set id>" % sys.argv[0]
|
||||
+ sys.exit(1)
|
||||
+
|
||||
+s = ServerProxy('http://localhost:8090')
|
||||
+print "Active calls: %d" % s.calls()
|
||||
+#p ={ 'name' : sys.argv[1], 'path' : sys.argv[2] }
|
||||
+#print s.di('sbc','loadProfile',p)
|
||||
+print s.di('dsm', 'postDSMEvent', 'sw_audio', [['cmd', 'fetchFile'],['audio_id', sys.argv[1]],['sound_set_id', sys.argv[2]]])
|
||||
\ No newline at end of file
|
||||
--- /dev/null
|
||||
+++ b/apps/confpin/tools/push_file
|
||||
@@ -0,0 +1,14 @@
|
||||
+#!/usr/bin/python
|
||||
+# -*- coding: utf-8 -*-
|
||||
+import sys
|
||||
+from xmlrpclib import *
|
||||
+
|
||||
+if len(sys.argv) != 3:
|
||||
+ print "usage: %s <prompt id> <set id>" % sys.argv[0]
|
||||
+ sys.exit(1)
|
||||
+
|
||||
+s = ServerProxy('http://localhost:8090')
|
||||
+print "Active calls: %d" % s.calls()
|
||||
+#p ={ 'name' : sys.argv[1], 'path' : sys.argv[2] }
|
||||
+#print s.di('sbc','loadProfile',p)
|
||||
+print s.di('dsm','postDSMEvent', 'sw_audio', [['cmd', 'pushFile'],['audio_id', sys.argv[1]],['sound_set_id', sys.argv[2]]])
|
||||
@ -1,195 +0,0 @@
|
||||
From 89c3172468d4bc02fb7484e20c4feae58ccd23e2 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Pogrebennyk <apogrebennyk@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:05 +0100
|
||||
Subject: MT#55831 don't create CF map if CF is denied by profile
|
||||
|
||||
don't create CF map if CF is denied by profile
|
||||
|
||||
(real ticket number: MT#13599)
|
||||
|
||||
--- a/apps/sw_vsc/SW_Vsc.cpp
|
||||
+++ b/apps/sw_vsc/SW_Vsc.cpp
|
||||
@@ -1214,36 +1214,36 @@ void SW_VscDialog::onInvite(const AmSipR
|
||||
if ((ret = regexec(&m_patterns->cfuOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- if (!number2uri(req, my_handler, uuid, subId, domain, domId, 4,
|
||||
- uri, username))
|
||||
+ u_int64_t attId = getAttributeId(my_handler, "cfu");
|
||||
+ if (!attId)
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- u_int64_t mapId = createCFMap(my_handler, subId, uri,
|
||||
- SW_VSC_DESTSET_CFU, "cfu");
|
||||
- if (!mapId)
|
||||
+ if(!checkSubscriberProfile(my_handler, profId, attId))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
- snprintf(map_str, sizeof(mapStr), "%llu",
|
||||
- (unsigned long long int)mapId);
|
||||
- mapStr = string(map_str);
|
||||
|
||||
- u_int64_t attId = getAttributeId(my_handler, "cfu");
|
||||
- if (!attId)
|
||||
+ if (!number2uri(req, my_handler, uuid, subId, domain, domId, 4,
|
||||
+ uri, username))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if(!checkSubscriberProfile(my_handler, profId, attId))
|
||||
+ u_int64_t mapId = createCFMap(my_handler, subId, uri,
|
||||
+ SW_VSC_DESTSET_CFU, "cfu");
|
||||
+ if (!mapId)
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
+ snprintf(map_str, sizeof(mapStr), "%llu",
|
||||
+ (unsigned long long int)mapId);
|
||||
+ mapStr = string(map_str);
|
||||
|
||||
u_int64_t prefId = getPreference(my_handler, subId, attId,
|
||||
&foundPref, &prefStr);
|
||||
@@ -1331,36 +1331,36 @@ void SW_VscDialog::onInvite(const AmSipR
|
||||
if ((ret = regexec(&m_patterns->cfbOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- if (!number2uri(req, my_handler, uuid, subId, domain, domId, 4,
|
||||
- uri, username))
|
||||
+ u_int64_t attId = getAttributeId(my_handler, "cfb");
|
||||
+ if (!attId)
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- u_int64_t mapId = createCFMap(my_handler, subId, uri,
|
||||
- SW_VSC_DESTSET_CFB, "cfb");
|
||||
- if (!mapId)
|
||||
+ if(!checkSubscriberProfile(my_handler, profId, attId))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
- snprintf(map_str, sizeof(mapStr), "%llu",
|
||||
- (unsigned long long int)mapId);
|
||||
- mapStr = string(map_str);
|
||||
|
||||
- u_int64_t attId = getAttributeId(my_handler, "cfb");
|
||||
- if (!attId)
|
||||
+ if (!number2uri(req, my_handler, uuid, subId, domain, domId, 4,
|
||||
+ uri, username))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if(!checkSubscriberProfile(my_handler, profId, attId))
|
||||
+ u_int64_t mapId = createCFMap(my_handler, subId, uri,
|
||||
+ SW_VSC_DESTSET_CFB, "cfb");
|
||||
+ if (!mapId)
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
+ snprintf(map_str, sizeof(mapStr), "%llu",
|
||||
+ (unsigned long long int)mapId);
|
||||
+ mapStr = string(map_str);
|
||||
|
||||
u_int64_t prefId = getPreference(my_handler, subId, attId,
|
||||
&foundPref, &prefStr);
|
||||
@@ -1448,6 +1448,19 @@ void SW_VscDialog::onInvite(const AmSipR
|
||||
if ((ret = regexec(&m_patterns->cftOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ u_int64_t attId = getAttributeId(my_handler, "cft");
|
||||
+ if (!attId)
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if(!checkSubscriberProfile(my_handler, profId, attId))
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
string::size_type timend = req.user.find('*', 4);
|
||||
string tim = req.user.substr(4, timend - 4);
|
||||
INFO("Extracted ringtimeout of '%s' from '%s' for uuid '%s'",
|
||||
@@ -1471,19 +1484,6 @@ void SW_VscDialog::onInvite(const AmSipR
|
||||
(unsigned long long int)mapId);
|
||||
mapStr = string(map_str);
|
||||
|
||||
- u_int64_t attId = getAttributeId(my_handler, "cft");
|
||||
- if (!attId)
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- if(!checkSubscriberProfile(my_handler, profId, attId))
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
u_int64_t prefId = getPreference(my_handler, subId, attId,
|
||||
&foundPref, &prefStr);
|
||||
if (!prefId)
|
||||
@@ -1628,36 +1628,36 @@ void SW_VscDialog::onInvite(const AmSipR
|
||||
if ((ret = regexec(&m_patterns->cfnaOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- if (!number2uri(req, my_handler, uuid, subId, domain, domId, 4,
|
||||
- uri, username))
|
||||
+ u_int64_t attId = getAttributeId(my_handler, "cfna");
|
||||
+ if (!attId)
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- u_int64_t mapId = createCFMap(my_handler, subId, uri,
|
||||
- SW_VSC_DESTSET_CFNA, "cfna");
|
||||
- if (!mapId)
|
||||
+ if(!checkSubscriberProfile(my_handler, profId, attId))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
- snprintf(map_str, sizeof(mapStr), "%llu",
|
||||
- (unsigned long long int)mapId);
|
||||
- mapStr = string(map_str);
|
||||
|
||||
- u_int64_t attId = getAttributeId(my_handler, "cfna");
|
||||
- if (!attId)
|
||||
+ if (!number2uri(req, my_handler, uuid, subId, domain, domId, 4,
|
||||
+ uri, username))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
|
||||
- if(!checkSubscriberProfile(my_handler, profId, attId))
|
||||
+ u_int64_t mapId = createCFMap(my_handler, subId, uri,
|
||||
+ SW_VSC_DESTSET_CFNA, "cfna");
|
||||
+ if (!mapId)
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
+ snprintf(map_str, sizeof(mapStr), "%llu",
|
||||
+ (unsigned long long int)mapId);
|
||||
+ mapStr = string(map_str);
|
||||
|
||||
u_int64_t prefId = getPreference(my_handler, subId, attId,
|
||||
&foundPref, &prefStr);
|
||||
@ -1,165 +0,0 @@
|
||||
From 1f02da5c8cc9dc711ded015059ae85a5126dd269 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Sayer <stefan.sayer@googlemail.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:11 +0100
|
||||
Subject: MT#55831 db_reg_agent: add username_with_domain option to use auth user with domain part
|
||||
|
||||
add username_with_domain option to use auth user with domain part
|
||||
(real ticket number: MT#9306)
|
||||
|
||||
implements M758
|
||||
---
|
||||
apps/db_reg_agent/DBRegAgent.cpp | 39 +++++++++++++++++++++++----------
|
||||
apps/db_reg_agent/DBRegAgent.h | 2 ++
|
||||
apps/db_reg_agent/etc/db_reg_agent.conf | 5 +++++
|
||||
doc/Readme.db_reg_agent.txt | 7 ++++++
|
||||
4 files changed, 42 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/apps/db_reg_agent/DBRegAgent.cpp b/apps/db_reg_agent/DBRegAgent.cpp
|
||||
index f004807..c9c3702 100644
|
||||
--- a/apps/db_reg_agent/DBRegAgent.cpp
|
||||
+++ b/apps/db_reg_agent/DBRegAgent.cpp
|
||||
@@ -52,7 +52,9 @@ bool DBRegAgent::delete_failed_deregistrations = false;
|
||||
bool DBRegAgent::save_contacts = true;
|
||||
bool DBRegAgent::db_read_contact = false;
|
||||
string DBRegAgent::contact_hostport;
|
||||
+bool DBRegAgent::username_with_domain = false;
|
||||
string DBRegAgent::outbound_proxy;
|
||||
+
|
||||
bool DBRegAgent::save_auth_replies = false;
|
||||
|
||||
unsigned int DBRegAgent::error_retry_interval = 300;
|
||||
@@ -146,6 +148,9 @@ int DBRegAgent::onLoad()
|
||||
db_read_contact =
|
||||
cfg.getParameter("db_read_contact", "no") == "yes";
|
||||
|
||||
+ username_with_domain =
|
||||
+ cfg.getParameter("username_with_domain", "no") == "yes";
|
||||
+
|
||||
save_auth_replies =
|
||||
cfg.getParameter("save_auth_replies", "no") == "yes";
|
||||
|
||||
@@ -391,15 +396,21 @@ void DBRegAgent::createRegistration(long subscriber_id,
|
||||
const string& realm,
|
||||
const string& contact) {
|
||||
|
||||
+ string auth_user = user;
|
||||
+ string _user = user;
|
||||
+ if (username_with_domain && user.find('@')!=string::npos) {
|
||||
+ _user = user.substr(0, user.find('@'));
|
||||
+ }
|
||||
+
|
||||
string contact_uri = contact;
|
||||
if (contact_uri.empty() && !contact_hostport.empty()) {
|
||||
- contact_uri = "sip:"+ user + "@" + contact_hostport;
|
||||
+ contact_uri = "sip:"+ _user + "@" + contact_hostport;
|
||||
}
|
||||
|
||||
string handle = AmSession::getNewId();
|
||||
- SIPRegistrationInfo reg_info(realm, user,
|
||||
- user, // name
|
||||
- user, // auth_user
|
||||
+ SIPRegistrationInfo reg_info(realm, _user,
|
||||
+ _user, // name
|
||||
+ auth_user,
|
||||
pass,
|
||||
outbound_proxy, // proxy
|
||||
contact_uri // contact
|
||||
@@ -466,27 +477,33 @@ void DBRegAgent::updateRegistration(long subscriber_id,
|
||||
const string& realm,
|
||||
const string& contact) {
|
||||
|
||||
+ string auth_user = user;
|
||||
+ string _user = user;
|
||||
+ if (username_with_domain && user.find('@')!=string::npos) {
|
||||
+ _user = user.substr(0, user.find('@'));
|
||||
+ }
|
||||
+
|
||||
registrations_mut.lock();
|
||||
map<long, AmSIPRegistration*>::iterator it=registrations.find(subscriber_id);
|
||||
if (it == registrations.end()) {
|
||||
registrations_mut.unlock();
|
||||
WARN("updateRegistration - registration %ld %s@%s unknown, creating\n",
|
||||
- subscriber_id, user.c_str(), realm.c_str());
|
||||
- createRegistration(subscriber_id, user, pass, realm, contact);
|
||||
+ subscriber_id, _user.c_str(), realm.c_str());
|
||||
+ createRegistration(subscriber_id, _user, pass, realm, contact);
|
||||
scheduleRegistration(subscriber_id);
|
||||
return;
|
||||
}
|
||||
|
||||
bool need_reregister = it->second->getInfo().domain != realm
|
||||
- || it->second->getInfo().user != user
|
||||
+ || it->second->getInfo().user != _user
|
||||
|| it->second->getInfo().pwd != pass
|
||||
|| it->second->getInfo().contact != contact;
|
||||
|
||||
string old_realm = it->second->getInfo().domain;
|
||||
string old_user = it->second->getInfo().user;
|
||||
- it->second->setRegistrationInfo(SIPRegistrationInfo(realm, user,
|
||||
- user, // name
|
||||
- user, // auth_user
|
||||
+ it->second->setRegistrationInfo(SIPRegistrationInfo(realm, _user,
|
||||
+ _user, // name
|
||||
+ auth_user,
|
||||
pass,
|
||||
outbound_proxy, // proxy
|
||||
contact)); // contact
|
||||
@@ -494,7 +511,7 @@ void DBRegAgent::updateRegistration(long subscriber_id,
|
||||
if (need_reregister) {
|
||||
DBG("user/realm for registration %ld changed (%s@%s -> %s@%s). "
|
||||
"Triggering immediate re-registration\n",
|
||||
- subscriber_id, old_user.c_str(), old_realm.c_str(), user.c_str(), realm.c_str());
|
||||
+ subscriber_id, old_user.c_str(), old_realm.c_str(), _user.c_str(), realm.c_str());
|
||||
scheduleRegistration(subscriber_id);
|
||||
}
|
||||
}
|
||||
diff --git a/apps/db_reg_agent/DBRegAgent.h b/apps/db_reg_agent/DBRegAgent.h
|
||||
index 868d999..660b558 100644
|
||||
--- a/apps/db_reg_agent/DBRegAgent.h
|
||||
+++ b/apps/db_reg_agent/DBRegAgent.h
|
||||
@@ -138,6 +138,8 @@ class DBRegAgent
|
||||
|
||||
static string contact_hostport;
|
||||
|
||||
+ static bool username_with_domain;
|
||||
+
|
||||
static string outbound_proxy;
|
||||
|
||||
static bool save_auth_replies;
|
||||
diff --git a/apps/db_reg_agent/etc/db_reg_agent.conf b/apps/db_reg_agent/etc/db_reg_agent.conf
|
||||
index 54875cb..fd341b5 100644
|
||||
--- a/apps/db_reg_agent/etc/db_reg_agent.conf
|
||||
+++ b/apps/db_reg_agent/etc/db_reg_agent.conf
|
||||
@@ -20,6 +20,11 @@ joined_query="select subscribers.subscriber_id as subscriber_id, subscribers.use
|
||||
#example with contact:
|
||||
# joined_query="select subscribers.subscriber_id as subscriber_id, subscribers.user as user, subscribers.pass as pass, subscribers.realm as realm, subscribers.contact as contact, registrations.registration_status as registration_status, registrations.expiry as expiry, registrations.last_registration as last_registration from subscribers left join registrations on subscribers.subscriber_id=registrations.subscriber_id;"
|
||||
|
||||
+# Does the user column (used as auth user) contain the domain?
|
||||
+# in this case it will be stripped when constructing From/To/contact
|
||||
+#username_with_domain default: no
|
||||
+#username_with_domain=yes
|
||||
+
|
||||
# outbound_proxy=<sip_uri>
|
||||
# set the outbound proxy to send registrations through
|
||||
#
|
||||
diff --git a/doc/Readme.db_reg_agent.txt b/doc/Readme.db_reg_agent.txt
|
||||
index 4ccb794..be1bf17 100644
|
||||
--- a/doc/Readme.db_reg_agent.txt
|
||||
+++ b/doc/Readme.db_reg_agent.txt
|
||||
@@ -65,6 +65,13 @@ specified by setting option db_read_contact=yes and providing a contact in the
|
||||
subscriber.contact column, and passing it with createRegistration/updateRegistration DI
|
||||
function.
|
||||
|
||||
+Auth username
|
||||
+-------------
|
||||
+If the username for authentication needs to include the domain, the option
|
||||
+username_with_domain should be set to 'yes' and the auth user including the domain
|
||||
+should be provisioned in the database. SEMS will strip the domain from the value of
|
||||
+the 'user' column before using it as the user part when constructing To/From/contact.
|
||||
+
|
||||
Database
|
||||
--------
|
||||
There may be two separate tables, subscriptions and registrations (status). SEMS inserts
|
||||
--
|
||||
2.10.1 (Apple Git-78)
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
From 1f02da5c8cc9dc711ded015059ae85a5126dd269 Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Pogrebennyk <apogrebennyk@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:12 +0100
|
||||
Subject: MT#55831 increase the config line length to 4096 because of header_list
|
||||
|
||||
increase the config line length to 4096 because of header_list
|
||||
(real ticket number: MT#1640)
|
||||
|
||||
--- a/core/AmConfigReader.h
|
||||
+++ b/core/AmConfigReader.h
|
||||
@@ -33,7 +33,7 @@
|
||||
using std::string;
|
||||
|
||||
|
||||
-#define MAX_CONFIG_LINE 2048
|
||||
+#define MAX_CONFIG_LINE 4096
|
||||
#define CONFIG_FILE_SUFFIX ".conf"
|
||||
|
||||
/**
|
||||
@ -1,22 +0,0 @@
|
||||
From 564d4c09263c021aa7e651edbfbd22e8b895a3bf Mon Sep 17 00:00:00 2001
|
||||
From: Jozef Kenyeres <jkenyeres@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:18 +0100
|
||||
Subject: MT#55831 fix failed relay of 200OK without SDP
|
||||
|
||||
fix failed relay of 200OK without SDP
|
||||
(real ticket number: TT#9521)
|
||||
|
||||
Index: sems/core/AmOfferAnswer.cpp
|
||||
===================================================================
|
||||
--- sems.orig/core/AmOfferAnswer.cpp
|
||||
+++ sems/core/AmOfferAnswer.cpp
|
||||
@@ -392,6 +392,9 @@ int AmOfferAnswer::onReplyOut(AmSipReply
|
||||
if (reply.code == 183 && reply.cseq_method == SIP_METH_INVITE) {
|
||||
// just ignore if no SDP is generated (required for B2B)
|
||||
}
|
||||
+ else if (reply.code == 200 && reply.cseq_method == SIP_METH_INVITE && state == OA_Completed) {
|
||||
+ // just ignore if no SDP is generated (required for B2B)
|
||||
+ }
|
||||
else return -1;
|
||||
}
|
||||
else {
|
||||
@ -1,244 +0,0 @@
|
||||
From cd20d43797777716900311f95a43dc864bb546c3 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Granig <agranig@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:08 +0100
|
||||
Subject: MT#55831 Implement vsc for block_in_clir
|
||||
|
||||
Implement vsc for block_in_clir
|
||||
(real ticket number: MT#20649)
|
||||
|
||||
Index: sems/apps/sw_vsc/SW_Vsc.cpp
|
||||
===================================================================
|
||||
--- sems.orig/apps/sw_vsc/SW_Vsc.cpp 2016-07-20 13:39:47.454933967 +0200
|
||||
+++ sems/apps/sw_vsc/SW_Vsc.cpp 2016-07-20 14:32:19.535931094 +0200
|
||||
@@ -93,6 +93,8 @@
|
||||
regfree(&m_patterns.speedDialPattern);
|
||||
regfree(&m_patterns.reminderOnPattern);
|
||||
regfree(&m_patterns.reminderOffPattern);
|
||||
+ regfree(&m_patterns.blockinclirOnPattern);
|
||||
+ regfree(&m_patterns.blockinclirOffPattern);
|
||||
}
|
||||
|
||||
int SW_VscFactory::onLoad()
|
||||
@@ -108,6 +110,8 @@
|
||||
string speedDialPattern;
|
||||
string reminderOnPattern;
|
||||
string reminderOffPattern;
|
||||
+ string blockinclirOnPattern;
|
||||
+ string blockinclirOffPattern;
|
||||
|
||||
AmConfigReader cfg;
|
||||
if (cfg.loadFile(AmConfig::ModConfigPath + string(MOD_NAME ".conf")))
|
||||
@@ -228,6 +232,18 @@
|
||||
ERROR("ReminderOffAnnouncement file not set\n");
|
||||
return -1;
|
||||
}
|
||||
+ m_patterns.blockinclirOnAnnouncement = cfg.getParameter("blockinclir_on_announcement", "");
|
||||
+ if (m_patterns.blockinclirOnAnnouncement.empty())
|
||||
+ {
|
||||
+ ERROR("BlockinclirOnAnnouncement file not set\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ m_patterns.blockinclirOffAnnouncement = cfg.getParameter("blockinclir_off_announcement", "");
|
||||
+ if (m_patterns.blockinclirOffAnnouncement.empty())
|
||||
+ {
|
||||
+ ERROR("BlockinclirOffAnnouncement file not set\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
|
||||
|
||||
m_patterns.voicemailNumber = cfg.getParameter("voicemail_number", "");
|
||||
@@ -395,6 +411,36 @@
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ blockinclirOnPattern = cfg.getParameter("blockinclir_on_pattern", "");
|
||||
+ if (blockinclirOnPattern.empty())
|
||||
+ {
|
||||
+ ERROR("BlockinclirOnPattern is empty\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (regcomp(&m_patterns.blockinclirOnPattern, blockinclirOnPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
+ {
|
||||
+ ERROR("BlockinclirOnPattern failed to compile ('%s'): %s\n",
|
||||
+ blockinclirOnPattern.c_str(),
|
||||
+ strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ blockinclirOffPattern = cfg.getParameter("blockinclir_off_pattern", "");
|
||||
+ if (blockinclirOffPattern.empty())
|
||||
+ {
|
||||
+ ERROR("BlockinclirOffPattern is empty\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (regcomp(&m_patterns.blockinclirOffPattern, blockinclirOffPattern.c_str(),
|
||||
+ REG_EXTENDED | REG_NOSUB))
|
||||
+ {
|
||||
+ ERROR("BlockinclirOffPattern failed to compile ('%s'): %s\n",
|
||||
+ blockinclirOffPattern.c_str(),
|
||||
+ strerror(errno));
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1059,6 +1105,8 @@
|
||||
string speedDialAnnouncement;
|
||||
string reminderOnAnnouncement;
|
||||
string reminderOffAnnouncement;
|
||||
+ string blockinclirOnAnnouncement;
|
||||
+ string blockinclirOffAnnouncement;
|
||||
|
||||
string uuid = getHeader(req.hdrs, "P-Caller-UUID");
|
||||
if (!uuid.length())
|
||||
@@ -1177,6 +1225,22 @@
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
+ blockinclirOnAnnouncement = m_patterns->audioPath + lang + m_patterns->blockinclirOnAnnouncement;
|
||||
+ if (!file_exists(blockinclirOnAnnouncement))
|
||||
+ {
|
||||
+ ERROR("BlockinclirOnAnnouncement file does not exist ('%s').\n",
|
||||
+ blockinclirOnAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ blockinclirOffAnnouncement = m_patterns->audioPath + lang + m_patterns->blockinclirOffAnnouncement;
|
||||
+ if (!file_exists(blockinclirOffAnnouncement))
|
||||
+ {
|
||||
+ ERROR("BlockinclirOffAnnouncement file does not exist ('%s').\n",
|
||||
+ blockinclirOffAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
|
||||
my_handler = mysql_init(NULL);
|
||||
if (!mysql_real_connect(my_handler,
|
||||
@@ -1842,6 +1906,95 @@
|
||||
}
|
||||
|
||||
|
||||
+ // block in clir
|
||||
+ if ((ret = regexec(&m_patterns->blockinclirOnPattern,
|
||||
+ req.user.c_str(), 0, 0, 0)) == 0)
|
||||
+ {
|
||||
+ std::string val = "1";
|
||||
+ u_int64_t attId = getAttributeId(my_handler, "block_in_clir");
|
||||
+ if (!attId)
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ u_int64_t prefId = getPreference(my_handler, subId, attId,
|
||||
+ &foundPref, &prefStr);
|
||||
+ if (!prefId)
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ else if (!foundPref)
|
||||
+ {
|
||||
+ if (!insertPreference(my_handler, subId, attId, val))
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ INFO("Successfully set VSC block_in_clir for uuid '%s'",
|
||||
+ uuid.c_str());
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (!updatePreferenceId(my_handler, prefId, val))
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ INFO("Successfully updated VSC block_in_clir for uuid '%s'",
|
||||
+ uuid.c_str());
|
||||
+ }
|
||||
+
|
||||
+ filename = blockinclirOnAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ else if (ret != REG_NOMATCH)
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if ((ret = regexec(&m_patterns->blockinclirOffPattern,
|
||||
+ req.user.c_str(), 0, 0, 0)) == 0)
|
||||
+ {
|
||||
+ u_int64_t attId = getAttributeId(my_handler, "block_in_clir");
|
||||
+ if (!attId)
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ u_int64_t prefId = getPreference(my_handler, subId, attId,
|
||||
+ &foundPref, &prefStr);
|
||||
+ if (!prefId)
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ else if (!foundPref)
|
||||
+ {
|
||||
+ INFO("Unnecessary VSC block_in_clir removal for uuid '%s'",
|
||||
+ uuid.c_str());
|
||||
+ }
|
||||
+ else if (!deletePreferenceId(my_handler, prefId))
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ INFO("Successfully removed block_in_clir for uuid '%s'",
|
||||
+ uuid.c_str());
|
||||
+ }
|
||||
+
|
||||
+ filename = blockinclirOffAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ else if (ret != REG_NOMATCH)
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
|
||||
INFO("Unkown VSC code '%s' found", req.user.c_str());
|
||||
filename = unknownAnnouncement;
|
||||
Index: sems/apps/sw_vsc/SW_Vsc.h
|
||||
===================================================================
|
||||
--- sems.orig/apps/sw_vsc/SW_Vsc.h 2016-07-20 13:39:47.402933680 +0200
|
||||
+++ sems/apps/sw_vsc/SW_Vsc.h 2016-07-20 13:47:17.856976961 +0200
|
||||
@@ -61,6 +61,12 @@
|
||||
|
||||
regex_t reminderOffPattern;
|
||||
string reminderOffAnnouncement;
|
||||
+
|
||||
+ regex_t blockinclirOnPattern;
|
||||
+ string blockinclirOnAnnouncement;
|
||||
+
|
||||
+ regex_t blockinclirOffPattern;
|
||||
+ string blockinclirOffAnnouncement;
|
||||
} sw_vsc_patterns_t;
|
||||
|
||||
class SW_VscFactory: public AmSessionFactory
|
||||
Index: sems/apps/sw_vsc/etc/sw_vsc.conf
|
||||
===================================================================
|
||||
--- sems.orig/apps/sw_vsc/etc/sw_vsc.conf 2016-07-20 13:39:47.406933702 +0200
|
||||
+++ sems/apps/sw_vsc/etc/sw_vsc.conf 2016-07-20 14:34:14.588367576 +0200
|
||||
@@ -38,3 +38,8 @@
|
||||
reminder_off_pattern = ^(\%23)55(\%23)?.*$
|
||||
reminder_off_announcement = sw_vsc_deactivated.wav
|
||||
|
||||
+blockinclir_on_pattern = ^\*32\*$
|
||||
+blockinclir_on_announcement = sw_vsc_activated.wav
|
||||
+blockinclir_off_pattern = ^(\%23)32(\%23)?.*$
|
||||
+blockinclir_off_announcement = sw_vsc_deactivated.wav
|
||||
+
|
||||
@ -1,696 +0,0 @@
|
||||
From f40a8b932a1dabd664995014d2fc2c9f2bcc9722 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Granig <agranig@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:09 +0100
|
||||
Subject: MT#55831 Rework config validation to be more slack
|
||||
|
||||
Don't bail out on missing config options, rather than using some
|
||||
invalid defaults.
|
||||
Also only check for existence of sound files in the places where
|
||||
they are needed for optimization purposes.
|
||||
Use macros to clean up redundant code.
|
||||
(real ticket number: MT#20649)
|
||||
|
||||
Index: sems/apps/sw_vsc/SW_Vsc.cpp
|
||||
===================================================================
|
||||
--- sems.orig/apps/sw_vsc/SW_Vsc.cpp 2016-07-21 12:55:32.091065992 +0200
|
||||
+++ sems/apps/sw_vsc/SW_Vsc.cpp 2016-07-21 13:22:56.987148286 +0200
|
||||
@@ -154,114 +154,102 @@
|
||||
if (m_patterns.audioPath[m_patterns.audioPath.length() - 1] != '/' )
|
||||
m_patterns.audioPath += "/";
|
||||
|
||||
+ // MT#20649: don't fail if announcements are missing;
|
||||
m_patterns.failAnnouncement = cfg.getParameter("error_announcement", "");
|
||||
if (m_patterns.failAnnouncement.empty())
|
||||
{
|
||||
- ERROR("ErrorAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("error_announcement file not set\n");
|
||||
}
|
||||
m_patterns.unknownAnnouncement = cfg.getParameter("unknown_announcement", "");
|
||||
if (m_patterns.unknownAnnouncement.empty())
|
||||
{
|
||||
- ERROR("UnknownAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("unknown_announcement file not set\n");
|
||||
}
|
||||
m_patterns.cfuOnAnnouncement = cfg.getParameter("cfu_on_announcement", "");
|
||||
if (m_patterns.cfuOnAnnouncement.empty())
|
||||
{
|
||||
- ERROR("CfuOnAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("cfu_on_announcement file not set\n");
|
||||
}
|
||||
m_patterns.cfuOffAnnouncement = cfg.getParameter("cfu_off_announcement", "");
|
||||
if (m_patterns.cfuOffAnnouncement.empty())
|
||||
{
|
||||
- ERROR("CfuOffAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("cfu_off_announcement file not set\n");
|
||||
}
|
||||
m_patterns.cfbOnAnnouncement = cfg.getParameter("cfb_on_announcement", "");
|
||||
if (m_patterns.cfbOnAnnouncement.empty())
|
||||
{
|
||||
- ERROR("CfbOnAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("cfb_on_announcement file not set\n");
|
||||
}
|
||||
m_patterns.cfbOffAnnouncement = cfg.getParameter("cfb_off_announcement", "");
|
||||
if (m_patterns.cfbOffAnnouncement.empty())
|
||||
{
|
||||
- ERROR("CfbOffAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("cfb_off_announcement file not set\n");
|
||||
}
|
||||
m_patterns.cftOnAnnouncement = cfg.getParameter("cft_on_announcement", "");
|
||||
if (m_patterns.cftOnAnnouncement.empty())
|
||||
{
|
||||
- ERROR("CftOnAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("cft_on_announcement file not set\n");
|
||||
}
|
||||
m_patterns.cftOffAnnouncement = cfg.getParameter("cft_off_announcement", "");
|
||||
if (m_patterns.cftOffAnnouncement.empty())
|
||||
{
|
||||
- ERROR("CftOffAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("cft_off_announcement file not set\n");
|
||||
}
|
||||
m_patterns.cfnaOnAnnouncement = cfg.getParameter("cfna_on_announcement", "");
|
||||
if (m_patterns.cfnaOnAnnouncement.empty())
|
||||
{
|
||||
- ERROR("CfnaOnAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("cfna_on_announcement file not set\n");
|
||||
}
|
||||
m_patterns.cfnaOffAnnouncement = cfg.getParameter("cfna_off_announcement", "");
|
||||
if (m_patterns.cfnaOffAnnouncement.empty())
|
||||
{
|
||||
- ERROR("CfnaOffAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("cfna_off_announcement file not set\n");
|
||||
}
|
||||
m_patterns.speedDialAnnouncement = cfg.getParameter("speed_dial_announcement", "");
|
||||
if (m_patterns.speedDialAnnouncement.empty())
|
||||
{
|
||||
- ERROR("SpeedDialAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("speed_dial_announcement file not set\n");
|
||||
}
|
||||
m_patterns.reminderOnAnnouncement = cfg.getParameter("reminder_on_announcement", "");
|
||||
if (m_patterns.reminderOnAnnouncement.empty())
|
||||
{
|
||||
- ERROR("ReminderOnAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("reminder_on_announcement file not set\n");
|
||||
}
|
||||
m_patterns.reminderOffAnnouncement = cfg.getParameter("reminder_off_announcement", "");
|
||||
if (m_patterns.reminderOffAnnouncement.empty())
|
||||
{
|
||||
- ERROR("ReminderOffAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("reminder_off_announcement file not set\n");
|
||||
}
|
||||
m_patterns.blockinclirOnAnnouncement = cfg.getParameter("blockinclir_on_announcement", "");
|
||||
if (m_patterns.blockinclirOnAnnouncement.empty())
|
||||
{
|
||||
- ERROR("BlockinclirOnAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("blockinclir_on_announcement file not set\n");
|
||||
}
|
||||
m_patterns.blockinclirOffAnnouncement = cfg.getParameter("blockinclir_off_announcement", "");
|
||||
if (m_patterns.blockinclirOffAnnouncement.empty())
|
||||
{
|
||||
- ERROR("BlockinclirOffAnnouncement file not set\n");
|
||||
- return -1;
|
||||
+ ERROR("blockinclir_off_announcement file not set\n");
|
||||
}
|
||||
|
||||
+ // We could set a default in cfg.getParameter, but we really want to log the error
|
||||
+ // if the pattern in question is not set:
|
||||
|
||||
m_patterns.voicemailNumber = cfg.getParameter("voicemail_number", "");
|
||||
if (m_patterns.voicemailNumber.empty())
|
||||
{
|
||||
- ERROR("voicemailNumber is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("voicemail_number not set\n");
|
||||
+ m_patterns.voicemailNumber = "invalid_default_value";
|
||||
}
|
||||
|
||||
cfuOnPattern = cfg.getParameter("cfu_on_pattern", "");
|
||||
if (cfuOnPattern.empty())
|
||||
{
|
||||
- ERROR("CfuOnPattern is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("cfu_on_pattern is empty\n");
|
||||
+ cfuOnPattern = "invalid_default_value";
|
||||
}
|
||||
if (regcomp(&m_patterns.cfuOnPattern, cfuOnPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
{
|
||||
- ERROR("CfuOnPattern failed to compile ('%s'): %s\n",
|
||||
+ ERROR("cfu_on_pattern failed to compile ('%s'): %s\n",
|
||||
cfuOnPattern.c_str(),
|
||||
strerror(errno));
|
||||
return -1;
|
||||
@@ -270,12 +258,12 @@
|
||||
cfuOffPattern = cfg.getParameter("cfu_off_pattern", "");
|
||||
if (cfuOffPattern.empty())
|
||||
{
|
||||
- ERROR("CfuOffPattern is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("cfu_off_pattern is empty\n");
|
||||
+ cfuOffPattern = "invalid_default_value";
|
||||
}
|
||||
if (regcomp(&m_patterns.cfuOffPattern, cfuOffPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
{
|
||||
- ERROR("CfuOffPattern failed to compile ('%s'): %s\n",
|
||||
+ ERROR("cfu_off_pattern failed to compile ('%s'): %s\n",
|
||||
cfuOffPattern.c_str(),
|
||||
strerror(errno));
|
||||
return -1;
|
||||
@@ -284,12 +272,12 @@
|
||||
cfbOnPattern = cfg.getParameter("cfb_on_pattern", "");
|
||||
if (cfbOnPattern.empty())
|
||||
{
|
||||
- ERROR("CfbOnPattern is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("cfb_on_pattern is empty\n");
|
||||
+ cfbOnPattern = "invalid_default_value";
|
||||
}
|
||||
if (regcomp(&m_patterns.cfbOnPattern, cfbOnPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
{
|
||||
- ERROR("CfbOnPattern failed to compile ('%s'): %s\n",
|
||||
+ ERROR("cfb_on_pattern failed to compile ('%s'): %s\n",
|
||||
cfbOnPattern.c_str(),
|
||||
strerror(errno));
|
||||
return -1;
|
||||
@@ -298,27 +286,26 @@
|
||||
cfbOffPattern = cfg.getParameter("cfb_off_pattern", "");
|
||||
if (cfbOffPattern.empty())
|
||||
{
|
||||
- ERROR("CfbOffPattern is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("cfb_off_pattern is empty\n");
|
||||
+ cfbOffPattern = "invalid_default_value";
|
||||
}
|
||||
if (regcomp(&m_patterns.cfbOffPattern, cfbOffPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
{
|
||||
- ERROR("CfbOffPattern failed to compile ('%s'): %s\n",
|
||||
+ ERROR("cfb_off_pattern failed to compile ('%s'): %s\n",
|
||||
cfbOffPattern.c_str(),
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
-
|
||||
cftOnPattern = cfg.getParameter("cft_on_pattern", "");
|
||||
if (cftOnPattern.empty())
|
||||
{
|
||||
- ERROR("CftOnPattern is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("cft_on_pattern is empty\n");
|
||||
+ cftOnPattern = "invalid_default_value";
|
||||
}
|
||||
if (regcomp(&m_patterns.cftOnPattern, cftOnPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
{
|
||||
- ERROR("CftOnPattern failed to compile ('%s'): %s\n",
|
||||
+ ERROR("cft_on_pattern failed to compile ('%s'): %s\n",
|
||||
cftOnPattern.c_str(),
|
||||
strerror(errno));
|
||||
return -1;
|
||||
@@ -327,12 +314,12 @@
|
||||
cftOffPattern = cfg.getParameter("cft_off_pattern", "");
|
||||
if (cftOffPattern.empty())
|
||||
{
|
||||
- ERROR("CftOffPattern is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("cft_off_pattern is empty\n");
|
||||
+ cftOffPattern = "invalid_default_value";
|
||||
}
|
||||
if (regcomp(&m_patterns.cftOffPattern, cftOffPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
{
|
||||
- ERROR("CftOffPattern failed to compile ('%s'): %s\n",
|
||||
+ ERROR("cft_off_pattern failed to compile ('%s'): %s\n",
|
||||
cftOffPattern.c_str(),
|
||||
strerror(errno));
|
||||
return -1;
|
||||
@@ -341,12 +328,12 @@
|
||||
cfnaOnPattern = cfg.getParameter("cfna_on_pattern", "");
|
||||
if (cfnaOnPattern.empty())
|
||||
{
|
||||
- ERROR("CfnaOnPattern is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("cfna_on_pattern is empty\n");
|
||||
+ cfnaOnPattern = "invalid_default_value";
|
||||
}
|
||||
if (regcomp(&m_patterns.cfnaOnPattern, cfnaOnPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
{
|
||||
- ERROR("CfnaOnPattern failed to compile ('%s'): %s\n",
|
||||
+ ERROR("cfna_on_pattern failed to compile ('%s'): %s\n",
|
||||
cfnaOnPattern.c_str(),
|
||||
strerror(errno));
|
||||
return -1;
|
||||
@@ -355,12 +342,12 @@
|
||||
cfnaOffPattern = cfg.getParameter("cfna_off_pattern", "");
|
||||
if (cfnaOffPattern.empty())
|
||||
{
|
||||
- ERROR("CfnaOffPattern is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("cfna_off_pattern is empty\n");
|
||||
+ cfnaOffPattern = "invalid_default_value";
|
||||
}
|
||||
if (regcomp(&m_patterns.cfnaOffPattern, cfnaOffPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
{
|
||||
- ERROR("CfnaOffPattern failed to compile ('%s'): %s\n",
|
||||
+ ERROR("cfna_off_pattern failed to compile ('%s'): %s\n",
|
||||
cfnaOffPattern.c_str(),
|
||||
strerror(errno));
|
||||
return -1;
|
||||
@@ -369,43 +356,41 @@
|
||||
speedDialPattern = cfg.getParameter("speed_dial_pattern", "");
|
||||
if (speedDialPattern.empty())
|
||||
{
|
||||
- ERROR("SpeedDialPattern is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("speed_dial_pattern is empty\n");
|
||||
+ speedDialPattern = "invalid_default_value";
|
||||
}
|
||||
if (regcomp(&m_patterns.speedDialPattern, speedDialPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
{
|
||||
- ERROR("SpeedDialPattern failed to compile ('%s'): %s\n",
|
||||
+ ERROR("speed_dial_pattern failed to compile ('%s'): %s\n",
|
||||
speedDialPattern.c_str(),
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
-
|
||||
reminderOnPattern = cfg.getParameter("reminder_on_pattern", "");
|
||||
if (reminderOnPattern.empty())
|
||||
{
|
||||
- ERROR("ReminderOnPattern is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("reminder_on_pattern is empty\n");
|
||||
+ reminderOnPattern = "invalid_default_value";
|
||||
}
|
||||
if (regcomp(&m_patterns.reminderOnPattern, reminderOnPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
{
|
||||
- ERROR("ReminderOnPattern failed to compile ('%s'): %s\n",
|
||||
+ ERROR("reminder_on_pattern failed to compile ('%s'): %s\n",
|
||||
reminderOnPattern.c_str(),
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
-
|
||||
reminderOffPattern = cfg.getParameter("reminder_off_pattern", "");
|
||||
if (reminderOffPattern.empty())
|
||||
{
|
||||
- ERROR("ReminderOffPattern is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("reminder_off_pattern is empty\n");
|
||||
+ reminderOffPattern = "invalid_default_value";
|
||||
}
|
||||
if (regcomp(&m_patterns.reminderOffPattern, reminderOffPattern.c_str(),
|
||||
REG_EXTENDED | REG_NOSUB))
|
||||
{
|
||||
- ERROR("ReminderOffPattern failed to compile ('%s'): %s\n",
|
||||
+ ERROR("reminder_off_pattern failed to compile ('%s'): %s\n",
|
||||
reminderOffPattern.c_str(),
|
||||
strerror(errno));
|
||||
return -1;
|
||||
@@ -414,28 +399,27 @@
|
||||
blockinclirOnPattern = cfg.getParameter("blockinclir_on_pattern", "");
|
||||
if (blockinclirOnPattern.empty())
|
||||
{
|
||||
- ERROR("BlockinclirOnPattern is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("blockinclir_on_pattern is empty\n");
|
||||
+ blockinclirOnPattern = "invalid_default_value";
|
||||
}
|
||||
if (regcomp(&m_patterns.blockinclirOnPattern, blockinclirOnPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
{
|
||||
- ERROR("BlockinclirOnPattern failed to compile ('%s'): %s\n",
|
||||
+ ERROR("blockinclir_on_pattern failed to compile ('%s'): %s\n",
|
||||
blockinclirOnPattern.c_str(),
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
-
|
||||
blockinclirOffPattern = cfg.getParameter("blockinclir_off_pattern", "");
|
||||
if (blockinclirOffPattern.empty())
|
||||
{
|
||||
- ERROR("BlockinclirOffPattern is empty\n");
|
||||
- return -1;
|
||||
+ ERROR("blockinclir_off_pattern is empty\n");
|
||||
+ blockinclirOffPattern = "invalid_default_value";
|
||||
}
|
||||
if (regcomp(&m_patterns.blockinclirOffPattern, blockinclirOffPattern.c_str(),
|
||||
REG_EXTENDED | REG_NOSUB))
|
||||
{
|
||||
- ERROR("BlockinclirOffPattern failed to compile ('%s'): %s\n",
|
||||
+ ERROR("blockinclir_off_pattern failed to compile ('%s'): %s\n",
|
||||
blockinclirOffPattern.c_str(),
|
||||
strerror(errno));
|
||||
return -1;
|
||||
@@ -1123,124 +1107,21 @@
|
||||
|
||||
|
||||
failAnnouncement = m_patterns->audioPath + lang + m_patterns->failAnnouncement;
|
||||
- if (!file_exists(failAnnouncement))
|
||||
+ if (m_patterns->failAnnouncement.empty() || !file_exists(failAnnouncement))
|
||||
{
|
||||
ERROR("ErrorAnnouncement file does not exist ('%s').\n",
|
||||
failAnnouncement.c_str());
|
||||
throw AmSession::Exception(500, "could not get failed announcement");
|
||||
}
|
||||
unknownAnnouncement = m_patterns->audioPath + lang + m_patterns->unknownAnnouncement;
|
||||
- if (!file_exists(unknownAnnouncement))
|
||||
+ if (m_patterns->unknownAnnouncement.empty() || !file_exists(unknownAnnouncement))
|
||||
{
|
||||
ERROR("UnknownAnnouncement file does not exist ('%s').\n",
|
||||
unknownAnnouncement.c_str());
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
- cfuOnAnnouncement = m_patterns->audioPath + lang + m_patterns->cfuOnAnnouncement;
|
||||
- if (!file_exists(cfuOnAnnouncement))
|
||||
- {
|
||||
- ERROR("CfuOnAnnouncement file does not exist ('%s').\n",
|
||||
- cfuOnAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- cfuOffAnnouncement = m_patterns->audioPath + lang + m_patterns->cfuOffAnnouncement;
|
||||
- if (!file_exists(cfuOffAnnouncement))
|
||||
- {
|
||||
- ERROR("CfuOffAnnouncement file does not exist ('%s').\n",
|
||||
- cfuOffAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- cfbOnAnnouncement = m_patterns->audioPath + lang + m_patterns->cfbOnAnnouncement;
|
||||
- if (!file_exists(cfbOnAnnouncement))
|
||||
- {
|
||||
- ERROR("CfbOnAnnouncement file does not exist ('%s').\n",
|
||||
- cfbOnAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- cfbOffAnnouncement = m_patterns->audioPath + lang + m_patterns->cfbOffAnnouncement;
|
||||
- if (!file_exists(cfbOffAnnouncement))
|
||||
- {
|
||||
- ERROR("CfbOffAnnouncement file does not exist ('%s').\n",
|
||||
- cfbOffAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- cftOnAnnouncement = m_patterns->audioPath + lang + m_patterns->cftOnAnnouncement;
|
||||
- if (!file_exists(cftOnAnnouncement))
|
||||
- {
|
||||
- ERROR("CftOnAnnouncement file does not exist ('%s').\n",
|
||||
- cftOnAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- cftOffAnnouncement = m_patterns->audioPath + lang + m_patterns->cftOffAnnouncement;
|
||||
- if (!file_exists(cftOffAnnouncement))
|
||||
- {
|
||||
- ERROR("CftOffAnnouncement file does not exist ('%s').\n",
|
||||
- cftOffAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- cfnaOnAnnouncement = m_patterns->audioPath + lang + m_patterns->cfnaOnAnnouncement;
|
||||
- if (!file_exists(cfnaOnAnnouncement))
|
||||
- {
|
||||
- ERROR("CfnaOnAnnouncement file does not exist ('%s').\n",
|
||||
- cfnaOnAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- cfnaOffAnnouncement = m_patterns->audioPath + lang + m_patterns->cfnaOffAnnouncement;
|
||||
- if (!file_exists(cfnaOffAnnouncement))
|
||||
- {
|
||||
- ERROR("CfnaOffAnnouncement file does not exist ('%s').\n",
|
||||
- cfnaOffAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- speedDialAnnouncement = m_patterns->audioPath + lang + m_patterns->speedDialAnnouncement;
|
||||
- if (!file_exists(speedDialAnnouncement))
|
||||
- {
|
||||
- ERROR("SpeedDialAnnouncement file does not exist ('%s').\n",
|
||||
- speedDialAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- reminderOnAnnouncement = m_patterns->audioPath + lang + m_patterns->reminderOnAnnouncement;
|
||||
- if (!file_exists(reminderOnAnnouncement))
|
||||
- {
|
||||
- ERROR("ReminderOnAnnouncement file does not exist ('%s').\n",
|
||||
- reminderOnAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- reminderOffAnnouncement = m_patterns->audioPath + lang + m_patterns->reminderOffAnnouncement;
|
||||
- if (!file_exists(reminderOffAnnouncement))
|
||||
- {
|
||||
- ERROR("ReminderOffAnnouncement file does not exist ('%s').\n",
|
||||
- reminderOffAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- blockinclirOnAnnouncement = m_patterns->audioPath + lang + m_patterns->blockinclirOnAnnouncement;
|
||||
- if (!file_exists(blockinclirOnAnnouncement))
|
||||
- {
|
||||
- ERROR("BlockinclirOnAnnouncement file does not exist ('%s').\n",
|
||||
- blockinclirOnAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- blockinclirOffAnnouncement = m_patterns->audioPath + lang + m_patterns->blockinclirOffAnnouncement;
|
||||
- if (!file_exists(blockinclirOffAnnouncement))
|
||||
- {
|
||||
- ERROR("BlockinclirOffAnnouncement file does not exist ('%s').\n",
|
||||
- blockinclirOffAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+
|
||||
|
||||
my_handler = mysql_init(NULL);
|
||||
if (!mysql_real_connect(my_handler,
|
||||
@@ -1278,6 +1159,15 @@
|
||||
if ((ret = regexec(&m_patterns->cfuOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ cfuOnAnnouncement = m_patterns->audioPath + lang + m_patterns->cfuOnAnnouncement;
|
||||
+ if (m_patterns->cfuOnAnnouncement.empty() || !file_exists(cfuOnAnnouncement))
|
||||
+ {
|
||||
+ ERROR("CfuOnAnnouncement file does not exist ('%s').\n",
|
||||
+ cfuOnAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
u_int64_t attId = getAttributeId(my_handler, "cfu");
|
||||
if (!attId)
|
||||
{
|
||||
@@ -1349,6 +1239,15 @@
|
||||
if ((ret = regexec(&m_patterns->cfuOffPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ cfuOffAnnouncement = m_patterns->audioPath + lang + m_patterns->cfuOffAnnouncement;
|
||||
+ if (m_patterns->cfuOffAnnouncement.empty() || !file_exists(cfuOffAnnouncement))
|
||||
+ {
|
||||
+ ERROR("CfuOffAnnouncement file does not exist ('%s').\n",
|
||||
+ cfuOffAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFU, "cfu"))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
@@ -1395,6 +1294,15 @@
|
||||
if ((ret = regexec(&m_patterns->cfbOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ cfbOnAnnouncement = m_patterns->audioPath + lang + m_patterns->cfbOnAnnouncement;
|
||||
+ if (m_patterns->cfbOnAnnouncement.empty() || !file_exists(cfbOnAnnouncement))
|
||||
+ {
|
||||
+ ERROR("CfbOnAnnouncement file does not exist ('%s').\n",
|
||||
+ cfbOnAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
u_int64_t attId = getAttributeId(my_handler, "cfb");
|
||||
if (!attId)
|
||||
{
|
||||
@@ -1466,6 +1374,15 @@
|
||||
if ((ret = regexec(&m_patterns->cfbOffPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ cfbOffAnnouncement = m_patterns->audioPath + lang + m_patterns->cfbOffAnnouncement;
|
||||
+ if (m_patterns->cfbOffAnnouncement.empty() || !file_exists(cfbOffAnnouncement))
|
||||
+ {
|
||||
+ ERROR("CfbOffAnnouncement file does not exist ('%s').\n",
|
||||
+ cfbOffAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFB, "cfb"))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
@@ -1512,6 +1429,15 @@
|
||||
if ((ret = regexec(&m_patterns->cftOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ cftOnAnnouncement = m_patterns->audioPath + lang + m_patterns->cftOnAnnouncement;
|
||||
+ if (m_patterns->cftOnAnnouncement.empty() || !file_exists(cftOnAnnouncement))
|
||||
+ {
|
||||
+ ERROR("CftOnAnnouncement file does not exist ('%s').\n",
|
||||
+ cftOnAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
u_int64_t attId = getAttributeId(my_handler, "cft");
|
||||
if (!attId)
|
||||
{
|
||||
@@ -1621,6 +1547,15 @@
|
||||
if ((ret = regexec(&m_patterns->cftOffPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ cftOffAnnouncement = m_patterns->audioPath + lang + m_patterns->cftOffAnnouncement;
|
||||
+ if (m_patterns->cftOffAnnouncement.empty() || !file_exists(cftOffAnnouncement))
|
||||
+ {
|
||||
+ ERROR("CftOffAnnouncement file does not exist ('%s').\n",
|
||||
+ cftOffAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFT, "cft"))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
@@ -1692,6 +1627,15 @@
|
||||
if ((ret = regexec(&m_patterns->cfnaOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ cfnaOnAnnouncement = m_patterns->audioPath + lang + m_patterns->cfnaOnAnnouncement;
|
||||
+ if (m_patterns->cfnaOnAnnouncement.empty() || !file_exists(cfnaOnAnnouncement))
|
||||
+ {
|
||||
+ ERROR("CfnaOnAnnouncement file does not exist ('%s').\n",
|
||||
+ cfnaOnAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
u_int64_t attId = getAttributeId(my_handler, "cfna");
|
||||
if (!attId)
|
||||
{
|
||||
@@ -1763,6 +1707,15 @@
|
||||
if ((ret = regexec(&m_patterns->cfnaOffPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ cfnaOffAnnouncement = m_patterns->audioPath + lang + m_patterns->cfnaOffAnnouncement;
|
||||
+ if (m_patterns->cfnaOffAnnouncement.empty() || !file_exists(cfnaOffAnnouncement))
|
||||
+ {
|
||||
+ ERROR("CfnaOffAnnouncement file does not exist ('%s').\n",
|
||||
+ cfnaOffAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFNA, "cfna"))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
@@ -1809,6 +1762,15 @@
|
||||
if ((ret = regexec(&m_patterns->speedDialPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ speedDialAnnouncement = m_patterns->audioPath + lang + m_patterns->speedDialAnnouncement;
|
||||
+ if (m_patterns->speedDialAnnouncement.empty() || !file_exists(speedDialAnnouncement))
|
||||
+ {
|
||||
+ ERROR("SpeedDialAnnouncement file does not exist ('%s').\n",
|
||||
+ speedDialAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
string slot = string("*") + req.user.substr(4, 1);
|
||||
if (!number2uri(req, my_handler, uuid, subId, domain, domId, 5,
|
||||
uri, username))
|
||||
@@ -1839,6 +1801,15 @@
|
||||
if ((ret = regexec(&m_patterns->reminderOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ reminderOnAnnouncement = m_patterns->audioPath + lang + m_patterns->reminderOnAnnouncement;
|
||||
+ if (m_patterns->reminderOnAnnouncement.empty() || !file_exists(reminderOnAnnouncement))
|
||||
+ {
|
||||
+ ERROR("ReminderOnAnnouncement file does not exist ('%s').\n",
|
||||
+ reminderOnAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
int hour, min;
|
||||
string tim; char c_tim[6] = "";
|
||||
hour = atoi(req.user.substr(4, 2).c_str());
|
||||
@@ -1885,6 +1856,15 @@
|
||||
if ((ret = regexec(&m_patterns->reminderOffPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ reminderOffAnnouncement = m_patterns->audioPath + lang + m_patterns->reminderOffAnnouncement;
|
||||
+ if (m_patterns->reminderOffAnnouncement.empty() || !file_exists(reminderOffAnnouncement))
|
||||
+ {
|
||||
+ ERROR("ReminderOffAnnouncement file does not exist ('%s').\n",
|
||||
+ reminderOffAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
if (!deleteReminder(my_handler, subId))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
@@ -1906,10 +1886,18 @@
|
||||
}
|
||||
|
||||
|
||||
- // block in clir
|
||||
if ((ret = regexec(&m_patterns->blockinclirOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ blockinclirOnAnnouncement = m_patterns->audioPath + lang + m_patterns->blockinclirOnAnnouncement;
|
||||
+ if (m_patterns->blockinclirOnAnnouncement.empty() || !file_exists(blockinclirOnAnnouncement))
|
||||
+ {
|
||||
+ ERROR("BlockinclirOnAnnouncement file does not exist ('%s').\n",
|
||||
+ blockinclirOnAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
std::string val = "1";
|
||||
u_int64_t attId = getAttributeId(my_handler, "block_in_clir");
|
||||
if (!attId)
|
||||
@@ -1957,6 +1945,15 @@
|
||||
if ((ret = regexec(&m_patterns->blockinclirOffPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
+ blockinclirOffAnnouncement = m_patterns->audioPath + lang + m_patterns->blockinclirOffAnnouncement;
|
||||
+ if (m_patterns->blockinclirOffAnnouncement.empty() || !file_exists(blockinclirOffAnnouncement))
|
||||
+ {
|
||||
+ ERROR("BlockinclirOffAnnouncement file does not exist ('%s').\n",
|
||||
+ blockinclirOffAnnouncement.c_str());
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
u_int64_t attId = getAttributeId(my_handler, "block_in_clir");
|
||||
if (!attId)
|
||||
{
|
||||
@ -1,565 +0,0 @@
|
||||
From f40a8b932a1dabd664995014d2fc2c9f2bcc9723 Mon Sep 17 00:00:00 2001
|
||||
From: Andreas Granig <agranig@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:09 +0100
|
||||
Subject: MT#55831 Rework config validation to be more slack (part 2)
|
||||
|
||||
Don't bail out on missing config options, rather than using some
|
||||
invalid defaults.
|
||||
Also only check for existence of sound files in the places where
|
||||
they are needed for optimization purposes.
|
||||
Use macros to clean up redundant code.
|
||||
(real ticket number: MT#20649)
|
||||
|
||||
Index: sems/apps/sw_vsc/SW_Vsc.cpp
|
||||
===================================================================
|
||||
--- sems.orig/apps/sw_vsc/SW_Vsc.cpp 2016-07-21 16:00:25.721737956 +0200
|
||||
+++ sems/apps/sw_vsc/SW_Vsc.cpp 2016-07-21 16:06:05.734333422 +0200
|
||||
@@ -73,6 +73,38 @@
|
||||
#define SW_VSC_DESTSET_CFT "cft_by_vsc"
|
||||
#define SW_VSC_DESTSET_CFNA "cfna_by_vsc"
|
||||
|
||||
+#define CHECK_ANNOUNCEMENT_CONFIG(member, config_var) \
|
||||
+ m_patterns.member = cfg.getParameter(config_var, ""); \
|
||||
+ if (m_patterns.member.empty()) \
|
||||
+ { \
|
||||
+ ERROR(config_var " file not set\n"); \
|
||||
+ }
|
||||
+
|
||||
+#define COMPILE_MATCH_PATTERN(member, config_var) \
|
||||
+ member = cfg.getParameter(config_var, ""); \
|
||||
+ if (member.empty()) \
|
||||
+ { \
|
||||
+ ERROR(config_var " is empty\n"); \
|
||||
+ member = "invalid_default_value"; \
|
||||
+ } \
|
||||
+ if (regcomp(&m_patterns.member, member.c_str(), REG_EXTENDED | REG_NOSUB)) \
|
||||
+ { \
|
||||
+ ERROR(config_var " failed to compile ('%s'): %s\n", \
|
||||
+ member.c_str(), \
|
||||
+ strerror(errno)); \
|
||||
+ return -1; \
|
||||
+ }
|
||||
+
|
||||
+#define CHECK_ANNOUNCEMENT_PATH(member, config_var) \
|
||||
+ member = m_patterns->audioPath + lang + m_patterns->member; \
|
||||
+ if (m_patterns->member.empty() || !file_exists(member)) \
|
||||
+ { \
|
||||
+ ERROR(config_var " file does not exist ('%s').\n", \
|
||||
+ member.c_str()); \
|
||||
+ filename = failAnnouncement; \
|
||||
+ goto out; \
|
||||
+ }
|
||||
+
|
||||
EXPORT_SESSION_FACTORY(SW_VscFactory, MOD_NAME);
|
||||
|
||||
SW_VscFactory::SW_VscFactory(const string &_app_name)
|
||||
@@ -154,82 +186,22 @@
|
||||
if (m_patterns.audioPath[m_patterns.audioPath.length() - 1] != '/' )
|
||||
m_patterns.audioPath += "/";
|
||||
|
||||
- // MT#20649: don't fail if announcements are missing;
|
||||
- m_patterns.failAnnouncement = cfg.getParameter("error_announcement", "");
|
||||
- if (m_patterns.failAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("error_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.unknownAnnouncement = cfg.getParameter("unknown_announcement", "");
|
||||
- if (m_patterns.unknownAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("unknown_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.cfuOnAnnouncement = cfg.getParameter("cfu_on_announcement", "");
|
||||
- if (m_patterns.cfuOnAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("cfu_on_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.cfuOffAnnouncement = cfg.getParameter("cfu_off_announcement", "");
|
||||
- if (m_patterns.cfuOffAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("cfu_off_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.cfbOnAnnouncement = cfg.getParameter("cfb_on_announcement", "");
|
||||
- if (m_patterns.cfbOnAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("cfb_on_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.cfbOffAnnouncement = cfg.getParameter("cfb_off_announcement", "");
|
||||
- if (m_patterns.cfbOffAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("cfb_off_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.cftOnAnnouncement = cfg.getParameter("cft_on_announcement", "");
|
||||
- if (m_patterns.cftOnAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("cft_on_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.cftOffAnnouncement = cfg.getParameter("cft_off_announcement", "");
|
||||
- if (m_patterns.cftOffAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("cft_off_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.cfnaOnAnnouncement = cfg.getParameter("cfna_on_announcement", "");
|
||||
- if (m_patterns.cfnaOnAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("cfna_on_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.cfnaOffAnnouncement = cfg.getParameter("cfna_off_announcement", "");
|
||||
- if (m_patterns.cfnaOffAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("cfna_off_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.speedDialAnnouncement = cfg.getParameter("speed_dial_announcement", "");
|
||||
- if (m_patterns.speedDialAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("speed_dial_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.reminderOnAnnouncement = cfg.getParameter("reminder_on_announcement", "");
|
||||
- if (m_patterns.reminderOnAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("reminder_on_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.reminderOffAnnouncement = cfg.getParameter("reminder_off_announcement", "");
|
||||
- if (m_patterns.reminderOffAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("reminder_off_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.blockinclirOnAnnouncement = cfg.getParameter("blockinclir_on_announcement", "");
|
||||
- if (m_patterns.blockinclirOnAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("blockinclir_on_announcement file not set\n");
|
||||
- }
|
||||
- m_patterns.blockinclirOffAnnouncement = cfg.getParameter("blockinclir_off_announcement", "");
|
||||
- if (m_patterns.blockinclirOffAnnouncement.empty())
|
||||
- {
|
||||
- ERROR("blockinclir_off_announcement file not set\n");
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(failAnnouncement, "error_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(unknownAnnouncement, "unknown_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(cfuOnAnnouncement, "cfu_on_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(cfuOffAnnouncement, "cfu_off_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(cfbOnAnnouncement, "cfb_on_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(cfbOffAnnouncement, "cfb_off_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(cftOnAnnouncement, "cft_on_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(cftOffAnnouncement, "cft_off_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(cfnaOnAnnouncement, "cfna_on_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(cfnaOffAnnouncement, "cfna_off_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(speedDialAnnouncement, "speed_dial_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(reminderOnAnnouncement, "reminder_on_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(reminderOffAnnouncement, "reminder_off_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(blockinclirOnAnnouncement, "blockinclir_on_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(blockinclirOffAnnouncement, "blockinclir_off_announcement");
|
||||
+
|
||||
|
||||
// We could set a default in cfg.getParameter, but we really want to log the error
|
||||
// if the pattern in question is not set:
|
||||
@@ -241,189 +213,19 @@
|
||||
m_patterns.voicemailNumber = "invalid_default_value";
|
||||
}
|
||||
|
||||
- cfuOnPattern = cfg.getParameter("cfu_on_pattern", "");
|
||||
- if (cfuOnPattern.empty())
|
||||
- {
|
||||
- ERROR("cfu_on_pattern is empty\n");
|
||||
- cfuOnPattern = "invalid_default_value";
|
||||
- }
|
||||
- if (regcomp(&m_patterns.cfuOnPattern, cfuOnPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
- {
|
||||
- ERROR("cfu_on_pattern failed to compile ('%s'): %s\n",
|
||||
- cfuOnPattern.c_str(),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- cfuOffPattern = cfg.getParameter("cfu_off_pattern", "");
|
||||
- if (cfuOffPattern.empty())
|
||||
- {
|
||||
- ERROR("cfu_off_pattern is empty\n");
|
||||
- cfuOffPattern = "invalid_default_value";
|
||||
- }
|
||||
- if (regcomp(&m_patterns.cfuOffPattern, cfuOffPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
- {
|
||||
- ERROR("cfu_off_pattern failed to compile ('%s'): %s\n",
|
||||
- cfuOffPattern.c_str(),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- cfbOnPattern = cfg.getParameter("cfb_on_pattern", "");
|
||||
- if (cfbOnPattern.empty())
|
||||
- {
|
||||
- ERROR("cfb_on_pattern is empty\n");
|
||||
- cfbOnPattern = "invalid_default_value";
|
||||
- }
|
||||
- if (regcomp(&m_patterns.cfbOnPattern, cfbOnPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
- {
|
||||
- ERROR("cfb_on_pattern failed to compile ('%s'): %s\n",
|
||||
- cfbOnPattern.c_str(),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- cfbOffPattern = cfg.getParameter("cfb_off_pattern", "");
|
||||
- if (cfbOffPattern.empty())
|
||||
- {
|
||||
- ERROR("cfb_off_pattern is empty\n");
|
||||
- cfbOffPattern = "invalid_default_value";
|
||||
- }
|
||||
- if (regcomp(&m_patterns.cfbOffPattern, cfbOffPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
- {
|
||||
- ERROR("cfb_off_pattern failed to compile ('%s'): %s\n",
|
||||
- cfbOffPattern.c_str(),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- cftOnPattern = cfg.getParameter("cft_on_pattern", "");
|
||||
- if (cftOnPattern.empty())
|
||||
- {
|
||||
- ERROR("cft_on_pattern is empty\n");
|
||||
- cftOnPattern = "invalid_default_value";
|
||||
- }
|
||||
- if (regcomp(&m_patterns.cftOnPattern, cftOnPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
- {
|
||||
- ERROR("cft_on_pattern failed to compile ('%s'): %s\n",
|
||||
- cftOnPattern.c_str(),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- cftOffPattern = cfg.getParameter("cft_off_pattern", "");
|
||||
- if (cftOffPattern.empty())
|
||||
- {
|
||||
- ERROR("cft_off_pattern is empty\n");
|
||||
- cftOffPattern = "invalid_default_value";
|
||||
- }
|
||||
- if (regcomp(&m_patterns.cftOffPattern, cftOffPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
- {
|
||||
- ERROR("cft_off_pattern failed to compile ('%s'): %s\n",
|
||||
- cftOffPattern.c_str(),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- cfnaOnPattern = cfg.getParameter("cfna_on_pattern", "");
|
||||
- if (cfnaOnPattern.empty())
|
||||
- {
|
||||
- ERROR("cfna_on_pattern is empty\n");
|
||||
- cfnaOnPattern = "invalid_default_value";
|
||||
- }
|
||||
- if (regcomp(&m_patterns.cfnaOnPattern, cfnaOnPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
- {
|
||||
- ERROR("cfna_on_pattern failed to compile ('%s'): %s\n",
|
||||
- cfnaOnPattern.c_str(),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- cfnaOffPattern = cfg.getParameter("cfna_off_pattern", "");
|
||||
- if (cfnaOffPattern.empty())
|
||||
- {
|
||||
- ERROR("cfna_off_pattern is empty\n");
|
||||
- cfnaOffPattern = "invalid_default_value";
|
||||
- }
|
||||
- if (regcomp(&m_patterns.cfnaOffPattern, cfnaOffPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
- {
|
||||
- ERROR("cfna_off_pattern failed to compile ('%s'): %s\n",
|
||||
- cfnaOffPattern.c_str(),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- speedDialPattern = cfg.getParameter("speed_dial_pattern", "");
|
||||
- if (speedDialPattern.empty())
|
||||
- {
|
||||
- ERROR("speed_dial_pattern is empty\n");
|
||||
- speedDialPattern = "invalid_default_value";
|
||||
- }
|
||||
- if (regcomp(&m_patterns.speedDialPattern, speedDialPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
- {
|
||||
- ERROR("speed_dial_pattern failed to compile ('%s'): %s\n",
|
||||
- speedDialPattern.c_str(),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- reminderOnPattern = cfg.getParameter("reminder_on_pattern", "");
|
||||
- if (reminderOnPattern.empty())
|
||||
- {
|
||||
- ERROR("reminder_on_pattern is empty\n");
|
||||
- reminderOnPattern = "invalid_default_value";
|
||||
- }
|
||||
- if (regcomp(&m_patterns.reminderOnPattern, reminderOnPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
- {
|
||||
- ERROR("reminder_on_pattern failed to compile ('%s'): %s\n",
|
||||
- reminderOnPattern.c_str(),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- reminderOffPattern = cfg.getParameter("reminder_off_pattern", "");
|
||||
- if (reminderOffPattern.empty())
|
||||
- {
|
||||
- ERROR("reminder_off_pattern is empty\n");
|
||||
- reminderOffPattern = "invalid_default_value";
|
||||
- }
|
||||
- if (regcomp(&m_patterns.reminderOffPattern, reminderOffPattern.c_str(),
|
||||
- REG_EXTENDED | REG_NOSUB))
|
||||
- {
|
||||
- ERROR("reminder_off_pattern failed to compile ('%s'): %s\n",
|
||||
- reminderOffPattern.c_str(),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- blockinclirOnPattern = cfg.getParameter("blockinclir_on_pattern", "");
|
||||
- if (blockinclirOnPattern.empty())
|
||||
- {
|
||||
- ERROR("blockinclir_on_pattern is empty\n");
|
||||
- blockinclirOnPattern = "invalid_default_value";
|
||||
- }
|
||||
- if (regcomp(&m_patterns.blockinclirOnPattern, blockinclirOnPattern.c_str(), REG_EXTENDED | REG_NOSUB))
|
||||
- {
|
||||
- ERROR("blockinclir_on_pattern failed to compile ('%s'): %s\n",
|
||||
- blockinclirOnPattern.c_str(),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
-
|
||||
- blockinclirOffPattern = cfg.getParameter("blockinclir_off_pattern", "");
|
||||
- if (blockinclirOffPattern.empty())
|
||||
- {
|
||||
- ERROR("blockinclir_off_pattern is empty\n");
|
||||
- blockinclirOffPattern = "invalid_default_value";
|
||||
- }
|
||||
- if (regcomp(&m_patterns.blockinclirOffPattern, blockinclirOffPattern.c_str(),
|
||||
- REG_EXTENDED | REG_NOSUB))
|
||||
- {
|
||||
- ERROR("blockinclir_off_pattern failed to compile ('%s'): %s\n",
|
||||
- blockinclirOffPattern.c_str(),
|
||||
- strerror(errno));
|
||||
- return -1;
|
||||
- }
|
||||
+ COMPILE_MATCH_PATTERN(cfuOnPattern, "cfu_on_pattern");
|
||||
+ COMPILE_MATCH_PATTERN(cfuOffPattern, "cfu_off_pattern");
|
||||
+ COMPILE_MATCH_PATTERN(cfbOnPattern, "cfb_on_pattern");
|
||||
+ COMPILE_MATCH_PATTERN(cfbOffPattern, "cfb_off_pattern");
|
||||
+ COMPILE_MATCH_PATTERN(cftOnPattern, "cft_on_pattern");
|
||||
+ COMPILE_MATCH_PATTERN(cftOffPattern, "cft_off_pattern");
|
||||
+ COMPILE_MATCH_PATTERN(cfnaOnPattern, "cfna_on_pattern");
|
||||
+ COMPILE_MATCH_PATTERN(cfnaOffPattern, "cfna_off_pattern");
|
||||
+ COMPILE_MATCH_PATTERN(speedDialPattern, "speed_dial_pattern");
|
||||
+ COMPILE_MATCH_PATTERN(reminderOnPattern, "reminder_on_pattern");
|
||||
+ COMPILE_MATCH_PATTERN(reminderOffPattern, "reminder_off_pattern");
|
||||
+ COMPILE_MATCH_PATTERN(blockinclirOnPattern, "blockinclir_on_pattern");
|
||||
+ COMPILE_MATCH_PATTERN(blockinclirOffPattern, "blockinclir_off_pattern");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1159,14 +961,7 @@
|
||||
if ((ret = regexec(&m_patterns->cfuOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- cfuOnAnnouncement = m_patterns->audioPath + lang + m_patterns->cfuOnAnnouncement;
|
||||
- if (m_patterns->cfuOnAnnouncement.empty() || !file_exists(cfuOnAnnouncement))
|
||||
- {
|
||||
- ERROR("CfuOnAnnouncement file does not exist ('%s').\n",
|
||||
- cfuOnAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_PATH(cfuOnAnnouncement, "cfu_on_announcement");
|
||||
|
||||
u_int64_t attId = getAttributeId(my_handler, "cfu");
|
||||
if (!attId)
|
||||
@@ -1239,14 +1034,7 @@
|
||||
if ((ret = regexec(&m_patterns->cfuOffPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- cfuOffAnnouncement = m_patterns->audioPath + lang + m_patterns->cfuOffAnnouncement;
|
||||
- if (m_patterns->cfuOffAnnouncement.empty() || !file_exists(cfuOffAnnouncement))
|
||||
- {
|
||||
- ERROR("CfuOffAnnouncement file does not exist ('%s').\n",
|
||||
- cfuOffAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_PATH(cfuOffAnnouncement, "cfu_off_announcement");
|
||||
|
||||
if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFU, "cfu"))
|
||||
{
|
||||
@@ -1294,14 +1082,7 @@
|
||||
if ((ret = regexec(&m_patterns->cfbOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- cfbOnAnnouncement = m_patterns->audioPath + lang + m_patterns->cfbOnAnnouncement;
|
||||
- if (m_patterns->cfbOnAnnouncement.empty() || !file_exists(cfbOnAnnouncement))
|
||||
- {
|
||||
- ERROR("CfbOnAnnouncement file does not exist ('%s').\n",
|
||||
- cfbOnAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_PATH(cfbOnAnnouncement, "cfb_on_announcement");
|
||||
|
||||
u_int64_t attId = getAttributeId(my_handler, "cfb");
|
||||
if (!attId)
|
||||
@@ -1374,14 +1155,7 @@
|
||||
if ((ret = regexec(&m_patterns->cfbOffPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- cfbOffAnnouncement = m_patterns->audioPath + lang + m_patterns->cfbOffAnnouncement;
|
||||
- if (m_patterns->cfbOffAnnouncement.empty() || !file_exists(cfbOffAnnouncement))
|
||||
- {
|
||||
- ERROR("CfbOffAnnouncement file does not exist ('%s').\n",
|
||||
- cfbOffAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_PATH(cfbOffAnnouncement, "cfb_off_announcement");
|
||||
|
||||
if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFB, "cfb"))
|
||||
{
|
||||
@@ -1429,14 +1203,7 @@
|
||||
if ((ret = regexec(&m_patterns->cftOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- cftOnAnnouncement = m_patterns->audioPath + lang + m_patterns->cftOnAnnouncement;
|
||||
- if (m_patterns->cftOnAnnouncement.empty() || !file_exists(cftOnAnnouncement))
|
||||
- {
|
||||
- ERROR("CftOnAnnouncement file does not exist ('%s').\n",
|
||||
- cftOnAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_PATH(cftOnAnnouncement, "cft_on_announcement");
|
||||
|
||||
u_int64_t attId = getAttributeId(my_handler, "cft");
|
||||
if (!attId)
|
||||
@@ -1547,14 +1314,7 @@
|
||||
if ((ret = regexec(&m_patterns->cftOffPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- cftOffAnnouncement = m_patterns->audioPath + lang + m_patterns->cftOffAnnouncement;
|
||||
- if (m_patterns->cftOffAnnouncement.empty() || !file_exists(cftOffAnnouncement))
|
||||
- {
|
||||
- ERROR("CftOffAnnouncement file does not exist ('%s').\n",
|
||||
- cftOffAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_PATH(cftOffAnnouncement, "cft_off_announcement");
|
||||
|
||||
if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFT, "cft"))
|
||||
{
|
||||
@@ -1627,14 +1387,7 @@
|
||||
if ((ret = regexec(&m_patterns->cfnaOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- cfnaOnAnnouncement = m_patterns->audioPath + lang + m_patterns->cfnaOnAnnouncement;
|
||||
- if (m_patterns->cfnaOnAnnouncement.empty() || !file_exists(cfnaOnAnnouncement))
|
||||
- {
|
||||
- ERROR("CfnaOnAnnouncement file does not exist ('%s').\n",
|
||||
- cfnaOnAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_PATH(cfnaOnAnnouncement, "cfna_on_announcement");
|
||||
|
||||
u_int64_t attId = getAttributeId(my_handler, "cfna");
|
||||
if (!attId)
|
||||
@@ -1707,14 +1460,7 @@
|
||||
if ((ret = regexec(&m_patterns->cfnaOffPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- cfnaOffAnnouncement = m_patterns->audioPath + lang + m_patterns->cfnaOffAnnouncement;
|
||||
- if (m_patterns->cfnaOffAnnouncement.empty() || !file_exists(cfnaOffAnnouncement))
|
||||
- {
|
||||
- ERROR("CfnaOffAnnouncement file does not exist ('%s').\n",
|
||||
- cfnaOffAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_PATH(cfnaOffAnnouncement, "cfna_off_announcement");
|
||||
|
||||
if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFNA, "cfna"))
|
||||
{
|
||||
@@ -1762,14 +1508,7 @@
|
||||
if ((ret = regexec(&m_patterns->speedDialPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- speedDialAnnouncement = m_patterns->audioPath + lang + m_patterns->speedDialAnnouncement;
|
||||
- if (m_patterns->speedDialAnnouncement.empty() || !file_exists(speedDialAnnouncement))
|
||||
- {
|
||||
- ERROR("SpeedDialAnnouncement file does not exist ('%s').\n",
|
||||
- speedDialAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_PATH(speedDialAnnouncement, "speed_dial_announcement");
|
||||
|
||||
string slot = string("*") + req.user.substr(4, 1);
|
||||
if (!number2uri(req, my_handler, uuid, subId, domain, domId, 5,
|
||||
@@ -1801,14 +1540,7 @@
|
||||
if ((ret = regexec(&m_patterns->reminderOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- reminderOnAnnouncement = m_patterns->audioPath + lang + m_patterns->reminderOnAnnouncement;
|
||||
- if (m_patterns->reminderOnAnnouncement.empty() || !file_exists(reminderOnAnnouncement))
|
||||
- {
|
||||
- ERROR("ReminderOnAnnouncement file does not exist ('%s').\n",
|
||||
- reminderOnAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_PATH(reminderOnAnnouncement, "reminder_on_announcement");
|
||||
|
||||
int hour, min;
|
||||
string tim; char c_tim[6] = "";
|
||||
@@ -1856,14 +1588,7 @@
|
||||
if ((ret = regexec(&m_patterns->reminderOffPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- reminderOffAnnouncement = m_patterns->audioPath + lang + m_patterns->reminderOffAnnouncement;
|
||||
- if (m_patterns->reminderOffAnnouncement.empty() || !file_exists(reminderOffAnnouncement))
|
||||
- {
|
||||
- ERROR("ReminderOffAnnouncement file does not exist ('%s').\n",
|
||||
- reminderOffAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_PATH(reminderOffAnnouncement, "reminder_off_announcement");
|
||||
|
||||
if (!deleteReminder(my_handler, subId))
|
||||
{
|
||||
@@ -1889,14 +1614,7 @@
|
||||
if ((ret = regexec(&m_patterns->blockinclirOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- blockinclirOnAnnouncement = m_patterns->audioPath + lang + m_patterns->blockinclirOnAnnouncement;
|
||||
- if (m_patterns->blockinclirOnAnnouncement.empty() || !file_exists(blockinclirOnAnnouncement))
|
||||
- {
|
||||
- ERROR("BlockinclirOnAnnouncement file does not exist ('%s').\n",
|
||||
- blockinclirOnAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_PATH(blockinclirOnAnnouncement, "blockinclir_on_announcement");
|
||||
|
||||
std::string val = "1";
|
||||
u_int64_t attId = getAttributeId(my_handler, "block_in_clir");
|
||||
@@ -1945,14 +1663,7 @@
|
||||
if ((ret = regexec(&m_patterns->blockinclirOffPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- blockinclirOffAnnouncement = m_patterns->audioPath + lang + m_patterns->blockinclirOffAnnouncement;
|
||||
- if (m_patterns->blockinclirOffAnnouncement.empty() || !file_exists(blockinclirOffAnnouncement))
|
||||
- {
|
||||
- ERROR("BlockinclirOffAnnouncement file does not exist ('%s').\n",
|
||||
- blockinclirOffAnnouncement.c_str());
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
+ CHECK_ANNOUNCEMENT_PATH(blockinclirOffAnnouncement, "blockinclir_off_announcement");
|
||||
|
||||
u_int64_t attId = getAttributeId(my_handler, "block_in_clir");
|
||||
if (!attId)
|
||||
@ -1,438 +0,0 @@
|
||||
From 7ce85a46b4d4ba01c1c98309a5c6d28c654efae3 Mon Sep 17 00:00:00 2001
|
||||
From: Marco Capetta <mcapetta@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:24 +0100
|
||||
Subject: MT#55831 Add VSC to disable all active call forwards at once
|
||||
|
||||
This feature gives the user the ability to disable all active
|
||||
call forwards (CFU, CFB, CFT, CFNA, CFS, CFR, CFO) by triggering
|
||||
a VSC on the phone.
|
||||
|
||||
Additionally create function SW_VscDialog::deleteCF to group all
|
||||
the common operations that are done to delete a CF.
|
||||
(real ticket number: TT#71001)
|
||||
|
||||
--- a/apps/sw_vsc/SW_Vsc.cpp
|
||||
+++ b/apps/sw_vsc/SW_Vsc.cpp
|
||||
@@ -72,6 +72,9 @@ using namespace pcrecpp;
|
||||
#define SW_VSC_DESTSET_CFB "cfb_by_vsc"
|
||||
#define SW_VSC_DESTSET_CFT "cft_by_vsc"
|
||||
#define SW_VSC_DESTSET_CFNA "cfna_by_vsc"
|
||||
+#define SW_VSC_DESTSET_CFS "cfs_by_vsc"
|
||||
+#define SW_VSC_DESTSET_CFR "cfr_by_vsc"
|
||||
+#define SW_VSC_DESTSET_CFO "cfc_by_vsc"
|
||||
|
||||
#define CHECK_ANNOUNCEMENT_CONFIG(member, config_var) \
|
||||
m_patterns.member = cfg.getParameter(config_var, ""); \
|
||||
@@ -114,6 +117,7 @@ SW_VscFactory::SW_VscFactory(const strin
|
||||
|
||||
SW_VscFactory::~SW_VscFactory()
|
||||
{
|
||||
+ regfree(&m_patterns.cfOffPattern);
|
||||
regfree(&m_patterns.cfuOnPattern);
|
||||
regfree(&m_patterns.cfuOffPattern);
|
||||
regfree(&m_patterns.cfbOnPattern);
|
||||
@@ -131,6 +135,7 @@ SW_VscFactory::~SW_VscFactory()
|
||||
|
||||
int SW_VscFactory::onLoad()
|
||||
{
|
||||
+ string cfOffPattern;
|
||||
string cfuOnPattern;
|
||||
string cfuOffPattern;
|
||||
string cfbOnPattern;
|
||||
@@ -188,6 +193,7 @@ int SW_VscFactory::onLoad()
|
||||
|
||||
CHECK_ANNOUNCEMENT_CONFIG(failAnnouncement, "error_announcement");
|
||||
CHECK_ANNOUNCEMENT_CONFIG(unknownAnnouncement, "unknown_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_CONFIG(cfOffAnnouncement, "cf_off_announcement");
|
||||
CHECK_ANNOUNCEMENT_CONFIG(cfuOnAnnouncement, "cfu_on_announcement");
|
||||
CHECK_ANNOUNCEMENT_CONFIG(cfuOffAnnouncement, "cfu_off_announcement");
|
||||
CHECK_ANNOUNCEMENT_CONFIG(cfbOnAnnouncement, "cfb_on_announcement");
|
||||
@@ -213,6 +219,7 @@ int SW_VscFactory::onLoad()
|
||||
m_patterns.voicemailNumber = "invalid_default_value";
|
||||
}
|
||||
|
||||
+ COMPILE_MATCH_PATTERN(cfOffPattern, "cf_off_pattern");
|
||||
COMPILE_MATCH_PATTERN(cfuOnPattern, "cfu_on_pattern");
|
||||
COMPILE_MATCH_PATTERN(cfuOffPattern, "cfu_off_pattern");
|
||||
COMPILE_MATCH_PATTERN(cfbOnPattern, "cfb_on_pattern");
|
||||
@@ -398,11 +405,14 @@ u_int64_t SW_VscDialog::getSubscriberId(
|
||||
}
|
||||
|
||||
u_int64_t SW_VscDialog::getPreference(MYSQL *my_handler, u_int64_t subscriberId,
|
||||
- u_int64_t attributeId, int *foundPref,
|
||||
- string *value)
|
||||
+ u_int64_t attributeId,
|
||||
+ int *foundPref, string *value)
|
||||
{
|
||||
- MYSQL_RES *res; MYSQL_ROW row; char query[1024] =
|
||||
- ""; u_int64_t id; *foundPref = 0;
|
||||
+ MYSQL_RES *res;
|
||||
+ MYSQL_ROW row;
|
||||
+ char query[1024] = "";
|
||||
+ u_int64_t id;
|
||||
+ *foundPref = 0;
|
||||
|
||||
snprintf(query, sizeof(query), SW_VSC_GET_PREFERENCE_ID,
|
||||
(unsigned long long int)subscriberId,
|
||||
@@ -859,6 +869,44 @@ u_int64_t SW_VscDialog::deleteCFMap(MYSQ
|
||||
return 1;
|
||||
}
|
||||
|
||||
+u_int64_t SW_VscDialog::deleteCF(MYSQL *my_handler, u_int64_t subscriberId,
|
||||
+ const char *mapName, const char *type,
|
||||
+ int *foundPref, string *value, const char *uuid)
|
||||
+{
|
||||
+ if (!deleteCFMap(my_handler, subscriberId, mapName, type))
|
||||
+ {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ u_int64_t attId = getAttributeId(my_handler, type);
|
||||
+ if (!attId)
|
||||
+ {
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ u_int64_t prefId = getPreference(my_handler, subscriberId, attId, foundPref, value);
|
||||
+ if (!prefId)
|
||||
+ {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else if (!*foundPref)
|
||||
+ {
|
||||
+ INFO("Unnecessary VSC %s removal for uuid '%s'",
|
||||
+ type, uuid);
|
||||
+ }
|
||||
+ else if (!deletePreferenceId(my_handler, prefId))
|
||||
+ {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ INFO("Successfully removed VSC %s for uuid '%s'",
|
||||
+ type, uuid);
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
void SW_VscDialog::onInvite(const AmSipRequest &req)
|
||||
{
|
||||
/// fooooo
|
||||
@@ -880,6 +928,7 @@ void SW_VscDialog::onInvite(const AmSipR
|
||||
|
||||
string failAnnouncement;
|
||||
string unknownAnnouncement;
|
||||
+ string cfOffAnnouncement;
|
||||
string cfuOnAnnouncement;
|
||||
string cfuOffAnnouncement;
|
||||
string cfbOnAnnouncement;
|
||||
@@ -958,6 +1007,96 @@ void SW_VscDialog::onInvite(const AmSipR
|
||||
|
||||
setReceiving(false);
|
||||
|
||||
+ if ((ret = regexec(&m_patterns->cfOffPattern,
|
||||
+ req.user.c_str(), 0, 0, 0)) == 0)
|
||||
+ {
|
||||
+ u_int64_t attId, prefId;
|
||||
+
|
||||
+ CHECK_ANNOUNCEMENT_PATH(cfOffAnnouncement, "cf_off_announcement");
|
||||
+
|
||||
+ /// Remove CFU
|
||||
+ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFU, "cfu", &foundPref, &prefStr, uuid.c_str()))
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /// Remove CFB
|
||||
+ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFB, "cfb", &foundPref, &prefStr, uuid.c_str()))
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /// Remove CFT
|
||||
+ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFT, "cft", &foundPref, &prefStr, uuid.c_str()))
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ attId = getAttributeId(my_handler, "ringtimeout");
|
||||
+ if (!attId)
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ prefId = getPreference(my_handler, subId, attId, &foundPref, &prefStr);
|
||||
+ if (!prefId)
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ else if (foundPref && !deletePreferenceId(my_handler, prefId))
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ INFO("Successfully removed VSC cft ringtimeout for uuid '%s'",
|
||||
+ uuid.c_str());
|
||||
+ }
|
||||
+
|
||||
+ /// Remove CFNA
|
||||
+ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFNA, "cfna", &foundPref, &prefStr, uuid.c_str()))
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /// Remove CFS
|
||||
+ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFS, "cfs", &foundPref, &prefStr, uuid.c_str()))
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /// Remove CFR
|
||||
+ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFR, "cfr", &foundPref, &prefStr, uuid.c_str()))
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /// Remove CFO
|
||||
+ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFO, "cfo", &foundPref, &prefStr, uuid.c_str()))
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /// END
|
||||
+ filename = cfOffAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ else if (ret != REG_NOMATCH)
|
||||
+ {
|
||||
+ filename = failAnnouncement;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
if ((ret = regexec(&m_patterns->cfuOnPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
@@ -1034,41 +1173,13 @@ void SW_VscDialog::onInvite(const AmSipR
|
||||
if ((ret = regexec(&m_patterns->cfuOffPattern,
|
||||
req.user.c_str(), 0, 0, 0)) == 0)
|
||||
{
|
||||
- CHECK_ANNOUNCEMENT_PATH(cfuOffAnnouncement, "cfu_off_announcement");
|
||||
+ CHECK_ANNOUNCEMENT_PATH(cfuOffAnnouncement, "cfu_off_announcement");
|
||||
|
||||
- if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFU, "cfu"))
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- u_int64_t attId = getAttributeId(my_handler, "cfu");
|
||||
- if (!attId)
|
||||
+ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFU, "cfu", &foundPref, &prefStr, uuid.c_str()))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
- u_int64_t prefId = getPreference(my_handler, subId, attId,
|
||||
- &foundPref, &prefStr);
|
||||
- if (!prefId)
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- else if (!foundPref)
|
||||
- {
|
||||
- INFO("Unnecessary VSC CFU removal for uuid '%s'",
|
||||
- uuid.c_str());
|
||||
- }
|
||||
- else if (!deletePreferenceId(my_handler, prefId))
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- INFO("Successfully removed VSC CFU for uuid '%s'",
|
||||
- uuid.c_str());
|
||||
- }
|
||||
|
||||
filename = cfuOffAnnouncement;
|
||||
goto out;
|
||||
@@ -1157,39 +1268,11 @@ void SW_VscDialog::onInvite(const AmSipR
|
||||
{
|
||||
CHECK_ANNOUNCEMENT_PATH(cfbOffAnnouncement, "cfb_off_announcement");
|
||||
|
||||
- if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFB, "cfb"))
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- u_int64_t attId = getAttributeId(my_handler, "cfb");
|
||||
- if (!attId)
|
||||
+ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFB, "cfb", &foundPref, &prefStr, uuid.c_str()))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
- u_int64_t prefId = getPreference(my_handler, subId, attId,
|
||||
- &foundPref, &prefStr);
|
||||
- if (!prefId)
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- else if (!foundPref)
|
||||
- {
|
||||
- INFO("Unnecessary VSC CFB removal for uuid '%s'",
|
||||
- uuid.c_str());
|
||||
- }
|
||||
- else if (!deletePreferenceId(my_handler, prefId))
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- INFO("Successfully removed VSC CFB for uuid '%s'",
|
||||
- uuid.c_str());
|
||||
- }
|
||||
|
||||
filename = cfbOffAnnouncement;
|
||||
goto out;
|
||||
@@ -1316,48 +1399,19 @@ void SW_VscDialog::onInvite(const AmSipR
|
||||
{
|
||||
CHECK_ANNOUNCEMENT_PATH(cftOffAnnouncement, "cft_off_announcement");
|
||||
|
||||
- if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFT, "cft"))
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- u_int64_t attId = getAttributeId(my_handler, "cft");
|
||||
- if (!attId)
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- u_int64_t prefId = getPreference(my_handler, subId, attId,
|
||||
- &foundPref, &prefStr);
|
||||
- if (!prefId)
|
||||
+ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFT, "cft", &foundPref, &prefStr, uuid.c_str()))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
- else if (!foundPref)
|
||||
- {
|
||||
- INFO("Unnecessary VSC CFT removal for uuid '%s'",
|
||||
- uuid.c_str());
|
||||
- }
|
||||
- else if (!deletePreferenceId(my_handler, prefId))
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- INFO("Successfully removed VSC CFT for uuid '%s'",
|
||||
- uuid.c_str());
|
||||
- }
|
||||
|
||||
- attId = getAttributeId(my_handler, "ringtimeout");
|
||||
+ u_int64_t attId = getAttributeId(my_handler, "ringtimeout");
|
||||
if (!attId)
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
- prefId = getPreference(my_handler, subId, attId, &foundPref, &prefStr);
|
||||
+ u_int64_t prefId = getPreference(my_handler, subId, attId, &foundPref, &prefStr);
|
||||
if (!prefId)
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
@@ -1462,39 +1516,11 @@ void SW_VscDialog::onInvite(const AmSipR
|
||||
{
|
||||
CHECK_ANNOUNCEMENT_PATH(cfnaOffAnnouncement, "cfna_off_announcement");
|
||||
|
||||
- if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFNA, "cfna"))
|
||||
+ if(!deleteCF(my_handler, subId, SW_VSC_DESTSET_CFNA, "cfna", &foundPref, &prefStr, uuid.c_str()))
|
||||
{
|
||||
filename = failAnnouncement;
|
||||
goto out;
|
||||
}
|
||||
- u_int64_t attId = getAttributeId(my_handler, "cfna");
|
||||
- if (!attId)
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- u_int64_t prefId = getPreference(my_handler, subId, attId,
|
||||
- &foundPref, &prefStr);
|
||||
- if (!prefId)
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- else if (!foundPref)
|
||||
- {
|
||||
- INFO("Unnecessary VSC CFNA removal for uuid '%s'",
|
||||
- uuid.c_str());
|
||||
- }
|
||||
- else if (!deletePreferenceId(my_handler, prefId))
|
||||
- {
|
||||
- filename = failAnnouncement;
|
||||
- goto out;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- INFO("Successfully removed VSC CFNA for uuid '%s'",
|
||||
- uuid.c_str());
|
||||
- }
|
||||
|
||||
filename = cfnaOffAnnouncement;
|
||||
goto out;
|
||||
--- a/apps/sw_vsc/SW_Vsc.h
|
||||
+++ b/apps/sw_vsc/SW_Vsc.h
|
||||
@@ -29,6 +29,9 @@ typedef struct
|
||||
string unknownAnnouncement;
|
||||
string voicemailNumber;
|
||||
|
||||
+ regex_t cfOffPattern;
|
||||
+ string cfOffAnnouncement;
|
||||
+
|
||||
regex_t cfuOnPattern;
|
||||
string cfuOnAnnouncement;
|
||||
|
||||
@@ -118,6 +121,9 @@ class SW_VscDialog : public AmSession,
|
||||
const char *mapName, const char *type);
|
||||
u_int64_t deleteCFMap(MYSQL *my_handler, u_int64_t subscriberId,
|
||||
const char *mapName, const char *type);
|
||||
+ u_int64_t deleteCF(MYSQL *my_handler, u_int64_t subscriberId,
|
||||
+ const char *mapName, const char *type,
|
||||
+ int *foundPref, string *value, const char *uuid);
|
||||
|
||||
|
||||
|
||||
--- a/apps/sw_vsc/etc/sw_vsc.conf
|
||||
+++ b/apps/sw_vsc/etc/sw_vsc.conf
|
||||
@@ -10,6 +10,9 @@ unknown_announcement = sw_vsc_unavailabl
|
||||
|
||||
voicemail_number = 2000
|
||||
|
||||
+cf_off_pattern = ^(\%23)99(\%23)?.*$
|
||||
+cf_off_announcement = sw_vsc_deactivated.wav
|
||||
+
|
||||
cfu_on_pattern = ^\*72\*[0-9]+$
|
||||
cfu_on_announcement = sw_vsc_activated.wav
|
||||
cfu_off_pattern = ^(\%23)72(\%23)?.*$
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,145 +0,0 @@
|
||||
From 7ffd8f9b54c49e61deada1efc00cfced7616c275 Mon Sep 17 00:00:00 2001
|
||||
From: Donat Zenichev <dzenichev@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:31 +0100
|
||||
Subject: MT#55831 Detect emergency calls and let them pass on license limitation (SEMS CE)
|
||||
|
||||
Remark: this commit is created as an attempt to keep PRO / CE sems repositories
|
||||
consistent in terms of the provided code and functionality.
|
||||
|
||||
We need to have a possibility to detect emergency calls and let them
|
||||
pass through the SEMS, even if the license limitation (CPSLimit) is triggered.
|
||||
|
||||
Also taking into account the global policy defined by the cfg parameter
|
||||
'skip_cpslimit_emergency'.
|
||||
If set to 'yes' (in the code will be treated as True)
|
||||
then we do not drop emergency calls on CPSLimit triggering.
|
||||
If set to 'no' - we treat emergency calls
|
||||
as if they were usual calls in terms of checking CPSLimit license limitation.
|
||||
(real ticket number: TT#138356)
|
||||
|
||||
--- a/core/AmConfig.cpp
|
||||
+++ b/core/AmConfig.cpp
|
||||
@@ -125,6 +125,8 @@ bool AmConfig::AcceptForkedDialo
|
||||
bool AmConfig::ShutdownMode = false;
|
||||
unsigned int AmConfig::ShutdownModeErrCode = 503;
|
||||
string AmConfig::ShutdownModeErrReason = "Server shutting down";
|
||||
+
|
||||
+bool AmConfig::skip_cpslimit_emergency = true;
|
||||
|
||||
string AmConfig::OptionsTranscoderOutStatsHdr; // empty by default
|
||||
string AmConfig::OptionsTranscoderInStatsHdr; // empty by default
|
||||
@@ -458,6 +460,11 @@ int AmConfig::readConfiguration()
|
||||
}
|
||||
}
|
||||
|
||||
+ // skip_cpslimit_emergency = true - do not drop emergency calls on CPSLimit
|
||||
+ // skip_cpslimit_emergency = false - drop emergency calls on CPSLimit
|
||||
+ if (cfg.hasParameter("skip_cpslimit_emergency"))
|
||||
+ skip_cpslimit_emergency = cfg.getParameter("skip_cpslimit_emergency")=="yes";
|
||||
+
|
||||
if(cfg.hasParameter("log_sessions"))
|
||||
LogSessions = cfg.getParameter("log_sessions")=="yes";
|
||||
|
||||
--- a/core/AmConfig.h
|
||||
+++ b/core/AmConfig.h
|
||||
@@ -281,6 +281,9 @@ struct AmConfig
|
||||
|
||||
static AmAudio::ResamplingImplementationType ResamplingImplementationType;
|
||||
|
||||
+ /* Global policy for treating emergency calls on CPSLimit triggering */
|
||||
+ static bool skip_cpslimit_emergency;
|
||||
+
|
||||
/** Read global configuration file and insert values. Maybe overwritten by
|
||||
* command line arguments */
|
||||
static int readConfiguration();
|
||||
--- a/core/AmSessionContainer.cpp
|
||||
+++ b/core/AmSessionContainer.cpp
|
||||
@@ -444,13 +444,25 @@ unsigned int AmSessionContainer::getMaxC
|
||||
return res;
|
||||
}
|
||||
|
||||
-bool AmSessionContainer::check_and_add_cps()
|
||||
+// we need the emergency_flag to mark emergency calls
|
||||
+// and skip checking CPSLimit for them if the global policy is so
|
||||
+// emergency_flag = True - do not run CPSLimit check for the call
|
||||
+// emergency_flag = False - run CPSLimit check for the call
|
||||
+bool AmSessionContainer::check_and_add_cps(bool emergency_flag)
|
||||
{
|
||||
struct timeval tv, res;
|
||||
gettimeofday(&tv,0);
|
||||
|
||||
AmLock lock(cps_mut);
|
||||
|
||||
+ // check global policy for dropping emergency calls
|
||||
+ if (!AmConfig::skip_cpslimit_emergency && emergency_flag) {
|
||||
+ emergency_flag = AmConfig::skip_cpslimit_emergency;
|
||||
+ DBG("Emergency call detected, but global policy is to do the CPSLimit check (license).\n");
|
||||
+ }
|
||||
+
|
||||
+ if (emergency_flag) DBG("Emergency call detected, skip CPSLimit check (license).\n");
|
||||
+
|
||||
while (cps_queue.size()) {
|
||||
timersub(&tv, &cps_queue.front(), &res);
|
||||
if (res.tv_sec >= CPS_SAMPLERATE) {
|
||||
@@ -466,7 +478,7 @@ bool AmSessionContainer::check_and_add_c
|
||||
max_cps = cps;
|
||||
}
|
||||
|
||||
- if( CPSLimit && cps > CPSLimit ){
|
||||
+ if( CPSLimit && cps > CPSLimit && !emergency_flag){
|
||||
DBG("cps_limit %d reached. Not creating session.\n", CPSLimit);
|
||||
return true;
|
||||
}
|
||||
@@ -500,7 +512,20 @@ AmSession* AmSessionContainer::createSes
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- if (check_and_add_cps()) {
|
||||
+ map<string,string> app_params;
|
||||
+ parse_app_params(req.hdrs,app_params);
|
||||
+
|
||||
+ // look into P-App-Param list, try to find 'emergency' marker
|
||||
+ emergency_flag = false;
|
||||
+ map<string, string>::iterator it;
|
||||
+
|
||||
+ it = app_params.find(EMERGENCY_PARAM);
|
||||
+ if (it != app_params.end() && (it->first == EMERGENCY_PARAM && it->second == "1")) {
|
||||
+ DBG("Emergency parameter detected: <;%s=%s> .\n", it->first.c_str(), it->second.c_str());
|
||||
+ emergency_flag = true;
|
||||
+ }
|
||||
+
|
||||
+ if (check_and_add_cps(emergency_flag)) {
|
||||
AmSipDialog::reply_error(req,AmConfig::CPSLimitErrCode,
|
||||
AmConfig::CPSLimitErrReason);
|
||||
return NULL;
|
||||
@@ -520,9 +545,6 @@ AmSession* AmSessionContainer::createSes
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- map<string,string> app_params;
|
||||
- parse_app_params(req.hdrs,app_params);
|
||||
-
|
||||
AmSession* session = NULL;
|
||||
if (req.method == "INVITE") {
|
||||
if (NULL != session_params) {
|
||||
--- a/core/AmSessionContainer.h
|
||||
+++ b/core/AmSessionContainer.h
|
||||
@@ -37,6 +37,8 @@
|
||||
#include <queue>
|
||||
#include <map>
|
||||
|
||||
+#define EMERGENCY_PARAM "emergency"
|
||||
+
|
||||
using std::string;
|
||||
|
||||
/**
|
||||
@@ -96,7 +98,8 @@ class AmSessionContainer : public AmThre
|
||||
unsigned int CPSLimit;
|
||||
unsigned int CPSHardLimit;
|
||||
|
||||
- bool check_and_add_cps();
|
||||
+ bool check_and_add_cps(bool emergency_flag);
|
||||
+ bool emergency_flag;
|
||||
|
||||
public:
|
||||
static AmSessionContainer* instance();
|
||||
@ -1,333 +0,0 @@
|
||||
From 087e126e607c0ec6215cbef7fd47ab29deadd0d0 Mon Sep 17 00:00:00 2001
|
||||
From: Fabricio Santolin <fabricio.santolin-da-silva@al-enterprise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:28 +0100
|
||||
Subject: MT#55831 Authorization header format support
|
||||
|
||||
Authorization header format support
|
||||
(real ticket number: TT#82409)
|
||||
|
||||
--- a/apps/reg_agent/RegistrationAgent.cpp
|
||||
+++ b/apps/reg_agent/RegistrationAgent.cpp
|
||||
@@ -138,10 +138,10 @@ void RegThread::create_registration(RegI
|
||||
di_args.push("reg_agent"); //sess_link
|
||||
di_args.push(ri.proxy.c_str());
|
||||
di_args.push(ri.contact.c_str());
|
||||
-
|
||||
+
|
||||
registrar_client_i->invoke("createRegistration", di_args, reg_handle);
|
||||
if (reg_handle.size())
|
||||
- ri.handle = reg_handle.get(0).asCStr();
|
||||
+ ri.handle = reg_handle.get(0).asCStr();
|
||||
}
|
||||
}
|
||||
}
|
||||
--- a/core/AmUACAuth.cpp
|
||||
+++ b/core/AmUACAuth.cpp
|
||||
@@ -7,8 +7,6 @@ UACAuthCred::UACAuthCred(const string& r
|
||||
const string& pwd)
|
||||
: realm(realm), user(user), pwd(pwd) { }
|
||||
|
||||
-
|
||||
-
|
||||
AmUACAuth::AmUACAuth() { }
|
||||
|
||||
AmUACAuth::~AmUACAuth() { }
|
||||
--- a/core/ampi/UACAuthAPI.h
|
||||
+++ b/core/ampi/UACAuthAPI.h
|
||||
@@ -48,10 +48,11 @@ class UACAuthCred
|
||||
string pwd;
|
||||
UACAuthCred();
|
||||
UACAuthCred(const string& realm,
|
||||
- const string& user,
|
||||
- const string& pwd);
|
||||
+ const string& user,
|
||||
+ const string& pwd);
|
||||
};
|
||||
|
||||
+
|
||||
class CredentialHolder
|
||||
: public virtual AmObject {
|
||||
public:
|
||||
--- a/apps/db_reg_agent/DBRegAgent.cpp
|
||||
+++ b/apps/db_reg_agent/DBRegAgent.cpp
|
||||
@@ -312,22 +312,24 @@ bool DBRegAgent::loadRegistrations() {
|
||||
case REG_STATUS_FAILED: // try again
|
||||
{
|
||||
createRegistration(subscriber_id,
|
||||
- (string)row[COLNAME_USER],
|
||||
- (string)row[COLNAME_PASS],
|
||||
- (string)row[COLNAME_REALM],
|
||||
- contact_uri
|
||||
- );
|
||||
+ (string)row[COLNAME_AUTH_USER],
|
||||
+ (string)row[COLNAME_USER],
|
||||
+ (string)row[COLNAME_PASS],
|
||||
+ (string)row[COLNAME_REALM],
|
||||
+ contact_uri
|
||||
+ );
|
||||
scheduleRegistration(subscriber_id);
|
||||
}; break;
|
||||
|
||||
case REG_STATUS_ACTIVE:
|
||||
{
|
||||
createRegistration(subscriber_id,
|
||||
- (string)row[COLNAME_USER],
|
||||
- (string)row[COLNAME_PASS],
|
||||
- (string)row[COLNAME_REALM],
|
||||
- contact_uri
|
||||
- );
|
||||
+ (string)row[COLNAME_AUTH_USER],
|
||||
+ (string)row[COLNAME_USER],
|
||||
+ (string)row[COLNAME_PASS],
|
||||
+ (string)row[COLNAME_REALM],
|
||||
+ contact_uri
|
||||
+ );
|
||||
|
||||
time_t dt_expiry = now_time;
|
||||
if (row[COLNAME_EXPIRY] != mysqlpp::null) {
|
||||
@@ -368,11 +370,12 @@ bool DBRegAgent::loadRegistrations() {
|
||||
DBG("Scheduling Deregister of registration %ld %s@%s", subscriber_id,
|
||||
((string)row[COLNAME_USER]).c_str(), ((string)row[COLNAME_REALM]).c_str());
|
||||
createRegistration(subscriber_id,
|
||||
- (string)row[COLNAME_USER],
|
||||
- (string)row[COLNAME_PASS],
|
||||
- (string)row[COLNAME_REALM],
|
||||
- contact_uri
|
||||
- );
|
||||
+ (string)row[COLNAME_AUTH_USER],
|
||||
+ (string)row[COLNAME_USER],
|
||||
+ (string)row[COLNAME_PASS],
|
||||
+ (string)row[COLNAME_REALM],
|
||||
+ contact_uri
|
||||
+ );
|
||||
scheduleDeregistration(subscriber_id);
|
||||
};
|
||||
}
|
||||
@@ -390,12 +393,14 @@ bool DBRegAgent::loadRegistrations() {
|
||||
|
||||
/** create registration in our list */
|
||||
void DBRegAgent::createRegistration(long subscriber_id,
|
||||
- const string& user,
|
||||
- const string& pass,
|
||||
- const string& realm,
|
||||
- const string& contact) {
|
||||
+ const string& auth_user,
|
||||
+ const string& user,
|
||||
+ const string& pass,
|
||||
+ const string& realm,
|
||||
+ const string& contact) {
|
||||
+
|
||||
+ string auth_user_temp = auth_user.empty() ? user : auth_user;
|
||||
|
||||
- string auth_user = user;
|
||||
string _user = user;
|
||||
if (username_with_domain && user.find('@')!=string::npos) {
|
||||
_user = user.substr(0, user.find('@'));
|
||||
@@ -409,12 +414,15 @@ void DBRegAgent::createRegistration(long
|
||||
string handle = AmSession::getNewId();
|
||||
SIPRegistrationInfo reg_info(realm, _user,
|
||||
_user, // name
|
||||
- auth_user,
|
||||
+ auth_user_temp, // auth_user
|
||||
pass,
|
||||
outbound_proxy, // proxy
|
||||
contact_uri // contact
|
||||
);
|
||||
|
||||
+DBG(" >>> realm '%s' - user '%s' - auth_user '%s' - pass: '%s' outbound_proxy '%s' contact_uri '%s'\n",
|
||||
+ realm.c_str(), _user.c_str(), auth_user.c_str(), pass.c_str(), outbound_proxy.c_str(), contact_uri.c_str());
|
||||
+
|
||||
registrations_mut.lock();
|
||||
try {
|
||||
if (registrations.find(subscriber_id) != registrations.end()) {
|
||||
@@ -471,12 +479,14 @@ void DBRegAgent::createRegistration(long
|
||||
}
|
||||
|
||||
void DBRegAgent::updateRegistration(long subscriber_id,
|
||||
+ const string& auth_user,
|
||||
const string& user,
|
||||
const string& pass,
|
||||
const string& realm,
|
||||
const string& contact) {
|
||||
|
||||
- string auth_user = user;
|
||||
+ string auth_user_temp = auth_user.empty() ? user : auth_user;
|
||||
+
|
||||
string _user = user;
|
||||
if (username_with_domain && user.find('@')!=string::npos) {
|
||||
_user = user.substr(0, user.find('@'));
|
||||
@@ -488,12 +498,13 @@ void DBRegAgent::updateRegistration(long
|
||||
registrations_mut.unlock();
|
||||
WARN("updateRegistration - registration %ld %s@%s unknown, creating\n",
|
||||
subscriber_id, _user.c_str(), realm.c_str());
|
||||
- createRegistration(subscriber_id, _user, pass, realm, contact);
|
||||
+ createRegistration(subscriber_id, auth_user_temp, _user, pass, realm, contact);
|
||||
scheduleRegistration(subscriber_id);
|
||||
return;
|
||||
}
|
||||
|
||||
bool need_reregister = it->second->getInfo().domain != realm
|
||||
+ || it->second->getInfo().auth_user != auth_user_temp
|
||||
|| it->second->getInfo().user != _user
|
||||
|| it->second->getInfo().pwd != pass
|
||||
|| it->second->getInfo().contact != contact;
|
||||
@@ -502,7 +513,7 @@ void DBRegAgent::updateRegistration(long
|
||||
string old_user = it->second->getInfo().user;
|
||||
it->second->setRegistrationInfo(SIPRegistrationInfo(realm, _user,
|
||||
_user, // name
|
||||
- auth_user,
|
||||
+ auth_user_temp, // auth_user
|
||||
pass,
|
||||
outbound_proxy, // proxy
|
||||
contact)); // contact
|
||||
@@ -1097,26 +1108,32 @@ void DBRegAgent::timer_cb(RegTimer* time
|
||||
}
|
||||
|
||||
|
||||
-void DBRegAgent::DIcreateRegistration(int subscriber_id, const string& user,
|
||||
+void DBRegAgent::DIcreateRegistration(int subscriber_id, const string& user,
|
||||
const string& pass, const string& realm,
|
||||
- const string& contact,
|
||||
+ const string& contact, const string& auth_user,
|
||||
AmArg& ret) {
|
||||
- DBG("DI method: createRegistration(%i, %s, %s, %s, %s)\n",
|
||||
- subscriber_id, user.c_str(),
|
||||
+
|
||||
+ string auth_user_temp = auth_user.empty() ? user : auth_user;
|
||||
+
|
||||
+ DBG("DI method: createRegistration(%i, %s, %s, %s, %s, %s)\n",
|
||||
+ subscriber_id, auth_user_temp.c_str(), user.c_str(),
|
||||
pass.c_str(), realm.c_str(), contact.c_str());
|
||||
|
||||
- createRegistration(subscriber_id, user, pass, realm, contact);
|
||||
+ createRegistration(subscriber_id, auth_user_temp, user, pass, realm, contact);
|
||||
scheduleRegistration(subscriber_id);
|
||||
ret.push(200);
|
||||
ret.push("OK");
|
||||
}
|
||||
|
||||
-void DBRegAgent::DIupdateRegistration(int subscriber_id, const string& user,
|
||||
+void DBRegAgent::DIupdateRegistration(int subscriber_id, const string& user,
|
||||
const string& pass, const string& realm,
|
||||
- const string& contact,
|
||||
+ const string& contact, const string& auth_user,
|
||||
AmArg& ret) {
|
||||
- DBG("DI method: updateRegistration(%i, %s, %s, %s)\n",
|
||||
- subscriber_id, user.c_str(),
|
||||
+
|
||||
+ string auth_user_temp = auth_user.empty() ? user : auth_user;
|
||||
+
|
||||
+ DBG("DI method: updateRegistration(%i, %s, %s, %s, %s)\n",
|
||||
+ subscriber_id, auth_user_temp.c_str(), user.c_str(),
|
||||
pass.c_str(), realm.c_str());
|
||||
|
||||
string contact_uri = contact;
|
||||
@@ -1124,7 +1141,7 @@ void DBRegAgent::DIupdateRegistration(in
|
||||
contact_uri = "sip:"+ user + "@" + contact_hostport;
|
||||
}
|
||||
|
||||
- updateRegistration(subscriber_id, user, pass, realm, contact_uri);
|
||||
+ updateRegistration(subscriber_id, auth_user_temp, user, pass, realm, contact_uri);
|
||||
|
||||
ret.push(200);
|
||||
ret.push("OK");
|
||||
@@ -1157,25 +1174,35 @@ void DBRegAgent::invoke(const string& me
|
||||
const AmArg& args, AmArg& ret)
|
||||
{
|
||||
if (method == "createRegistration"){
|
||||
- args.assertArrayFmt("isss"); // subscriber_id, user, pass, realm
|
||||
+ args.assertArrayFmt("issss"); // subscriber_id, user, pass, realm , auth_user
|
||||
string contact;
|
||||
- if (args.size() > 4) {
|
||||
+ string auth_user;
|
||||
+ if (args.size() == 5) {
|
||||
assertArgCStr(args.get(4));
|
||||
contact = args.get(4).asCStr();
|
||||
+ } else if (args.size() > 5) {
|
||||
+ assertArgCStr(args.get(4));
|
||||
+ assertArgCStr(args.get(5));
|
||||
+ contact = args.get(4).asCStr();
|
||||
+ auth_user = args.get(5).asCStr();
|
||||
}
|
||||
- DIcreateRegistration(args.get(0).asInt(), args.get(1).asCStr(),
|
||||
- args.get(2).asCStr(),args.get(3).asCStr(),
|
||||
- contact, ret);
|
||||
+ DIcreateRegistration(args.get(0).asInt(), args.get(1).asCStr(),
|
||||
+ args.get(2).asCStr(), args.get(3).asCStr(), contact, auth_user, ret);
|
||||
} else if (method == "updateRegistration"){
|
||||
- args.assertArrayFmt("isss"); // subscriber_id, user, pass, realm
|
||||
+ args.assertArrayFmt("issss"); // subscriber_id, auth_user, user, pass, realm
|
||||
string contact;
|
||||
- if (args.size() > 4) {
|
||||
+ string auth_user;
|
||||
+ if (args.size() == 5) {
|
||||
+ assertArgCStr(args.get(4));
|
||||
+ contact = args.get(4).asCStr();
|
||||
+ } else if (args.size() > 5) {
|
||||
assertArgCStr(args.get(4));
|
||||
+ assertArgCStr(args.get(5));
|
||||
contact = args.get(4).asCStr();
|
||||
+ auth_user = args.get(5).asCStr();
|
||||
}
|
||||
DIupdateRegistration(args.get(0).asInt(), args.get(1).asCStr(),
|
||||
- args.get(2).asCStr(),args.get(3).asCStr(),
|
||||
- contact, ret);
|
||||
+ args.get(2).asCStr(), args.get(3).asCStr(), contact, auth_user, ret);
|
||||
} else if (method == "removeRegistration"){
|
||||
args.assertArrayFmt("i"); // subscriber_id
|
||||
DIremoveRegistration(args.get(0).asInt(), ret);
|
||||
--- a/apps/db_reg_agent/DBRegAgent.h
|
||||
+++ b/apps/db_reg_agent/DBRegAgent.h
|
||||
@@ -55,6 +55,7 @@ using std::queue;
|
||||
#define REG_STATUS_TO_BE_REMOVED_S "5"
|
||||
|
||||
#define COLNAME_SUBSCRIBER_ID "subscriber_id"
|
||||
+#define COLNAME_AUTH_USER "auth_user"
|
||||
#define COLNAME_USER "user"
|
||||
#define COLNAME_PASS "pass"
|
||||
#define COLNAME_REALM "realm"
|
||||
@@ -182,16 +183,18 @@ class DBRegAgent
|
||||
|
||||
/** create registration in our list */
|
||||
void createRegistration(long subscriber_id,
|
||||
- const string& user,
|
||||
- const string& pass,
|
||||
- const string& realm,
|
||||
- const string& contact);
|
||||
+ const string& auth_user,
|
||||
+ const string& user,
|
||||
+ const string& pass,
|
||||
+ const string& realm,
|
||||
+ const string& contact);
|
||||
/** update registration in our list */
|
||||
void updateRegistration(long subscriber_id,
|
||||
- const string& user,
|
||||
- const string& pass,
|
||||
- const string& realm,
|
||||
- const string& contact);
|
||||
+ const string& auth_user,
|
||||
+ const string& user,
|
||||
+ const string& pass,
|
||||
+ const string& realm,
|
||||
+ const string& contact);
|
||||
|
||||
/** remove registration */
|
||||
void removeRegistration(long subscriber_id);
|
||||
@@ -245,12 +248,12 @@ class DBRegAgent
|
||||
|
||||
AmDynInvoke* uac_auth_i;
|
||||
|
||||
- void DIcreateRegistration(int subscriber_id, const string& user,
|
||||
- const string& pass, const string& realm,
|
||||
- const string& contact, AmArg& ret);
|
||||
+ void DIcreateRegistration(int subscriber_id, const string& user,
|
||||
+ const string& pass, const string& realm,
|
||||
+ const string& contact, const string& auth_user, AmArg& ret);
|
||||
void DIupdateRegistration(int subscriber_id, const string& user,
|
||||
- const string& pass, const string& realm,
|
||||
- const string& contact, AmArg& ret);
|
||||
+ const string& pass, const string& realm,
|
||||
+ const string& contact, const string& auth_user, AmArg& ret);
|
||||
void DIremoveRegistration(int subscriber_id, AmArg& ret);
|
||||
void DIrefreshRegistration(int subscriber_id, AmArg& ret);
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
From b3a3ab6f636394ea214e1f27a1d3702b8c714189 Mon Sep 17 00:00:00 2001
|
||||
From: Donat Zenichev <dzenichev@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:33 +0100
|
||||
Subject: MT#55831 DSM: ModCurl - fix ordered comparison of const ptr with 0 (CE)
|
||||
|
||||
We don't have to compare a const char pointer with '>' / '<' operands
|
||||
agains 0.
|
||||
|
||||
The conditional code will not get executed, if 'data->version' is null -
|
||||
but not that it will, if it's not null.
|
||||
|
||||
We should use a classical check for null pointers agains 0 using '!=',
|
||||
this has the least potential for subtle bugs, and is guaranteed to be portable.
|
||||
(real ticket number: MT#55816)
|
||||
|
||||
--- a/apps/dsm/mods/mod_curl/ModCurl.cpp
|
||||
+++ b/apps/dsm/mods/mod_curl/ModCurl.cpp
|
||||
@@ -41,20 +41,23 @@ SC_EXPORT(CurlModule);
|
||||
|
||||
CurlModule::CurlModule() {
|
||||
if (!curl_initialized) {
|
||||
+
|
||||
curl_initialized = true;
|
||||
+
|
||||
if (curl_global_init(CURL_GLOBAL_ALL)) {
|
||||
ERROR("Initializing libcurl\n");
|
||||
- throw string("Initializing libcurl");
|
||||
+ throw std::runtime_error("Initializing libcurl");
|
||||
}
|
||||
|
||||
curl_version_info_data *data = curl_version_info(CURLVERSION_NOW);
|
||||
- if (data && data->version >=0) {
|
||||
- DBG("using libcurl version '%s'\n",
|
||||
- data->version);
|
||||
+
|
||||
+ if (data && 0 != data->version) {
|
||||
+ DBG("using libcurl version '%s'\n", data->version);
|
||||
+
|
||||
if (data->features & CURL_VERSION_SSL) {
|
||||
- DBG("libcurl with SSL version '%s'\n", data->ssl_version);
|
||||
+ DBG("libcurl with SSL version '%s'\n", data->ssl_version);
|
||||
} else {
|
||||
- DBG("libcurl without SSL support\n");
|
||||
+ DBG("libcurl without SSL support\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,65 +0,0 @@
|
||||
From 2d0775b77c60c8536ecb49302b794a2a36a25a92 Mon Sep 17 00:00:00 2001
|
||||
From: Donat Zenichev <dzenichev@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:32 +0100
|
||||
Subject: MT#55831 dsm: ModUtils, fix the work of utils_get_count_files() (CE)
|
||||
|
||||
We need to rework the utils_get_count_files(), because it improperly
|
||||
treats the given list of numbers, especially what relates to zeroes.
|
||||
|
||||
Previous approach gets deprecated, and another approach is applied.
|
||||
(real ticket number: TT#143150)
|
||||
|
||||
--- a/apps/dsm/mods/mod_utils/ModUtils.cpp
|
||||
+++ b/apps/dsm/mods/mod_utils/ModUtils.cpp
|
||||
@@ -72,20 +72,32 @@ vector<string> utils_get_count_files(DSM
|
||||
|
||||
vector<string> res;
|
||||
|
||||
+ unsigned int number = cnt;
|
||||
+ unsigned int n = log10(number) + 1;
|
||||
+ const int max = 9;
|
||||
+
|
||||
+ string full_number = std::to_string(number);
|
||||
+ string remainder; /* what remains after 9 digits, if remains */
|
||||
+ bool remainder_exists = false;
|
||||
+
|
||||
if (cnt <= 20) {
|
||||
res.push_back(basedir+int2str(cnt)+suffix);
|
||||
return res;
|
||||
}
|
||||
-
|
||||
- for (int i=9;i>1;i--) {
|
||||
- div_t num = div(cnt, (int)pow(10.,i));
|
||||
- if (num.quot) {
|
||||
- res.push_back(basedir+int2str(int(num.quot * pow(10.,i)))+suffix);
|
||||
- }
|
||||
- cnt = num.rem;
|
||||
+
|
||||
+ if (n > max) {
|
||||
+ remainder_exists = true;
|
||||
+ remainder = full_number.substr(max);
|
||||
+ cnt = std::stoi(remainder);
|
||||
+ }
|
||||
+
|
||||
+ for (int i = n; i > 0; i--) {
|
||||
+ int num = (int)((number % (unsigned int)pow(10, i)) / pow(10, i - 1));
|
||||
+ if ( (n - i) < max )
|
||||
+ res.push_back(basedir+int2str(num)+suffix); /* only push until max amount here */
|
||||
}
|
||||
|
||||
- if (!cnt)
|
||||
+ if (!remainder_exists)
|
||||
return res;
|
||||
|
||||
if ((cnt <= 20) || (!(cnt%10))) {
|
||||
--- a/apps/dsm/mods/mod_utils/ModUtils.h
|
||||
+++ b/apps/dsm/mods/mod_utils/ModUtils.h
|
||||
@@ -31,6 +31,8 @@
|
||||
#include "AmRingTone.h"
|
||||
#include "DSMSession.h"
|
||||
|
||||
+#include <string>
|
||||
+
|
||||
#define MOD_CLS_NAME SCUtilsModule
|
||||
|
||||
DECLARE_MODULE(MOD_CLS_NAME);
|
||||
@ -1,24 +0,0 @@
|
||||
From 38ad6c8d75fa9e0f3ebcc6320272dd5252505c5f Mon Sep 17 00:00:00 2001
|
||||
From: Marco Capetta <mcapetta@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:25 +0100
|
||||
Subject: MT#55831 Handle BYE after 180 with to_tag
|
||||
|
||||
- customer has a scenario when 180 has to_tag and call terminated by caller with BYE but calle did not get any call termination signalling.
|
||||
- a bit more special for such cases BYE handling added.
|
||||
(real ticket number: TT#73957)
|
||||
|
||||
--- a/apps/sbc/CallLeg.cpp
|
||||
+++ b/apps/sbc/CallLeg.cpp
|
||||
@@ -961,7 +961,11 @@ void CallLeg::onSipRequest(const AmSipRe
|
||||
}
|
||||
}
|
||||
else {
|
||||
- if(getCallStatus() == Disconnected &&
|
||||
+ if (getCallStatus() == Ringing && !getOtherId().empty() && req.method == SIP_METH_BYE) {
|
||||
+ dlg->reply(req,200,"OK");
|
||||
+ stopCall(&req);
|
||||
+ }
|
||||
+ else if(getCallStatus() == Disconnected &&
|
||||
req.method == SIP_METH_BYE) {
|
||||
// seems that we have already sent/received a BYE
|
||||
// -> we'd better terminate this ASAP
|
||||
@ -1,104 +0,0 @@
|
||||
From d0d4dc33c2097979deb35464749ec4601d68547b Mon Sep 17 00:00:00 2001
|
||||
From: Marco Capetta <mcapetta@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:21 +0100
|
||||
Subject: MT#55831 Fix issue if an UPDATE is received after 183
|
||||
|
||||
If an SDP UPDATE is received after the 183, but before the 200,
|
||||
SEMS fails when it receive the final ACK. In fact SEMS tries to
|
||||
find the SDP content inside the ACK message itself.
|
||||
|
||||
The solution is copied from sems-pbx module where the issue
|
||||
doesn't happen.
|
||||
(real ticket number: TT#43503)
|
||||
|
||||
--- a/core/AmOfferAnswer.cpp
|
||||
+++ b/core/AmOfferAnswer.cpp
|
||||
@@ -53,7 +53,8 @@ AmOfferAnswer::AmOfferAnswer(AmSipDialog
|
||||
cseq(0),
|
||||
sdp_remote(),
|
||||
sdp_local(),
|
||||
- dlg(dlg)
|
||||
+ dlg(dlg),
|
||||
+ force_sdp(true)
|
||||
{
|
||||
|
||||
}
|
||||
@@ -322,7 +323,7 @@ int AmOfferAnswer::onRequestOut(AmSipReq
|
||||
sdp_buf.length());
|
||||
has_sdp = true;
|
||||
}
|
||||
- else {
|
||||
+ else if(force_sdp) {
|
||||
return -1;
|
||||
}
|
||||
} else if (sdp_body && has_sdp) {
|
||||
@@ -395,7 +396,7 @@ int AmOfferAnswer::onReplyOut(AmSipReply
|
||||
else if (reply.code == 200 && reply.cseq_method == SIP_METH_INVITE && state == OA_Completed) {
|
||||
// just ignore if no SDP is generated (required for B2B)
|
||||
}
|
||||
- else return -1;
|
||||
+ else if(force_sdp) return -1;
|
||||
}
|
||||
else {
|
||||
if(!sdp_body){
|
||||
--- a/apps/sbc/CallLeg.cpp
|
||||
+++ b/apps/sbc/CallLeg.cpp
|
||||
@@ -197,7 +197,10 @@ CallLeg::CallLeg(const CallLeg* caller,
|
||||
set_sip_relay_only(false); // will be changed later on (for now we have no peer so we can't relay)
|
||||
|
||||
// enable OA for the purpose of hold request detection
|
||||
- if (dlg) dlg->setOAEnabled(true);
|
||||
+ if (dlg) {
|
||||
+ dlg->setOAEnabled(true);
|
||||
+ dlg->setOAForceSDP(false);
|
||||
+ }
|
||||
else WARN("can't enable OA!\n");
|
||||
|
||||
// code below taken from createCalleeSession
|
||||
@@ -259,7 +262,10 @@ CallLeg::CallLeg(AmSipDialog* p_dlg, AmS
|
||||
set_sip_relay_only(false);
|
||||
|
||||
// enable OA for the purpose of hold request detection
|
||||
- if (dlg) dlg->setOAEnabled(true);
|
||||
+ if (dlg) {
|
||||
+ dlg->setOAEnabled(true);
|
||||
+ dlg->setOAForceSDP(false);
|
||||
+ }
|
||||
else WARN("can't enable OA!\n");
|
||||
}
|
||||
|
||||
--- a/core/AmOfferAnswer.h
|
||||
+++ b/core/AmOfferAnswer.h
|
||||
@@ -53,6 +53,9 @@ private:
|
||||
|
||||
AmSipDialog* dlg;
|
||||
|
||||
+ /** Should SDP generation be forced when not required by standards? */
|
||||
+ bool force_sdp;
|
||||
+
|
||||
/** State maintenance */
|
||||
void saveState();
|
||||
int checkStateChange();
|
||||
@@ -75,6 +78,9 @@ public:
|
||||
void clear();
|
||||
void clearTransitionalState();
|
||||
|
||||
+ void setForceSDP(bool force) { force_sdp = force; }
|
||||
+ bool getForceSDP() const { return force_sdp; }
|
||||
+
|
||||
/** Event handlers */
|
||||
int onRequestIn(const AmSipRequest& req);
|
||||
int onReplyIn(const AmSipReply& reply);
|
||||
--- a/core/AmSipDialog.h
|
||||
+++ b/core/AmSipDialog.h
|
||||
@@ -95,6 +95,10 @@ protected:
|
||||
AmOfferAnswer::OAState getOAState();
|
||||
void setOAState(AmOfferAnswer::OAState n_st);
|
||||
void setOAEnabled(bool oa_enabled);
|
||||
+
|
||||
+ void setOAForceSDP(bool force) { oa.setForceSDP(force); }
|
||||
+ bool getOAForceSDP() const { return oa.getForceSDP(); }
|
||||
+
|
||||
const AmSdp& getLocalSdp() { return oa.getLocalSdp(); }
|
||||
const AmSdp& getRemoteSdp() { return oa.getRemoteSdp(); }
|
||||
|
||||
@ -1,957 +0,0 @@
|
||||
From ef4a7b95cf479acc107792e265d626a6c23bd736 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Prokop <mprokop@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:27 +0100
|
||||
Subject: MT#55831 Build and include SBC tools + examples, port to py3k
|
||||
|
||||
Otherwise we're missing plenty of audio files in /usr/lib/ngcp-sems/audio/,
|
||||
several plugins in /usr/lib/ngcp-sems/plug-in/, as well as a bunch of binaries:
|
||||
|
||||
* /usr/sbin/ngcp-sems-get-callproperties
|
||||
* /usr/sbin/ngcp-sems-list-active-calls
|
||||
* /usr/sbin/ngcp-sems-list-calls
|
||||
* /usr/sbin/ngcp-sems-list-finished-calls
|
||||
* /usr/sbin/ngcp-sems-sbc-get-activeprofile
|
||||
* /usr/sbin/ngcp-sems-sbc-get-regex-map-names
|
||||
* /usr/sbin/ngcp-sems-sbc-list-profiles
|
||||
* /usr/sbin/ngcp-sems-sbc-load-callcontrol-modules
|
||||
* /usr/sbin/ngcp-sems-sbc-load-profile
|
||||
* /usr/sbin/ngcp-sems-sbc-reload-profile
|
||||
* /usr/sbin/ngcp-sems-sbc-reload-profiles
|
||||
* /usr/sbin/ngcp-sems-sbc-set-activeprofile
|
||||
* /usr/sbin/ngcp-sems-sbc-set-regex-map
|
||||
* /usr/sbin/ngcp-sems-sbc-teardown-call
|
||||
* /usr/sbin/ngcp-sems-webconference-addparticipant
|
||||
* /usr/sbin/ngcp-sems-webconference-roomcreate
|
||||
* /usr/sbin/ngcp-sems-webconference-roominfo
|
||||
|
||||
This fixes a regression introduced in commit 1619876f76d (TT#101059).
|
||||
|
||||
Ported the python2 scripts we ship with our Debian package to python3
|
||||
(AKA py3k), fixed inconsistent use of tabs and spaces in indentation
|
||||
and indention in several files:
|
||||
|
||||
* apps/sbc/tools/sems-sbc-*
|
||||
* apps/examples/db_announce/announcement.py
|
||||
* apps/examples/py_sems_ex/*py
|
||||
|
||||
We're also not installing the *.pyc files (see
|
||||
apps/ivr/Makefile.ivr_application +
|
||||
apps/py_sems/Makefile.py_sems_application), they don't exist in py3k
|
||||
builds and it wouldn't make any sense to ship them in Debian packages
|
||||
anyway.
|
||||
(real ticket number: TT#105412)
|
||||
|
||||
--- a/apps/sbc/tools/sems-sbc-get-activeprofile
|
||||
+++ b/apps/sbc/tools/sems-sbc-get-activeprofile
|
||||
@@ -1,7 +1,7 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
-from xmlrpclib import *
|
||||
+from xmlrpc.client import *
|
||||
s = ServerProxy('http://localhost:8090')
|
||||
-print "Active calls: %d" % s.calls()
|
||||
-print s.di('sbc','getActiveProfile')
|
||||
+print("Active calls: %d" % s.calls())
|
||||
+print(s.di('sbc','getActiveProfile'))
|
||||
--- a/apps/sbc/tools/sems-sbc-get-regex-map-names
|
||||
+++ b/apps/sbc/tools/sems-sbc-get-regex-map-names
|
||||
@@ -1,7 +1,7 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
-from xmlrpclib import *
|
||||
+from xmlrpc.client import *
|
||||
|
||||
s = ServerProxy('http://localhost:8090')
|
||||
-print s.di('sbc','getRegexMapNames')
|
||||
+print(s.di('sbc','getRegexMapNames'))
|
||||
--- a/apps/sbc/tools/sems-sbc-list-profiles
|
||||
+++ b/apps/sbc/tools/sems-sbc-list-profiles
|
||||
@@ -1,7 +1,7 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
-from xmlrpclib import *
|
||||
+from xmlrpc.client import *
|
||||
s = ServerProxy('http://localhost:8090')
|
||||
-print "Active calls: %d" % s.calls()
|
||||
-print s.di('sbc','listProfiles')
|
||||
+print("Active calls: %d" % s.calls())
|
||||
+print(s.di('sbc','listProfiles'))
|
||||
--- a/apps/sbc/tools/sems-sbc-load-callcontrol-modules
|
||||
+++ b/apps/sbc/tools/sems-sbc-load-callcontrol-modules
|
||||
@@ -1,12 +1,12 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
-from xmlrpclib import *
|
||||
+from xmlrpc.client import *
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
- print "usage: %s <semicolon separated list of plugins to load>" % sys.argv[0]
|
||||
+ print("usage: %s <semicolon separated list of plugins to load>" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
s = ServerProxy('http://localhost:8090')
|
||||
-print "Active calls: %d" % s.calls()
|
||||
-print s.di('sbc','loadCallcontrolModules',sys.argv[1])
|
||||
+print("Active calls: %d" % s.calls())
|
||||
+print(s.di('sbc','loadCallcontrolModules',sys.argv[1]))
|
||||
--- a/apps/sbc/tools/sems-sbc-load-profile
|
||||
+++ b/apps/sbc/tools/sems-sbc-load-profile
|
||||
@@ -1,13 +1,13 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
-from xmlrpclib import *
|
||||
+from xmlrpc.client import *
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
- print "usage: %s <profile name> <full profile path>" % sys.argv[0]
|
||||
+ print("usage: %s <profile name> <full profile path>" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
s = ServerProxy('http://localhost:8090')
|
||||
-print "Active calls: %d" % s.calls()
|
||||
+print("Active calls: %d" % s.calls())
|
||||
p ={ 'name' : sys.argv[1], 'path' : sys.argv[2] }
|
||||
-print s.di('sbc','loadProfile',p)
|
||||
+print(s.di('sbc','loadProfile',p))
|
||||
--- a/apps/sbc/tools/sems-sbc-reload-profile
|
||||
+++ b/apps/sbc/tools/sems-sbc-reload-profile
|
||||
@@ -1,13 +1,13 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
-from xmlrpclib import *
|
||||
+from xmlrpc.client import *
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
- print "usage: %s <profile name>" % sys.argv[0]
|
||||
+ print("usage: %s <profile name>" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
s = ServerProxy('http://localhost:8090')
|
||||
-print "Active calls: %d" % s.calls()
|
||||
+print("Active calls: %d" % s.calls())
|
||||
p ={ 'name' : sys.argv[1] }
|
||||
-print s.di('sbc','reloadProfile',p)
|
||||
+print(s.di('sbc','reloadProfile',p))
|
||||
--- a/apps/sbc/tools/sems-sbc-reload-profiles
|
||||
+++ b/apps/sbc/tools/sems-sbc-reload-profiles
|
||||
@@ -1,7 +1,7 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
-from xmlrpclib import *
|
||||
+from xmlrpc.client import *
|
||||
s = ServerProxy('http://localhost:8090')
|
||||
-print s.calls()
|
||||
-print s.di('sbc','reloadProfiles')
|
||||
+print(s.calls())
|
||||
+print(s.di('sbc','reloadProfiles'))
|
||||
--- a/apps/sbc/tools/sems-sbc-set-activeprofile
|
||||
+++ b/apps/sbc/tools/sems-sbc-set-activeprofile
|
||||
@@ -1,12 +1,12 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
-from xmlrpclib import *
|
||||
+from xmlrpc.client import *
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
- print "usage: %s <profile name>" % sys.argv[0]
|
||||
+ print("usage: %s <profile name>" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
s = ServerProxy('http://localhost:8090')
|
||||
-print "Active calls: %d" % s.calls()
|
||||
-print s.di('sbc','setActiveProfile',sys.argv[1])
|
||||
+print("Active calls: %d" % s.calls())
|
||||
+print(s.di('sbc','setActiveProfile',sys.argv[1]))
|
||||
--- a/apps/sbc/tools/sems-sbc-set-regex-map
|
||||
+++ b/apps/sbc/tools/sems-sbc-set-regex-map
|
||||
@@ -1,13 +1,13 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
-from xmlrpclib import *
|
||||
+from xmlrpc.client import *
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
- print "usage: %s <regex map name> <full regex map path>" % sys.argv[0]
|
||||
+ print("usage: %s <regex map name> <full regex map path>" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
s = ServerProxy('http://localhost:8090')
|
||||
-print "Active calls: %d" % s.calls()
|
||||
+print("Active calls: %d" % s.calls())
|
||||
p ={ 'name' : sys.argv[1], 'file' : sys.argv[2] }
|
||||
-print s.di('sbc','setRegexMap',p)
|
||||
+print(s.di('sbc','setRegexMap',p))
|
||||
--- a/apps/sbc/tools/sems-sbc-teardown-call
|
||||
+++ b/apps/sbc/tools/sems-sbc-teardown-call
|
||||
@@ -1,19 +1,19 @@
|
||||
-#!/usr/bin/python
|
||||
+#!/usr/bin/python3
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys
|
||||
-from xmlrpclib import *
|
||||
+from xmlrpc.client import *
|
||||
|
||||
if len(sys.argv) != 2:
|
||||
- print "usage: %s <ltag/ID of call to tear down>" % sys.argv[0]
|
||||
+ print("usage: %s <ltag/ID of call to tear down>" % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
s = ServerProxy('http://localhost:8090')
|
||||
-print "Active calls: %d" % s.calls()
|
||||
+print("Active calls: %d" % s.calls())
|
||||
res = s.di('sbc', 'postControlCmd', sys.argv[1], "teardown")
|
||||
|
||||
if res[0] >= 200 and res[0] < 300:
|
||||
- print "OK"
|
||||
+ print("OK")
|
||||
sys.exit(0)
|
||||
else:
|
||||
- print "Error: %s" % str(res)
|
||||
+ print("Error: %s" % str(res))
|
||||
sys.exit(2)
|
||||
--- a/apps/examples/db_announce/announcement.py
|
||||
+++ b/apps/examples/db_announce/announcement.py
|
||||
@@ -9,62 +9,69 @@
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
# Use, copying, modification, and distribution without written
|
||||
-# permission is not allowed.
|
||||
+# permission is not allowed.
|
||||
|
||||
import os, MySQLdb
|
||||
|
||||
from log import *
|
||||
from ivr import *
|
||||
|
||||
-APPLICATION = 'announcement'
|
||||
+APPLICATION = "announcement"
|
||||
+
|
||||
+GREETING_MSG = "greeting_msg"
|
||||
|
||||
-GREETING_MSG = 'greeting_msg'
|
||||
|
||||
class IvrDialog(IvrDialogBase):
|
||||
|
||||
- DB_HOST = 'localhost'
|
||||
- DB_USER = 'sems'
|
||||
- DB_PASSWD = ''
|
||||
- DB_DB = 'sems'
|
||||
+ DB_HOST = "localhost"
|
||||
+ DB_USER = "sems"
|
||||
+ DB_PASSWD = ""
|
||||
+ DB_DB = "sems"
|
||||
|
||||
def __init__(self):
|
||||
|
||||
- try:
|
||||
- if config['mysql_server']:
|
||||
- self.DB_HOST = config['mysql_server']
|
||||
+ try:
|
||||
+ if config["mysql_server"]:
|
||||
+ self.DB_HOST = config["mysql_server"]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
- try:
|
||||
- if config['mysql_user']:
|
||||
- self.DB_USER = config['mysql_user']
|
||||
+ try:
|
||||
+ if config["mysql_user"]:
|
||||
+ self.DB_USER = config["mysql_user"]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
- try:
|
||||
- if config['mysql_passwd']:
|
||||
- self.DB_PASSWD = config['mysql_passwd']
|
||||
+ try:
|
||||
+ if config["mysql_passwd"]:
|
||||
+ self.DB_PASSWD = config["mysql_passwd"]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
- try:
|
||||
- if config['mysql_db']:
|
||||
- self.DB_DB = config['mysql_db']
|
||||
+ try:
|
||||
+ if config["mysql_db"]:
|
||||
+ self.DB_DB = config["mysql_db"]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
try:
|
||||
- self.db = MySQLdb.connect(host=self.DB_HOST,\
|
||||
- user=self.DB_USER,\
|
||||
- passwd=self.DB_PASSWD,\
|
||||
- db=self.DB_DB)
|
||||
- except MySQLdb.Error, e:
|
||||
- error(APPLICATION + ": cannot open database: " +\
|
||||
- str(e.args[0]) + ":" + e.args[1])
|
||||
+ self.db = MySQLdb.connect(
|
||||
+ host=self.DB_HOST,
|
||||
+ user=self.DB_USER,
|
||||
+ passwd=self.DB_PASSWD,
|
||||
+ db=self.DB_DB,
|
||||
+ )
|
||||
+ except MySQLdb.Error as e:
|
||||
+ error(
|
||||
+ APPLICATION
|
||||
+ + ": cannot open database: "
|
||||
+ + str(e.args[0])
|
||||
+ + ":"
|
||||
+ + e.args[1]
|
||||
+ )
|
||||
return False
|
||||
|
||||
self.audio = dict()
|
||||
-
|
||||
return True
|
||||
|
||||
def onSessionStart(self, hdrs):
|
||||
@@ -72,7 +79,7 @@
|
||||
if not self.__init__():
|
||||
self.bye()
|
||||
self.stopSession()
|
||||
-
|
||||
+
|
||||
self.language = getHeader(hdrs, "P-Language")
|
||||
|
||||
if not self.language:
|
||||
@@ -83,16 +90,16 @@
|
||||
return
|
||||
|
||||
self.enqueue(self.audio[GREETING_MSG], None)
|
||||
-
|
||||
+
|
||||
def onEmptyQueue(self):
|
||||
|
||||
if not self.queueIsEmpty():
|
||||
return
|
||||
-
|
||||
+
|
||||
self.sendBye()
|
||||
|
||||
return
|
||||
-
|
||||
+
|
||||
def onBye(self):
|
||||
|
||||
self.db.close()
|
||||
@@ -116,7 +123,17 @@
|
||||
|
||||
if start > 2:
|
||||
|
||||
- cursor.execute("SELECT audio FROM user_audio WHERE application='" + APPLICATION + "' AND message='" + msg + "' AND domain='" + self.dialog.domain + "' AND userid='" + self.dialog.user + "'")
|
||||
+ cursor.execute(
|
||||
+ "SELECT audio FROM user_audio WHERE application='"
|
||||
+ + APPLICATION
|
||||
+ + "' AND message='"
|
||||
+ + msg
|
||||
+ + "' AND domain='"
|
||||
+ + self.dialog.domain
|
||||
+ + "' AND userid='"
|
||||
+ + self.dialog.user
|
||||
+ + "'"
|
||||
+ )
|
||||
|
||||
if cursor.rowcount > 0:
|
||||
self.getFromTemp(cursor.fetchone()[0], msg, wav)
|
||||
@@ -125,14 +142,32 @@
|
||||
|
||||
if start > 1:
|
||||
|
||||
- cursor.execute("SELECT audio FROM domain_audio WHERE application='" + APPLICATION + "' AND message='" + msg + "' AND domain='" + self.dialog.domain + "' AND language='" + self.language + "'")
|
||||
+ cursor.execute(
|
||||
+ "SELECT audio FROM domain_audio WHERE application='"
|
||||
+ + APPLICATION
|
||||
+ + "' AND message='"
|
||||
+ + msg
|
||||
+ + "' AND domain='"
|
||||
+ + self.dialog.domain
|
||||
+ + "' AND language='"
|
||||
+ + self.language
|
||||
+ + "'"
|
||||
+ )
|
||||
|
||||
if cursor.rowcount > 0:
|
||||
self.getFromTemp(cursor.fetchone()[0], msg, wav)
|
||||
cursor.close()
|
||||
return True
|
||||
-
|
||||
- cursor.execute("SELECT audio FROM default_audio WHERE application='" + APPLICATION + "' AND message='" + msg + "' AND language='" + (self.language) + "'")
|
||||
+
|
||||
+ cursor.execute(
|
||||
+ "SELECT audio FROM default_audio WHERE application='"
|
||||
+ + APPLICATION
|
||||
+ + "' AND message='"
|
||||
+ + msg
|
||||
+ + "' AND language='"
|
||||
+ + (self.language)
|
||||
+ + "'"
|
||||
+ )
|
||||
|
||||
if cursor.rowcount > 0:
|
||||
self.getFromTemp(cursor.fetchone()[0], msg, wav)
|
||||
@@ -143,11 +178,16 @@
|
||||
cursor.close()
|
||||
return False
|
||||
|
||||
- except MySQLdb.Error, e:
|
||||
- error(APPLICATION + ": error in accessing database: " +\
|
||||
- str(e.args[0]) + ":" + e.args[1])
|
||||
+ except MySQLdb.Error as e:
|
||||
+ error(
|
||||
+ APPLICATION
|
||||
+ + ": error in accessing database: "
|
||||
+ + str(e.args[0])
|
||||
+ + ":"
|
||||
+ + e.args[1]
|
||||
+ )
|
||||
return False
|
||||
-
|
||||
+
|
||||
def getFromTemp(self, audio, msg, wav):
|
||||
|
||||
fp = os.tmpfile()
|
||||
--- a/apps/ivr/Makefile.ivr_application
|
||||
+++ b/apps/ivr/Makefile.ivr_application
|
||||
@@ -9,7 +9,7 @@
|
||||
include $(COREPATH)/../Makefile.defs
|
||||
include $(IVRPATH)/Makefile.defs
|
||||
|
||||
-#
|
||||
+#
|
||||
ivr_modules_dir?=lib/$(APP_NAME)/ivr
|
||||
|
||||
LIB_INSTALLDIR?=$(modules_prefix)/$(ivr_modules_dir)
|
||||
@@ -35,21 +35,23 @@
|
||||
rm -f ${TARBALL_PREFIX}*.tar.gz
|
||||
|
||||
.PHONY: compile
|
||||
-compile:
|
||||
+compile:
|
||||
$(PY_EXE) $(IVRPATH)/py_comp -q .
|
||||
|
||||
.PHONY: install
|
||||
install: all $(extra_install)
|
||||
install -d $(DESTDIR)${BASEDIR}/${LIB_INSTALLDIR}
|
||||
- install -m ${LIB_PERMISSIONS} *.pyc $(DESTDIR)${BASEDIR}/${LIB_INSTALLDIR}
|
||||
+ # note: we're ignoring those and need to skip it with py3k
|
||||
+ # install -m ${LIB_PERMISSIONS} *.pyc $(DESTDIR)${BASEDIR}/${LIB_INSTALLDIR}
|
||||
|
||||
ifneq (,$(LIBDIR))
|
||||
- install -d $(DESTDIR)${BASEDIR}/${LIB_INSTALLDIR}/${LIBDIR}
|
||||
- install -m ${LIB_PERMISSIONS} ${LIBDIR}/*.pyc $(DESTDIR)${BASEDIR}/${LIB_INSTALLDIR}/${LIBDIR}
|
||||
+ install -d $(DESTDIR)${BASEDIR}/${LIB_INSTALLDIR}/${LIBDIR}
|
||||
+ # note: we're ignoring those and need to skip it with py3k
|
||||
+ # install -m ${LIB_PERMISSIONS} ${LIBDIR}/*.pyc $(DESTDIR)${BASEDIR}/${LIB_INSTALLDIR}/${LIBDIR}
|
||||
endif
|
||||
|
||||
.PHONY: install-cfg
|
||||
-install-cfg:
|
||||
+install-cfg:
|
||||
mkdir -p $(DESTDIR)$(app_cfg_target)
|
||||
@set -e; \
|
||||
for r in $(module_conf_files); do \
|
||||
@@ -75,16 +77,16 @@
|
||||
fi ; \
|
||||
done
|
||||
|
||||
-uninstall:
|
||||
+uninstall:
|
||||
@echo "please remove the files from $(DESTDIR)${LIB_INSTALLDIR} manually."
|
||||
|
||||
-fulltest:
|
||||
- find | grep /Test | grep -v ".svn" | grep \\.py$$ | sed -e "s#^./##g" | bash -e -
|
||||
+fulltest:
|
||||
+ find | grep /Test | grep -v ".svn" | grep \\.py$$ | sed -e "s#^./##g" | bash -e -
|
||||
|
||||
-check:
|
||||
- find ${LIBDIR}/ | grep \\.py$$ | grep -v Test | PYTHONPATH=$(PYTHONPATH):$(IVRPATH)/moc xargs pychecker ${PYCHECKERARGS}
|
||||
+check:
|
||||
+ find ${LIBDIR}/ | grep \\.py$$ | grep -v Test | PYTHONPATH=$(PYTHONPATH):$(IVRPATH)/moc xargs pychecker ${PYCHECKERARGS}
|
||||
|
||||
-doccheck:
|
||||
+doccheck:
|
||||
find ${LIBDIR}/ | grep \\.py$$ | grep -v Test | xargs pychecker ${PYCHECKERARGS} ${PYCHECKERDOCARGS}
|
||||
|
||||
dist: all
|
||||
--- a/apps/examples/py_sems_ex/early_media.py
|
||||
+++ b/apps/examples/py_sems_ex/early_media.py
|
||||
@@ -1,113 +1,112 @@
|
||||
-import base64,time,os,sip
|
||||
+import base64, time, os, sip
|
||||
|
||||
from py_sems_log import *
|
||||
from py_sems import *
|
||||
from py_sems_lib import *
|
||||
|
||||
+
|
||||
class PySemsScript(PySemsDialog):
|
||||
+ def __init__(self):
|
||||
+
|
||||
+ debug("***** __init__ *******")
|
||||
+ PySemsDialog.__init__(self)
|
||||
+ self.initial_req = None
|
||||
+ self.ann = None
|
||||
+ sip.settracemask(0xFFFF)
|
||||
+
|
||||
+ def onInvite(self, req):
|
||||
+
|
||||
+ print("----------------- %s ----------------" % self.__class__)
|
||||
+
|
||||
+ ann_file = self.getAnnounceFile(req)
|
||||
+ self.ann = AmAudioFile()
|
||||
+
|
||||
+ try:
|
||||
+ self.ann.open(ann_file)
|
||||
+
|
||||
+ self.initial_req = AmSipRequest(req)
|
||||
+ debug("dlg.local_tag: %s" % self.dlg.local_tag)
|
||||
+
|
||||
+ debug("***** onInvite *******")
|
||||
+ (res, sdp_reply) = self.acceptAudio(req.body, req.hdrs)
|
||||
+ if res < 0:
|
||||
+ self.dlg.reply(req, 500)
|
||||
+
|
||||
+ debug("res = %s" % repr(res))
|
||||
+ debug("sdp_reply = %s" % sdp_reply)
|
||||
+
|
||||
+ if self.dlg.reply(req, 183, "OK", "application/sdp", sdp_reply, "") != 0:
|
||||
+ self.setStopped()
|
||||
+ except:
|
||||
+ self.dlg.reply(req, 500, "File not found", "", "", "")
|
||||
+ self.ann = None
|
||||
+ self.setStopped()
|
||||
+ raise
|
||||
+
|
||||
+ def onSessionStart(self, req):
|
||||
+
|
||||
+ debug("***** onSessionStart *******")
|
||||
+ PySemsDialog.onSessionStart(self, req)
|
||||
+
|
||||
+ self.localreq = AmSipRequest(req)
|
||||
+ self.setOutput(self.ann)
|
||||
+
|
||||
+ def onCancel(self):
|
||||
+
|
||||
+ debug("***** onCancel *******")
|
||||
+
|
||||
+ self.dlg.reply(self.initial_req, 487, "Call terminated", "", "", "")
|
||||
+ self.setStopped()
|
||||
+
|
||||
+ def getAnnounceFile(self, req):
|
||||
+
|
||||
+ announce_file = (
|
||||
+ config["announce_path"]
|
||||
+ + req.domain
|
||||
+ + "/"
|
||||
+ + get_header_param(req.r_uri, "play")
|
||||
+ + ".wav"
|
||||
+ )
|
||||
+
|
||||
+ debug("trying '%s'", announce_file)
|
||||
+ if os.path.exists(announce_file):
|
||||
+ return announce_file
|
||||
+
|
||||
+ announce_file = config["announce_path"] + req.user + ".wav"
|
||||
+ debug("trying '%s'", announce_file)
|
||||
+ if os.path.exists(announce_file):
|
||||
+ return announce_file
|
||||
+
|
||||
+ announce_file = config["announce_path"] + config["announce_file"]
|
||||
+ debug("using default '%s'", announce_file)
|
||||
+ return announce_file
|
||||
+
|
||||
+ def process(self, ev):
|
||||
+
|
||||
+ debug("*********** PySemsScript.process **************")
|
||||
+ if isinstance(ev, AmAudioEvent):
|
||||
+ if ev.event_id == AmAudioEvent.cleared:
|
||||
+
|
||||
+ debug("AmAudioEvent.cleared")
|
||||
+
|
||||
+ code = getHeader(self.localreq.hdrs, "P-Final-Reply-Code")
|
||||
+ reason = getHeader(self.localreq.hdrs, "P-Final-Reply-Reason")
|
||||
+
|
||||
+ if reason == "":
|
||||
+ reason = "OK"
|
||||
+
|
||||
+ code_i = 400
|
||||
+ try:
|
||||
+ code_i = int(code)
|
||||
+ if (code_i < 300) or (code_i > 699):
|
||||
+ debug("Invalid reply code: %d", code_i)
|
||||
+ except:
|
||||
+ debug("Invalid reply code: %s", code)
|
||||
|
||||
- def __init__(self):
|
||||
-
|
||||
- debug("***** __init__ *******")
|
||||
- PySemsDialog.__init__(self)
|
||||
- self.initial_req = None
|
||||
- self.ann = None
|
||||
- sip.settracemask(0xFFFF)
|
||||
-
|
||||
- def onInvite(self,req):
|
||||
-
|
||||
-
|
||||
- print "----------------- %s ----------------" % self.__class__
|
||||
-
|
||||
- ann_file = self.getAnnounceFile(req)
|
||||
- self.ann = AmAudioFile()
|
||||
-
|
||||
- try:
|
||||
- self.ann.open(ann_file)
|
||||
-
|
||||
- self.initial_req = AmSipRequest(req)
|
||||
- debug("dlg.local_tag: %s" % self.dlg.local_tag)
|
||||
-
|
||||
- debug("***** onInvite *******")
|
||||
- (res,sdp_reply) = self.acceptAudio(req.body,req.hdrs)
|
||||
- if res < 0:
|
||||
- self.dlg.reply(req,500)
|
||||
-
|
||||
- debug("res = %s" % repr(res))
|
||||
- debug("sdp_reply = %s" % sdp_reply)
|
||||
-
|
||||
- if self.dlg.reply(req,183,"OK","application/sdp",sdp_reply,"") <> 0:
|
||||
- self.setStopped()
|
||||
- except:
|
||||
- self.dlg.reply(req,500,"File not found","","","")
|
||||
- self.ann = None
|
||||
- self.setStopped()
|
||||
- raise
|
||||
-
|
||||
-
|
||||
- def onSessionStart(self,req):
|
||||
-
|
||||
- debug("***** onSessionStart *******")
|
||||
- PySemsDialog.onSessionStart(self,req)
|
||||
-
|
||||
- self.localreq = AmSipRequest(req)
|
||||
- self.setOutput(self.ann)
|
||||
-
|
||||
-
|
||||
- def onCancel(self):
|
||||
-
|
||||
- debug("***** onCancel *******")
|
||||
-
|
||||
- self.dlg.reply(self.initial_req,487,"Call terminated","","","")
|
||||
- self.setStopped()
|
||||
-
|
||||
-
|
||||
- def getAnnounceFile(self,req):
|
||||
-
|
||||
- announce_file = config["announce_path"] + req.domain + "/" + get_header_param(req.r_uri, "play") + ".wav"
|
||||
-
|
||||
- debug("trying '%s'",announce_file)
|
||||
- if os.path.exists(announce_file):
|
||||
- return announce_file
|
||||
-
|
||||
- announce_file = config["announce_path"] + req.user + ".wav"
|
||||
- debug("trying '%s'",announce_file)
|
||||
- if os.path.exists(announce_file):
|
||||
- return announce_file
|
||||
-
|
||||
- announce_file = config["announce_path"] + config["announce_file"]
|
||||
- debug("using default '%s'",announce_file)
|
||||
- return announce_file
|
||||
-
|
||||
-
|
||||
- def process(self,ev):
|
||||
-
|
||||
- debug("*********** PySemsScript.process **************")
|
||||
- if isinstance(ev,AmAudioEvent):
|
||||
- if ev.event_id == AmAudioEvent.cleared:
|
||||
-
|
||||
- debug("AmAudioEvent.cleared")
|
||||
-
|
||||
- code = getHeader(self.localreq.hdrs,"P-Final-Reply-Code")
|
||||
- reason = getHeader(self.localreq.hdrs,"P-Final-Reply-Reason")
|
||||
-
|
||||
- if reason == "":
|
||||
- reason = "OK"
|
||||
-
|
||||
- code_i = 400
|
||||
- try:
|
||||
- code_i = int(code)
|
||||
- if (code_i < 300) or (code_i>699):
|
||||
- debug("Invalid reply code: %d",code_i)
|
||||
- except:
|
||||
- debug("Invalid reply code: %s",code)
|
||||
-
|
||||
- debug("Replying %d %s" % (code_i, reason))
|
||||
- self.dlg.reply(self.localreq, code_i, reason, "", "", "")
|
||||
- self.setStopped()
|
||||
- return
|
||||
-
|
||||
- PySemsDialog.process(self,ev);
|
||||
- return
|
||||
+ debug("Replying %d %s" % (code_i, reason))
|
||||
+ self.dlg.reply(self.localreq, code_i, reason, "", "", "")
|
||||
+ self.setStopped()
|
||||
+ return
|
||||
|
||||
-
|
||||
+ PySemsDialog.process(self, ev)
|
||||
+ return
|
||||
--- a/apps/examples/py_sems_ex/jukecall.py
|
||||
+++ b/apps/examples/py_sems_ex/jukecall.py
|
||||
@@ -1,110 +1,123 @@
|
||||
-import base64,time,os,sip
|
||||
+import base64, time, os, sip
|
||||
|
||||
from py_sems_log import *
|
||||
from py_sems import *
|
||||
from py_sems_lib import *
|
||||
|
||||
+
|
||||
class MyB2ABEvent(PySemsB2ABEvent):
|
||||
- def __init__(self, id):
|
||||
- PySemsB2ABEvent.__init__(self,id)
|
||||
+ def __init__(self, id):
|
||||
+ PySemsB2ABEvent.__init__(self, id)
|
||||
+
|
||||
|
||||
class MyCalleeSession(PySemsB2ABCalleeDialog):
|
||||
- def __init__(self, tag):
|
||||
- debug("**** __init callee __ ****")
|
||||
- AmB2ABCalleeSession.__init__(self, tag)
|
||||
- self.ann=None
|
||||
- #debug("**** tag = " + tag);
|
||||
-
|
||||
- def onPyB2ABEvent(self, ev):
|
||||
- debug("***************************** callee PyB2ABEvent ************************")
|
||||
- if isinstance(ev, MyB2ABEvent):
|
||||
- self.ann = AmAudioFile()
|
||||
- self.ann.open("/tmp/test.wav")
|
||||
- self.setOutput(self.ann)
|
||||
- return
|
||||
+ def __init__(self, tag):
|
||||
+ debug("**** __init callee __ ****")
|
||||
+ AmB2ABCalleeSession.__init__(self, tag)
|
||||
+ self.ann = None
|
||||
+ # debug("**** tag = " + tag);
|
||||
+
|
||||
+ def onPyB2ABEvent(self, ev):
|
||||
+ debug(
|
||||
+ "***************************** callee PyB2ABEvent ************************"
|
||||
+ )
|
||||
+ if isinstance(ev, MyB2ABEvent):
|
||||
+ self.ann = AmAudioFile()
|
||||
+ self.ann.open("/tmp/test.wav")
|
||||
+ self.setOutput(self.ann)
|
||||
+ return
|
||||
+
|
||||
|
||||
-
|
||||
class PySemsScript(PySemsB2ABDialog):
|
||||
+ def __init__(self):
|
||||
|
||||
- def __init__(self):
|
||||
-
|
||||
- debug("***** __init__ *******")
|
||||
- PySemsB2ABDialog.__init__(self)
|
||||
- self.initial_user = None
|
||||
- self.initial_domain = None
|
||||
- self.initial_fromuri = None
|
||||
- self.ann = None
|
||||
- sip.settracemask(0xFFFF)
|
||||
-
|
||||
- def onInvite(self, req):
|
||||
- if len(req.user) < 2:
|
||||
- self.dlg.reply(req,500,"Need a number to dial","","","")
|
||||
- self.setStopped()
|
||||
- return
|
||||
-
|
||||
- ann_file = self.getAnnounceFile(req)
|
||||
- self.ann = AmAudioFile()
|
||||
- try:
|
||||
- self.ann.open(ann_file)
|
||||
- except:
|
||||
- self.dlg.reply(req,500,"File not found","","","")
|
||||
- self.ann = None
|
||||
- self.setStopped()
|
||||
- raise
|
||||
-
|
||||
- PySemsB2ABDialog.onInvite(self,req)
|
||||
-
|
||||
- def onSessionStart(self,req):
|
||||
- self.setOutput(self.ann)
|
||||
- self.initial_user = req.user
|
||||
- self.initial_domain = req.domain
|
||||
- self.initial_fromuri = req.from_uri
|
||||
-
|
||||
- def getAnnounceFile(self,req):
|
||||
-
|
||||
- announce_file = config["announce_path"] + req.domain + "/" + get_header_param(req.r_uri, "play") + ".wav"
|
||||
-
|
||||
- debug("trying '%s'",announce_file)
|
||||
- if os.path.exists(announce_file):
|
||||
- return announce_file
|
||||
-
|
||||
- announce_file = config["announce_path"] + req.user + ".wav"
|
||||
- debug("trying '%s'",announce_file)
|
||||
- if os.path.exists(announce_file):
|
||||
- return announce_file
|
||||
-
|
||||
- announce_file = config["announce_path"] + config["announce_file"]
|
||||
- debug("using default '%s'",announce_file)
|
||||
- return announce_file
|
||||
-
|
||||
-
|
||||
- def process(self,ev):
|
||||
-
|
||||
- debug("*********** PySemsScript.process **************")
|
||||
- if isinstance(ev,AmAudioEvent):
|
||||
- if ev.event_id == AmAudioEvent.cleared:
|
||||
- debug("AmAudioEvent.cleared")
|
||||
- to = self.initial_user[1:len(self.initial_user)] + \
|
||||
- "@" + self.initial_domain
|
||||
- debug("to is " + to)
|
||||
- debug("from is "+ self.initial_fromuri)
|
||||
- self.connectCallee("<sip:"+to+">", "sip:"+to, \
|
||||
- self.initial_fromuri, self.initial_fromuri)
|
||||
- debug("connectcallee ok")
|
||||
- return
|
||||
-
|
||||
- PySemsB2ABDialog.process(self,ev);
|
||||
- return
|
||||
-
|
||||
- def createCalleeSession(self):
|
||||
- print self.dlg.local_tag
|
||||
- cs = MyCalleeSession(self.dlg.local_tag)
|
||||
- print cs
|
||||
- return cs
|
||||
-
|
||||
- def onDtmf(self, event, dur):
|
||||
- debug("************ onDTMF: ********* " + str(event) + "," + str(dur))
|
||||
- ev = MyB2ABEvent(15)
|
||||
- self.relayEvent(ev)
|
||||
-
|
||||
-
|
||||
+ debug("***** __init__ *******")
|
||||
+ PySemsB2ABDialog.__init__(self)
|
||||
+ self.initial_user = None
|
||||
+ self.initial_domain = None
|
||||
+ self.initial_fromuri = None
|
||||
+ self.ann = None
|
||||
+ sip.settracemask(0xFFFF)
|
||||
+
|
||||
+ def onInvite(self, req):
|
||||
+ if len(req.user) < 2:
|
||||
+ self.dlg.reply(req, 500, "Need a number to dial", "", "", "")
|
||||
+ self.setStopped()
|
||||
+ return
|
||||
+
|
||||
+ ann_file = self.getAnnounceFile(req)
|
||||
+ self.ann = AmAudioFile()
|
||||
+ try:
|
||||
+ self.ann.open(ann_file)
|
||||
+ except:
|
||||
+ self.dlg.reply(req, 500, "File not found", "", "", "")
|
||||
+ self.ann = None
|
||||
+ self.setStopped()
|
||||
+ raise
|
||||
+
|
||||
+ PySemsB2ABDialog.onInvite(self, req)
|
||||
+
|
||||
+ def onSessionStart(self, req):
|
||||
+ self.setOutput(self.ann)
|
||||
+ self.initial_user = req.user
|
||||
+ self.initial_domain = req.domain
|
||||
+ self.initial_fromuri = req.from_uri
|
||||
+
|
||||
+ def getAnnounceFile(self, req):
|
||||
+
|
||||
+ announce_file = (
|
||||
+ config["announce_path"]
|
||||
+ + req.domain
|
||||
+ + "/"
|
||||
+ + get_header_param(req.r_uri, "play")
|
||||
+ + ".wav"
|
||||
+ )
|
||||
+
|
||||
+ debug("trying '%s'", announce_file)
|
||||
+ if os.path.exists(announce_file):
|
||||
+ return announce_file
|
||||
+
|
||||
+ announce_file = config["announce_path"] + req.user + ".wav"
|
||||
+ debug("trying '%s'", announce_file)
|
||||
+ if os.path.exists(announce_file):
|
||||
+ return announce_file
|
||||
+
|
||||
+ announce_file = config["announce_path"] + config["announce_file"]
|
||||
+ debug("using default '%s'", announce_file)
|
||||
+ return announce_file
|
||||
+
|
||||
+ def process(self, ev):
|
||||
+
|
||||
+ debug("*********** PySemsScript.process **************")
|
||||
+ if isinstance(ev, AmAudioEvent):
|
||||
+ if ev.event_id == AmAudioEvent.cleared:
|
||||
+ debug("AmAudioEvent.cleared")
|
||||
+ to = (
|
||||
+ self.initial_user[1 : len(self.initial_user)]
|
||||
+ + "@"
|
||||
+ + self.initial_domain
|
||||
+ )
|
||||
+ debug("to is " + to)
|
||||
+ debug("from is " + self.initial_fromuri)
|
||||
+ self.connectCallee(
|
||||
+ "<sip:" + to + ">",
|
||||
+ "sip:" + to,
|
||||
+ self.initial_fromuri,
|
||||
+ self.initial_fromuri,
|
||||
+ )
|
||||
+ debug("connectcallee ok")
|
||||
+ return
|
||||
+
|
||||
+ PySemsB2ABDialog.process(self, ev)
|
||||
+ return
|
||||
+
|
||||
+ def createCalleeSession(self):
|
||||
+ print(self.dlg.local_tag)
|
||||
+ cs = MyCalleeSession(self.dlg.local_tag)
|
||||
+ print(cs)
|
||||
+ return cs
|
||||
+
|
||||
+ def onDtmf(self, event, dur):
|
||||
+ debug("************ onDTMF: ********* " + str(event) + "," + str(dur))
|
||||
+ ev = MyB2ABEvent(15)
|
||||
+ self.relayEvent(ev)
|
||||
--- a/apps/py_sems/Makefile.py_sems_application
|
||||
+++ b/apps/py_sems/Makefile.py_sems_application
|
||||
@@ -36,9 +36,11 @@
|
||||
.PHONY: install
|
||||
install: all
|
||||
install -d $(DESTDIR)${BASEDIR}/${LIB_INSTALLDIR}
|
||||
- install -m ${LIB_PERMISSIONS} *.pyc $(DESTDIR)${BASEDIR}/${LIB_INSTALLDIR}
|
||||
+ # note: we're ignoring those and need to skip it with py3k
|
||||
+ #install -m ${LIB_PERMISSIONS} *.pyc $(DESTDIR)${BASEDIR}/${LIB_INSTALLDIR}
|
||||
install -d $(DESTDIR)${BASEDIR}/${LIB_INSTALLDIR}/${LIBDIR}
|
||||
- install -m ${LIB_PERMISSIONS} ${LIBDIR}/*.pyc $(DESTDIR)${BASEDIR}/${LIB_INSTALLDIR}/${LIBDIR}
|
||||
+ # note: we're ignoring those and need to skip it with py3k
|
||||
+ #install -m ${LIB_PERMISSIONS} ${LIBDIR}/*.pyc $(DESTDIR)${BASEDIR}/${LIB_INSTALLDIR}/${LIBDIR}
|
||||
|
||||
.PHONY: install-cfg
|
||||
install-cfg:
|
||||
@ -1,34 +0,0 @@
|
||||
From f47f18c2f666cea2d20a60afe9255ab93ae243bc Mon Sep 17 00:00:00 2001
|
||||
From: Marco Capetta <mcapetta@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:20 +0100
|
||||
Subject: MT#55831 NGCP refreshes the session even if STT is not supported
|
||||
|
||||
Unset Sems internal Session Timers in case B leg doesn't support it
|
||||
(no Timer in Supported header of 200OK message).
|
||||
(real ticket number: TT#29926)
|
||||
|
||||
--- a/core/plug-in/session_timer/SessionTimer.cpp
|
||||
+++ b/core/plug-in/session_timer/SessionTimer.cpp
|
||||
@@ -346,7 +346,21 @@ void SessionTimer::updateTimer(AmSession
|
||||
if (((reply.code < 200) || (reply.code >= 300)) &&
|
||||
(!(accept_501_reply && reply.code == 501)))
|
||||
return;
|
||||
-
|
||||
+
|
||||
+ // verify if B leg supports Session Timers
|
||||
+ remote_timer_aware =
|
||||
+ key_in_list(getHeader(reply.hdrs, SIP_HDR_SUPPORTED, SIP_HDR_SUPPORTED_COMPACT),
|
||||
+ TIMER_OPTION_TAG);
|
||||
+
|
||||
+ if (!remote_timer_aware) {
|
||||
+ // timer NOT supported by B leg
|
||||
+ DBG("Session Timer NOT supported by leg B, removing internal session timer intervals");
|
||||
+ session_timer_conf.setEnableSessionTimer("no");
|
||||
+ removeTimers(s);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // timer supported by B leg
|
||||
// determine session interval
|
||||
string sess_expires_hdr = getHeader(reply.hdrs, SIP_HDR_SESSION_EXPIRES,
|
||||
SIP_HDR_SESSION_EXPIRES_COMPACT, true);
|
||||
@ -1,34 +0,0 @@
|
||||
From 5ef025a2bf958ba5a78c9091f6f9f7c7fc3c67ce Mon Sep 17 00:00:00 2001
|
||||
From: Donat Zenichev <dzenichev@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:29 +0100
|
||||
Subject: MT#55831 Authentication from SEMS with no credentials
|
||||
|
||||
There are cases when calls coming to a subscriber of C5 CE,
|
||||
is being challenged by this subscriber, the use case for that could be
|
||||
if for e.g. we have a PBX/SBC connected to NGCP via subscriber's object.
|
||||
|
||||
Current implementation of SEMS works so, that in case parameters;
|
||||
'enable_auth' and 'enable_aleg_auth' are set to value 'yes',
|
||||
SEMS tries to pass the digest for the calling party.
|
||||
|
||||
This leads to the empty 'username' and wrong 'response' parameters of
|
||||
the Proxy-Authorization header, eventually the Authorization process is failed.
|
||||
|
||||
This is to be changed, so in case 'u=', 'p=' and 'd=' have not been
|
||||
previously sent by the Proxy (in 'P-App-Param:'), or rather they are empty, authentication should be transparent,
|
||||
hence be processed by the calling side, with no interfer from SEMS into that.
|
||||
(real ticket number: TT#128701)
|
||||
|
||||
--- a/core/plug-in/uac_auth/UACAuth.cpp
|
||||
+++ b/core/plug-in/uac_auth/UACAuth.cpp
|
||||
@@ -173,7 +173,9 @@ bool UACAuth::onSipReply(const AmSipRequ
|
||||
// credential->realm.c_str(),
|
||||
// credential->user.c_str(),
|
||||
// credential->pwd.c_str());
|
||||
- if (!nonce_reuse &&
|
||||
+ if ((credential->user.empty() || credential->pwd.empty()) && reply.code==407) {
|
||||
+ DBG("No credentials to pass the challenge from behalf of B2B, sending 407 transparently\n");
|
||||
+ } else if (!nonce_reuse &&
|
||||
(((reply.code == 401) &&
|
||||
getHeader(ri->second.hdrs, SIP_HDR_AUTHORIZATION, true).length()) ||
|
||||
((reply.code == 407) &&
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,46 +0,0 @@
|
||||
From d7bce5145bb852a9cf439326bb33e5a142b6a2e1 Mon Sep 17 00:00:00 2001
|
||||
From: Roman Romanchenko <rromanchenko@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:13:00 +0100
|
||||
Subject: MT#55831 sems-* constant 10% CPU usage in idle Virtual environment vagrant/vmware
|
||||
|
||||
sems-* constant 10% CPU usage in idle Virtual environment vagrant/vmware
|
||||
DBRegagent loop sleep replaced with waitForEvent() call
|
||||
(real ticket number: TT#52455)
|
||||
|
||||
--- a/apps/db_reg_agent/DBRegAgent.cpp
|
||||
+++ b/apps/db_reg_agent/DBRegAgent.cpp
|
||||
@@ -897,9 +897,8 @@ void DBRegAgent::run() {
|
||||
DBG("running DBRegAgent thread...\n");
|
||||
shutdown_finished = false;
|
||||
while (running) {
|
||||
+ waitForEventTimed(500); // 500 milliseconds
|
||||
processEvents();
|
||||
-
|
||||
- usleep(1000); // 1ms
|
||||
}
|
||||
|
||||
DBG("DBRegAgent done, removing all registrations from Event Dispatcher...\n");
|
||||
--- a/core/AmEventQueue.cpp
|
||||
+++ b/core/AmEventQueue.cpp
|
||||
@@ -100,6 +100,11 @@ void AmEventQueue::waitForEvent()
|
||||
ev_pending.wait_for();
|
||||
}
|
||||
|
||||
+void AmEventQueue::waitForEventTimed(unsigned long msec)
|
||||
+{
|
||||
+ ev_pending.wait_for_to(msec);
|
||||
+}
|
||||
+
|
||||
void AmEventQueue::processSingleEvent()
|
||||
{
|
||||
m_queue.lock();
|
||||
--- a/core/AmEventQueue.h
|
||||
+++ b/core/AmEventQueue.h
|
||||
@@ -80,6 +80,7 @@ public:
|
||||
void postEvent(AmEvent*);
|
||||
void processEvents();
|
||||
void waitForEvent();
|
||||
+ void waitForEventTimed(unsigned long msec);
|
||||
void processSingleEvent();
|
||||
bool eventPending();
|
||||
|
||||
@ -1,19 +0,0 @@
|
||||
From 1619876f76da9ac3530b3524795ba06ddcfdab09 Mon Sep 17 00:00:00 2001
|
||||
From: Roman Romanchenko <rromanchenko@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:26 +0100
|
||||
Subject: MT#55831 sems: fails to build against Debian/bullseye
|
||||
|
||||
- python support removed
|
||||
(real ticket number: TT#101059)
|
||||
|
||||
--- a/Makefile.defs
|
||||
+++ b/Makefile.defs
|
||||
@@ -85,7 +85,7 @@
|
||||
# build in support for monitoring?
|
||||
#
|
||||
#
|
||||
-USE_MONITORING=yes
|
||||
+USE_MONITORING=no
|
||||
|
||||
# Support for long debug messages? (useful for debugging SIP messages' contents)
|
||||
#
|
||||
@ -1,53 +0,0 @@
|
||||
From 944cf94dcd2ad44e66b895682329ead001c72546 Mon Sep 17 00:00:00 2001
|
||||
From: Richard Fuchs <rfuchs@sipwise.com>
|
||||
Date: Thu, 29 Dec 2022 10:14:19 +0100
|
||||
Subject: MT#55831 restore reporting of number of running calls
|
||||
|
||||
restore reporting of number of running calls
|
||||
(real ticket number: TT#27201)
|
||||
|
||||
--- a/core/AmSession.cpp
|
||||
+++ b/core/AmSession.cpp
|
||||
@@ -49,6 +49,9 @@
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include <sys/time.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <termios.h>
|
||||
+#include <sys/ioctl.h>
|
||||
|
||||
volatile unsigned int AmSession::session_num = 0;
|
||||
AmMutex AmSession::session_num_mut;
|
||||
@@ -494,6 +497,14 @@
|
||||
return id;
|
||||
}
|
||||
/* bookkeeping functions - TODO: move to monitoring */
|
||||
+static inline void __update_session_count(unsigned int num) {
|
||||
+ int fd = open("/proc/ngcp/check", O_RDONLY);
|
||||
+ if (fd >= 0) {
|
||||
+ // set calls usage
|
||||
+ ioctl(fd, TCXONC, (int) num);
|
||||
+ close(fd);
|
||||
+ }
|
||||
+}
|
||||
void AmSession::session_started() {
|
||||
struct timeval now, delta;
|
||||
|
||||
@@ -511,6 +522,8 @@
|
||||
if(session_num > max_session_num) max_session_num = session_num;
|
||||
|
||||
session_num_mut.unlock();
|
||||
+
|
||||
+ __update_session_count(getSessionNum());
|
||||
}
|
||||
|
||||
void AmSession::session_stopped() {
|
||||
@@ -524,6 +537,8 @@
|
||||
//current session number
|
||||
session_num--;
|
||||
session_num_mut.unlock();
|
||||
+
|
||||
+ __update_session_count(getSessionNum());
|
||||
}
|
||||
|
||||
unsigned int AmSession::getSessionNum() {
|
||||
@ -1,27 +0,0 @@
|
||||
From 09dca94aa38c3e9ec5efc9b3c119fa97ce404bed Mon Sep 17 00:00:00 2001
|
||||
From: Raphael Coeffic <rco@iptel.org>
|
||||
Date: Thu, 29 Dec 2022 10:13:01 +0100
|
||||
Subject: MT#55831 sbc: fixed reading encoding param in readPayload()
|
||||
|
||||
(real ticket number: TT#13019)
|
||||
|
||||
---
|
||||
apps/sbc/SBCCallProfile.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/apps/sbc/SBCCallProfile.cpp b/apps/sbc/SBCCallProfile.cpp
|
||||
index ce93ef2..2654fd8 100644
|
||||
--- a/apps/sbc/SBCCallProfile.cpp
|
||||
+++ b/apps/sbc/SBCCallProfile.cpp
|
||||
@@ -1347,7 +1347,7 @@ static bool readPayload(SdpPayload &p, const string &src)
|
||||
|
||||
if (elems.size() < 1) return false;
|
||||
|
||||
- if (elems.size() > 2) str2int(elems[1], p.encoding_param);
|
||||
+ if (elems.size() > 2) str2int(elems[2], p.encoding_param);
|
||||
if (elems.size() > 1) str2int(elems[1], p.clock_rate);
|
||||
else p.clock_rate = 8000; // default value
|
||||
p.encoding_name = elems[0];
|
||||
--
|
||||
2.1.4
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
From b722a91680499851990c192a7023cecb0ef04609 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Sayer <stefan.sayer@googlemail.com>
|
||||
Date: Thu, 29 Dec 2022 10:13:02 +0100
|
||||
Subject: MT#55831 sbc: codecs: compare encoding_param only if both != 0
|
||||
|
||||
(real ticket number: TT#13019)
|
||||
|
||||
---
|
||||
apps/sbc/SBCCallLeg.cpp | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/apps/sbc/SBCCallLeg.cpp b/apps/sbc/SBCCallLeg.cpp
|
||||
index 5184f2e..299cbbe 100644
|
||||
--- a/apps/sbc/SBCCallLeg.cpp
|
||||
+++ b/apps/sbc/SBCCallLeg.cpp
|
||||
@@ -76,7 +76,7 @@ static const SdpPayload *findPayload(const std::vector<SdpPayload>& payloads, co
|
||||
}
|
||||
|
||||
if (p->clock_rate != payload.clock_rate) continue;
|
||||
- if ((p->encoding_param >= 0) && (payload.encoding_param >= 0) &&
|
||||
+ if ((p->encoding_param > 0) && (payload.encoding_param > 0) &&
|
||||
(p->encoding_param != payload.encoding_param)) continue;
|
||||
return &(*p);
|
||||
}
|
||||
--
|
||||
2.1.4
|
||||
|
||||
@ -1,773 +0,0 @@
|
||||
From 03cd08e1f0f05d5477e797d5184cec61544b0e55 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Sayer <stefan.sayer@frafos.com>
|
||||
Date: Thu, 29 Dec 2022 10:13:03 +0100
|
||||
Subject: MT#55831 core:codec init: support for fmt params negotiation,
|
||||
fmt_description changed
|
||||
|
||||
- a codec may export with CODEC_WITH_FMT also a payload format negotiation function
|
||||
negotiate_fmt
|
||||
|
||||
- transcoder adds fmt strings to transcoder codecs
|
||||
|
||||
- changed codec fmt_description such that the codec returns a pointer to a
|
||||
description array
|
||||
|
||||
Conflicts:
|
||||
|
||||
core/plug-in/amr/amr.c
|
||||
core/plug-in/speex/speex.c
|
||||
|
||||
(real ticket number: TT#13019)
|
||||
|
||||
---
|
||||
apps/sbc/SBCCallProfile.cpp | 5 +++--
|
||||
core/AmAudio.cpp | 16 +++++++++-----
|
||||
core/AmAudio.h | 1 +
|
||||
core/AmPlugIn.cpp | 15 +++++++++++++
|
||||
core/AmPlugIn.h | 11 ++++++++++
|
||||
core/AmRtpAudio.cpp | 51 ++++++++++++++++++++++++++-------------------
|
||||
core/amci/amci.h | 28 ++++++++++++++++++++-----
|
||||
core/plug-in/adpcm/adpcm.c | 7 ++++---
|
||||
core/plug-in/g722/g722.c | 6 ++++--
|
||||
core/plug-in/g729/g729.c | 12 +++++++++--
|
||||
core/plug-in/gsm/gsm.c | 19 ++++++++---------
|
||||
core/plug-in/ilbc/ilbc.c | 25 +++++++++++++---------
|
||||
core/plug-in/isac/isac.c | 16 +++++++-------
|
||||
core/plug-in/opus/opus.c | 17 ++++++++-------
|
||||
core/plug-in/silk/silk.c | 36 +++++++++++++++++++-------------
|
||||
core/plug-in/speex/speex.c | 44 +++++++++++++++++++++-----------------
|
||||
16 files changed, 197 insertions(+), 112 deletions(-)
|
||||
|
||||
diff --git a/apps/sbc/SBCCallProfile.cpp b/apps/sbc/SBCCallProfile.cpp
|
||||
index 2654fd8..5733fee 100644
|
||||
--- a/apps/sbc/SBCCallProfile.cpp
|
||||
+++ b/apps/sbc/SBCCallProfile.cpp
|
||||
@@ -1391,8 +1391,9 @@ static bool read(const std::string &src, vector<SdpPayload> &codecs)
|
||||
if(!payload) {
|
||||
ERROR("Ignoring unknown payload found in call profile: '%s/%i'\n",
|
||||
p.encoding_name.c_str(), p.clock_rate);
|
||||
- }
|
||||
- else {
|
||||
+ } else {
|
||||
+ p.sdp_format_parameters = plugin->getSdpFormatParameters(payload->codec_id, true, "");
|
||||
+
|
||||
if(payload_id < DYNAMIC_PAYLOAD_TYPE_START)
|
||||
p.payload_type = payload->payload_id;
|
||||
else
|
||||
diff --git a/core/AmAudio.cpp b/core/AmAudio.cpp
|
||||
index 43c8043..bb9f213 100644
|
||||
--- a/core/AmAudio.cpp
|
||||
+++ b/core/AmAudio.cpp
|
||||
@@ -55,7 +55,8 @@ AmAudioFormat::AmAudioFormat(int codec_id, unsigned int rate)
|
||||
: channels(1),
|
||||
codec_id(codec_id),
|
||||
rate(rate),
|
||||
- codec(NULL)
|
||||
+ codec(NULL),
|
||||
+ sdp_format_parameters_out(NULL)
|
||||
{
|
||||
codec = getCodec();
|
||||
}
|
||||
@@ -103,13 +104,18 @@ bool AmAudioFormat::operator != (const AmAudioFormat& r) const
|
||||
|
||||
void AmAudioFormat::initCodec()
|
||||
{
|
||||
- amci_codec_fmt_info_t fmt_i[4];
|
||||
- fmt_i[0].id=0;
|
||||
+ amci_codec_fmt_info_t* fmt_i = NULL;
|
||||
+ sdp_format_parameters_out = NULL; // reset
|
||||
|
||||
if( codec && codec->init ) {
|
||||
- if ((h_codec = (*codec->init)(sdp_format_parameters.c_str(), fmt_i)) == -1) {
|
||||
+ if ((h_codec = (*codec->init)(sdp_format_parameters.c_str(),
|
||||
+ &sdp_format_parameters_out, &fmt_i)) == -1) {
|
||||
ERROR("could not initialize codec %i\n",codec->id);
|
||||
- }
|
||||
+ } else {
|
||||
+ if (NULL != sdp_format_parameters_out) {
|
||||
+ DBG("negotiated fmt parameters '%s'\n", sdp_format_parameters_out);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/core/AmAudio.h b/core/AmAudio.h
|
||||
index 3fa847d..e87fe23 100644
|
||||
--- a/core/AmAudio.h
|
||||
+++ b/core/AmAudio.h
|
||||
@@ -139,6 +139,7 @@ public:
|
||||
int channels;
|
||||
|
||||
string sdp_format_parameters;
|
||||
+ const char* sdp_format_parameters_out;
|
||||
|
||||
AmAudioFormat(int codec_id = CODEC_PCM16,
|
||||
unsigned int rate = SYSTEM_SAMPLECLOCK_RATE);
|
||||
diff --git a/core/AmPlugIn.cpp b/core/AmPlugIn.cpp
|
||||
index 7664e91..a677c17 100644
|
||||
--- a/core/AmPlugIn.cpp
|
||||
+++ b/core/AmPlugIn.cpp
|
||||
@@ -400,6 +400,21 @@ amci_payload_t* AmPlugIn::payload(int payload_id) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
+string AmPlugIn::getSdpFormatParameters(int codec_id, bool is_offer, const string& fmt_params_in) {
|
||||
+ amci_codec_t* c = codec(codec_id);
|
||||
+ if (NULL == c)
|
||||
+ return ""; // empty for unsupported codec
|
||||
+
|
||||
+ if (NULL == c->negotiate_fmt)
|
||||
+ return ""; // empty if codec doesn't know either
|
||||
+
|
||||
+ char out_fmt[256] = { '\0' };
|
||||
+ if ((c->negotiate_fmt)(is_offer ? 1:0, fmt_params_in.c_str(), out_fmt, 256) >=0 )
|
||||
+ return string(out_fmt);
|
||||
+
|
||||
+ return "";
|
||||
+}
|
||||
+
|
||||
int AmPlugIn::getDynPayload(const string& name, int rate, int encoding_param) const {
|
||||
// find a dynamic payload by name/rate and encoding_param (channels, if > 0)
|
||||
for(std::map<int, amci_payload_t*>::const_iterator pl_it = payloads.begin();
|
||||
diff --git a/core/AmPlugIn.h b/core/AmPlugIn.h
|
||||
index b8e6485..95d3152 100644
|
||||
--- a/core/AmPlugIn.h
|
||||
+++ b/core/AmPlugIn.h
|
||||
@@ -199,6 +199,17 @@ class AmPlugIn : public AmPayloadProvider
|
||||
*/
|
||||
amci_codec_t* codec(int id);
|
||||
|
||||
+ /**
|
||||
+ * get codec format parameters
|
||||
+ * @param id Codec ID (see amci/codecs.h).
|
||||
+ * @param is_offer for an offer?
|
||||
+ * @param fmt_params_in input parameters for an answer
|
||||
+ * @return fmt parameters for SDP (offer or answer)
|
||||
+ */
|
||||
+ string getSdpFormatParameters(int codec_id, bool is_offer, const string& fmt_params_in);
|
||||
+
|
||||
+
|
||||
+
|
||||
/**
|
||||
* Application lookup function
|
||||
* @param app_name application name
|
||||
diff --git a/core/AmRtpAudio.cpp b/core/AmRtpAudio.cpp
|
||||
index a8cacde..a6bd259 100644
|
||||
--- a/core/AmRtpAudio.cpp
|
||||
+++ b/core/AmRtpAudio.cpp
|
||||
@@ -62,34 +62,41 @@ int AmAudioRtpFormat::setCurrentPayload(Payload pl)
|
||||
|
||||
void AmAudioRtpFormat::initCodec()
|
||||
{
|
||||
- amci_codec_fmt_info_t fmt_i[4];
|
||||
-
|
||||
- fmt_i[0].id=0;
|
||||
+ amci_codec_fmt_info_t* fmt_i = NULL;
|
||||
+ sdp_format_parameters_out = NULL; // reset
|
||||
|
||||
if( codec && codec->init ) {
|
||||
- if ((h_codec = (*codec->init)(sdp_format_parameters.c_str(), fmt_i)) == -1) {
|
||||
+ if ((h_codec = (*codec->init)(sdp_format_parameters.c_str(),
|
||||
+ &sdp_format_parameters_out, &fmt_i)) == -1) {
|
||||
ERROR("could not initialize codec %i\n",codec->id);
|
||||
} else {
|
||||
- string s;
|
||||
- int i=0;
|
||||
- while (fmt_i[i].id) {
|
||||
- switch (fmt_i[i].id) {
|
||||
- case AMCI_FMT_FRAME_LENGTH : {
|
||||
- //frame_length=fmt_i[i].value;
|
||||
- } break;
|
||||
- case AMCI_FMT_FRAME_SIZE: {
|
||||
- frame_size=fmt_i[i].value;
|
||||
- } break;
|
||||
- case AMCI_FMT_ENCODED_FRAME_SIZE: {
|
||||
- // frame_encoded_size=fmt_i[i].value;
|
||||
- } break;
|
||||
- default: {
|
||||
- DBG("Unknown codec format descriptor: %d\n", fmt_i[i].id);
|
||||
- } break;
|
||||
+ if (NULL != sdp_format_parameters_out) {
|
||||
+ DBG("negotiated fmt parameters '%s'\n", sdp_format_parameters_out);
|
||||
+ log_demangled_stacktrace(L_DBG, 30);
|
||||
+ }
|
||||
+
|
||||
+ if (NULL != fmt_i) {
|
||||
+ unsigned int i=0;
|
||||
+ while (i<4 && fmt_i[i].id) {
|
||||
+ switch (fmt_i[i].id) {
|
||||
+ case AMCI_FMT_FRAME_LENGTH : {
|
||||
+ //frame_length=fmt_i[i].value; // ignored
|
||||
+ } break;
|
||||
+ case AMCI_FMT_FRAME_SIZE: {
|
||||
+ frame_size=fmt_i[i].value;
|
||||
+ } break;
|
||||
+ case AMCI_FMT_ENCODED_FRAME_SIZE: {
|
||||
+ // frame_encoded_size=fmt_i[i].value; // ignored
|
||||
+ } break;
|
||||
+ default: {
|
||||
+ DBG("Unknown codec format descriptor: %d\n", fmt_i[i].id);
|
||||
+ } break;
|
||||
+ }
|
||||
+
|
||||
+ i++;
|
||||
}
|
||||
- i++;
|
||||
}
|
||||
- }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/core/amci/amci.h b/core/amci/amci.h
|
||||
index 39b15cb..de6dbdb 100644
|
||||
--- a/core/amci/amci.h
|
||||
+++ b/core/amci/amci.h
|
||||
@@ -238,8 +238,10 @@ typedef void (*amci_codec_module_destroy_t)(void);
|
||||
/**
|
||||
* \brief Codec's init function pointer.
|
||||
*
|
||||
- * @param format_parameters [in] parameters as passed by fmtp tag, 0 if none
|
||||
- * @param format_description [out] pointer to describing block, with amci_codec_fmt_info_t array; zero-terminated. 0 if none
|
||||
+ * @param format_parameters [in] parameters as passed by fmtp tag, NULL if none
|
||||
+ * @param format_parameters_out [out] parameters passed back to fmtp, NULL if none
|
||||
+ * @param format_description [out] pointer to describing block, with amci_codec_fmt_info_t array; zero-terminated.
|
||||
+ NULL if none
|
||||
* <table><tr><td><b>key</b></td><td><b>value</b></td></tr>
|
||||
* <tr><td>AMCI_FMT_FRAME_LENGTH (1)</td><td> frame length in ms (for framed codecs; must be multiple of 10)</td></tr>
|
||||
* <tr><td>AMCI_FMT_FRAME_SIZE (2)</td><td> frame size in samples</td></tr>
|
||||
@@ -254,7 +256,8 @@ typedef void (*amci_codec_module_destroy_t)(void);
|
||||
int value;
|
||||
} amci_codec_fmt_info_t;
|
||||
|
||||
-typedef long (*amci_codec_init_t)(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
+ typedef long (*amci_codec_init_t)(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** fmt_info);
|
||||
|
||||
/**
|
||||
* \brief Codec's destroy function pointer.
|
||||
@@ -273,6 +276,11 @@ typedef unsigned int (*amci_codec_bytes2samples_t)(long h_codec, unsigned int nu
|
||||
typedef unsigned int (*amci_codec_samples2bytes_t)(long h_codec, unsigned int num_samples);
|
||||
|
||||
/**
|
||||
+ * \brief Codec's function for negotiating codec format; this needs to be dry-run, i.e. no codec instantiated
|
||||
+ */
|
||||
+typedef int (*amci_codec_negotiate_fmt_t)(int is_offer, const char* params_in, char* params_out, unsigned int params_out_len);
|
||||
+
|
||||
+/**
|
||||
* \brief Codec description
|
||||
*/
|
||||
struct amci_codec_t {
|
||||
@@ -302,6 +310,9 @@ struct amci_codec_t {
|
||||
|
||||
/** Function for calculating the number of samples from bytes. */
|
||||
amci_codec_samples2bytes_t samples2bytes;
|
||||
+
|
||||
+ /** function for dry-negotiating codec format - no codec instance is created */
|
||||
+ amci_codec_negotiate_fmt_t negotiate_fmt;
|
||||
};
|
||||
|
||||
/** \brief supported subtypes for a file */
|
||||
@@ -464,7 +475,7 @@ struct amci_exports_t {
|
||||
* @hideinitializer
|
||||
*/
|
||||
#define END_CODECS \
|
||||
- { -1, 0, 0, 0, 0, 0, 0, 0 } \
|
||||
+ { -1, 0, 0, 0, 0, 0, 0, 0, 0 } \
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -473,7 +484,14 @@ struct amci_exports_t {
|
||||
* @hideinitializer
|
||||
*/
|
||||
#define CODEC(id, intern2type,type2intern,plc,init,destroy,bytes2samples,samples2bytes) \
|
||||
- { id, intern2type, type2intern, plc, init, destroy, bytes2samples, samples2bytes },
|
||||
+ { id, intern2type, type2intern, plc, init, destroy, bytes2samples, samples2bytes, 0 },
|
||||
+
|
||||
+ /**
|
||||
+ A codec with negotiate_fmt function
|
||||
+ @hideinitializer
|
||||
+ */
|
||||
+#define CODEC_WITH_FMT(id, intern2type,type2intern,plc,init,destroy,bytes2samples,samples2bytes,negotiate_fmt) \
|
||||
+ { id, intern2type, type2intern, plc, init, destroy, bytes2samples, samples2bytes, negotiate_fmt},
|
||||
|
||||
/**
|
||||
* Portable export definition macro
|
||||
diff --git a/core/plug-in/adpcm/adpcm.c b/core/plug-in/adpcm/adpcm.c
|
||||
index ae2db28..4c6fc37 100644
|
||||
--- a/core/plug-in/adpcm/adpcm.c
|
||||
+++ b/core/plug-in/adpcm/adpcm.c
|
||||
@@ -40,7 +40,8 @@
|
||||
/* or ATM-AAL packing -> RFC3551 has the names AAL2-G726-xy for the big-endian packing */
|
||||
#define G726_PACK_RFC3551 1
|
||||
|
||||
-static long G726_create(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
+static long G726_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
static void G726_destroy(long h_inst);
|
||||
|
||||
static int Pcm16_2_G726_16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
|
||||
@@ -108,7 +109,8 @@ struct G726_twoway {
|
||||
struct g72x_state from_g726;
|
||||
};
|
||||
|
||||
-static long G726_create(const char* format_parameters, amci_codec_fmt_info_t* format_description) {
|
||||
+static long G726_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description) {
|
||||
struct G726_twoway* cinst = calloc(1, sizeof(struct G726_twoway));
|
||||
if (!cinst)
|
||||
return -1;
|
||||
@@ -116,7 +118,6 @@ static long G726_create(const char* format_parameters, amci_codec_fmt_info_t* fo
|
||||
g72x_init_state(&cinst->to_g726);
|
||||
g72x_init_state(&cinst->from_g726);
|
||||
|
||||
- format_description[0].id = 0;
|
||||
return (long) cinst;
|
||||
}
|
||||
|
||||
diff --git a/core/plug-in/g722/g722.c b/core/plug-in/g722/g722.c
|
||||
index de08f87..9ee9b63 100644
|
||||
--- a/core/plug-in/g722/g722.c
|
||||
+++ b/core/plug-in/g722/g722.c
|
||||
@@ -36,7 +36,8 @@ int Pcm16_2_G722NB( unsigned char* out_buf, unsigned char* in_buf, unsigned int
|
||||
int G722NB_2_Pcm16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
|
||||
unsigned int channels, unsigned int rate, long h_codec );
|
||||
|
||||
-long G722NB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
+long G722NB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
void G722NB_destroy(long handle);
|
||||
|
||||
static unsigned int G722NB_bytes2samples(long, unsigned int);
|
||||
@@ -67,7 +68,8 @@ typedef struct {
|
||||
} G722State;
|
||||
|
||||
|
||||
-long G722NB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description)
|
||||
+long G722NB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description)
|
||||
{
|
||||
G722State* gs;
|
||||
|
||||
diff --git a/core/plug-in/g729/g729.c b/core/plug-in/g729/g729.c
|
||||
index 4e0131e..d83f270 100644
|
||||
--- a/core/plug-in/g729/g729.c
|
||||
+++ b/core/plug-in/g729/g729.c
|
||||
@@ -56,12 +56,19 @@ static int pcm16_2_g729(unsigned char* out_buf, unsigned char* in_buf, unsigned
|
||||
static int g729_2_pcm16(unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
|
||||
unsigned int channels, unsigned int rate, long h_codec );
|
||||
|
||||
-static long g729_create(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
+static long g729_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
static void g729_destroy(long h_codec);
|
||||
|
||||
static unsigned int g729_bytes2samples(long, unsigned int);
|
||||
static unsigned int g729_samples2bytes(long, unsigned int);
|
||||
|
||||
+static amci_codec_fmt_info_t[] gsm_fmt_description = { { AMCI_FMT_FRAME_LENGTH, 20 },
|
||||
+ { AMCI_FMT_FRAME_SIZE, 160 },
|
||||
+ { AMCI_FMT_ENCODED_FRAME_SIZE, 33 },
|
||||
+ { 0, 0 }
|
||||
+};
|
||||
+
|
||||
#define G729_PAYLOAD_ID 18
|
||||
#define G729_BYTES_PER_FRAME 10
|
||||
#define G729_SAMPLES_PER_FRAME 10
|
||||
@@ -176,7 +183,8 @@ stream_destroy(struct stream *st)
|
||||
}
|
||||
|
||||
|
||||
-long g729_create(const char* format_parameters, amci_codec_fmt_info_t* format_description)
|
||||
+long g729_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description)
|
||||
{
|
||||
USC_CodecInfo pInfo;
|
||||
struct G729_codec *codec;
|
||||
diff --git a/core/plug-in/gsm/gsm.c b/core/plug-in/gsm/gsm.c
|
||||
index cf779c1..b8a5f67 100644
|
||||
--- a/core/plug-in/gsm/gsm.c
|
||||
+++ b/core/plug-in/gsm/gsm.c
|
||||
@@ -39,13 +39,18 @@ static int pcm16_2_gsm(unsigned char* out_buf, unsigned char* in_buf, unsigned i
|
||||
static int gsm_2_pcm16(unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
|
||||
unsigned int channels, unsigned int rate, long h_codec );
|
||||
|
||||
-static long gsm_create_if(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
+static long gsm_create_if(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
|
||||
static void gsm_destroy_if(long h_codec);
|
||||
|
||||
static unsigned int gsm_bytes2samples(long, unsigned int);
|
||||
static unsigned int gsm_samples2bytes(long, unsigned int);
|
||||
|
||||
+static amci_codec_fmt_info_t gsm_fmt_description[] = { {AMCI_FMT_FRAME_LENGTH, 20},
|
||||
+ {AMCI_FMT_FRAME_SIZE, 160},
|
||||
+ {AMCI_FMT_ENCODED_FRAME_SIZE, 33}, {0,0}};
|
||||
+
|
||||
BEGIN_EXPORTS( "gsm", AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY )
|
||||
|
||||
BEGIN_CODECS
|
||||
@@ -126,7 +131,8 @@ static int gsm_2_pcm16(unsigned char* out_buf, unsigned char* in_buf, unsigned i
|
||||
}
|
||||
|
||||
|
||||
-static long gsm_create_if(const char* format_parameters, amci_codec_fmt_info_t* format_description)
|
||||
+static long gsm_create_if(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description)
|
||||
{
|
||||
gsm* h_codec=0;
|
||||
|
||||
@@ -139,15 +145,8 @@ static long gsm_create_if(const char* format_parameters, amci_codec_fmt_info_t*
|
||||
h_codec[0] = gsm_create();
|
||||
h_codec[1] = gsm_create();
|
||||
|
||||
- format_description[0].id = AMCI_FMT_FRAME_LENGTH ;
|
||||
- format_description[0].value = 20;
|
||||
- format_description[1].id = AMCI_FMT_FRAME_SIZE;
|
||||
- format_description[1].value = 160;
|
||||
- format_description[2].id = AMCI_FMT_ENCODED_FRAME_SIZE;
|
||||
- format_description[2].value = 33;
|
||||
- format_description[3].id = 0;
|
||||
+ *format_description = gsm_fmt_description;
|
||||
|
||||
-
|
||||
return (long)h_codec;
|
||||
}
|
||||
|
||||
diff --git a/core/plug-in/ilbc/ilbc.c b/core/plug-in/ilbc/ilbc.c
|
||||
index bc60978..7f5eca9 100644
|
||||
--- a/core/plug-in/ilbc/ilbc.c
|
||||
+++ b/core/plug-in/ilbc/ilbc.c
|
||||
@@ -73,7 +73,8 @@ static int iLBC_PLC( unsigned char* out_buf, unsigned int size,
|
||||
|
||||
static int Pcm16_2_iLBC( unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
|
||||
unsigned int channels, unsigned int rate, long h_codec );
|
||||
-static long iLBC_create(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
+static long iLBC_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
static void iLBC_destroy(long h_inst);
|
||||
static int iLBC_open(FILE* fp, struct amci_file_desc_t* fmt_desc, int options, long h_codec);
|
||||
static int iLBC_close(FILE* fp, struct amci_file_desc_t* fmt_desc, int options, long h_codec, struct amci_codec_t *codec);
|
||||
@@ -81,6 +82,14 @@ static int iLBC_close(FILE* fp, struct amci_file_desc_t* fmt_desc, int options,
|
||||
static unsigned int ilbc_bytes2samples(long, unsigned int);
|
||||
static unsigned int ilbc_samples2bytes(long, unsigned int);
|
||||
|
||||
+static amci_codec_fmt_info_t ilbc_fmt_description_30[] = { {AMCI_FMT_FRAME_LENGTH, 30},
|
||||
+ {AMCI_FMT_FRAME_SIZE, 240},
|
||||
+ {AMCI_FMT_ENCODED_FRAME_SIZE, 50}, {0,0}};
|
||||
+
|
||||
+static amci_codec_fmt_info_t ilbc_fmt_description_20[] = { {AMCI_FMT_FRAME_LENGTH, 20},
|
||||
+ {AMCI_FMT_FRAME_SIZE, 160},
|
||||
+ {AMCI_FMT_ENCODED_FRAME_SIZE, 38}, {0,0}};
|
||||
+
|
||||
BEGIN_EXPORTS( "ilbc" , AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY )
|
||||
|
||||
BEGIN_CODECS
|
||||
@@ -129,7 +138,8 @@ static unsigned int ilbc_samples2bytes(long h_codec, unsigned int num_samples)
|
||||
return (num_samples / 160) * 38;
|
||||
}
|
||||
|
||||
-long iLBC_create(const char* format_parameters, amci_codec_fmt_info_t* format_description) {
|
||||
+long iLBC_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description) {
|
||||
|
||||
iLBC_Codec_Inst_t* codec_inst;
|
||||
int mode;
|
||||
@@ -156,14 +166,9 @@ long iLBC_create(const char* format_parameters, amci_codec_fmt_info_t* format_de
|
||||
}
|
||||
}
|
||||
}
|
||||
- format_description[0].id = AMCI_FMT_FRAME_LENGTH ;
|
||||
- format_description[0].value = mode;
|
||||
- format_description[1].id = AMCI_FMT_FRAME_SIZE;
|
||||
- format_description[1].value = mode==30 ? 240 : 160;
|
||||
- format_description[2].id = AMCI_FMT_ENCODED_FRAME_SIZE;
|
||||
- format_description[2].value = mode==30 ? 50 : 38;
|
||||
- format_description[3].id = 0;
|
||||
-
|
||||
+
|
||||
+ *format_description = (mode == 30) ? ilbc_fmt_description_30 : ilbc_fmt_description_20;
|
||||
+
|
||||
if (format_parameters) {
|
||||
DBG("ilbc with format parameters : '%s', mode=%d.\n", format_parameters, mode);
|
||||
}
|
||||
diff --git a/core/plug-in/isac/isac.c b/core/plug-in/isac/isac.c
|
||||
index 36c110f..9c771ae 100644
|
||||
--- a/core/plug-in/isac/isac.c
|
||||
+++ b/core/plug-in/isac/isac.c
|
||||
@@ -33,13 +33,15 @@ int Pcm16_2_iSAC( unsigned char* out_buf, unsigned char* in_buf, unsigned int si
|
||||
int iSAC_2_Pcm16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
|
||||
unsigned int channels, unsigned int rate, long h_codec );
|
||||
|
||||
-static long iSAC_create(const char* format_parameters,
|
||||
- amci_codec_fmt_info_t* format_description);
|
||||
+static long iSAC_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
static void iSAC_destroy(long handle);
|
||||
|
||||
static unsigned int iSAC_bytes2samples(long, unsigned int);
|
||||
static unsigned int iSAC_samples2bytes(long, unsigned int);
|
||||
|
||||
+static amci_codec_fmt_info_t isac_fmt_description[] = {{AMCI_FMT_FRAME_SIZE, iSAC_FRAME_MS * iSAC_SAMPLE_RATE / 1000}, {0,0}};
|
||||
+
|
||||
BEGIN_EXPORTS("isac", AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY)
|
||||
|
||||
BEGIN_CODECS
|
||||
@@ -62,8 +64,8 @@ END_FILE_FORMATS
|
||||
|
||||
END_EXPORTS
|
||||
|
||||
-static long iSAC_create(const char* format_parameters,
|
||||
- amci_codec_fmt_info_t* format_description)
|
||||
+static long iSAC_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description)
|
||||
{
|
||||
ISACStruct *iSAC_st=NULL;
|
||||
int err = WebRtcIsac_Create(&iSAC_st);
|
||||
@@ -85,11 +87,7 @@ static long iSAC_create(const char* format_parameters,
|
||||
return 0;
|
||||
}
|
||||
|
||||
- format_description[0].id = AMCI_FMT_FRAME_SIZE;
|
||||
- format_description[0].value = iSAC_FRAME_MS * iSAC_SAMPLE_RATE / 1000;
|
||||
- DBG("set AMCI_FMT_FRAME_SIZE to %d\n", format_description[0].value);
|
||||
-
|
||||
- format_description[1].id = 0;
|
||||
+ *format_description = isac_fmt_description;
|
||||
|
||||
return (long)iSAC_st;
|
||||
}
|
||||
diff --git a/core/plug-in/opus/opus.c b/core/plug-in/opus/opus.c
|
||||
index 8cb6f39..57a92bc 100644
|
||||
--- a/core/plug-in/opus/opus.c
|
||||
+++ b/core/plug-in/opus/opus.c
|
||||
@@ -84,7 +84,8 @@ static int opus_plc( unsigned char* out_buf, unsigned int size,
|
||||
|
||||
static int pcm16_2_opus( unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
|
||||
unsigned int channels, unsigned int rate, long h_codec );
|
||||
-static long opus_create(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
+static long opus_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
static void opus_destroy(long h_inst);
|
||||
|
||||
#if SYSTEM_SAMPLECLOCK_RATE >= 48000
|
||||
@@ -99,6 +100,9 @@ static void opus_destroy(long h_inst);
|
||||
#error Minimal sample rate for OPUS codec is 8000.
|
||||
#endif
|
||||
|
||||
+static amci_codec_fmt_info_t opus_fmt_description[] = { {AMCI_FMT_FRAME_LENGTH, 20},
|
||||
+ {AMCI_FMT_FRAME_SIZE, 20 * _OPUS_RATE / 1000}, {0,0}};
|
||||
+
|
||||
BEGIN_EXPORTS( "opus" , AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY )
|
||||
|
||||
BEGIN_CODECS
|
||||
@@ -122,19 +126,14 @@ typedef struct {
|
||||
OpusDecoder* opus_dec;
|
||||
} opus_state_t;
|
||||
|
||||
-long opus_create(const char* format_parameters, amci_codec_fmt_info_t* format_description) {
|
||||
+long opus_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description) {
|
||||
opus_state_t* codec_inst;
|
||||
int error;
|
||||
|
||||
if (format_parameters) {
|
||||
DBG("OPUS params: >>%s<<.\n", format_parameters);
|
||||
}
|
||||
-
|
||||
- format_description[0].id = AMCI_FMT_FRAME_LENGTH ;
|
||||
- format_description[0].value = 20;
|
||||
- format_description[1].id = AMCI_FMT_FRAME_SIZE;
|
||||
- format_description[1].value = 20 * _OPUS_RATE / 1000;
|
||||
- format_description[2].id = 0;
|
||||
|
||||
codec_inst = (opus_state_t*)malloc(sizeof(opus_state_t));
|
||||
|
||||
@@ -161,6 +160,8 @@ long opus_create(const char* format_parameters, amci_codec_fmt_info_t* format_de
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ *format_description = opus_fmt_description;
|
||||
+
|
||||
return (long)codec_inst;
|
||||
}
|
||||
|
||||
diff --git a/core/plug-in/silk/silk.c b/core/plug-in/silk/silk.c
|
||||
index 7bfd3ce..30326f8 100644
|
||||
--- a/core/plug-in/silk/silk.c
|
||||
+++ b/core/plug-in/silk/silk.c
|
||||
@@ -35,10 +35,14 @@ int Pcm16_2_SILK( unsigned char* out_buf, unsigned char* in_buf, unsigned int si
|
||||
int SILK_2_Pcm16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
|
||||
unsigned int channels, unsigned int rate, long h_codec );
|
||||
|
||||
-long SILK_NB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
-long SILK_MB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
-long SILK_WB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
-long SILK_UB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
+long SILK_NB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
+long SILK_MB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
+long SILK_WB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
+long SILK_UB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
void SILK_destroy(long handle);
|
||||
|
||||
static unsigned int SILK_bytes2samples(long, unsigned int);
|
||||
@@ -169,9 +173,7 @@ static int create_SILK_decoder(SILK_state* st,
|
||||
}
|
||||
|
||||
static long SILK_create(unsigned int rtp_Hz,
|
||||
- unsigned int avg_bit_rate,
|
||||
- const char* format_parameters,
|
||||
- amci_codec_fmt_info_t* format_description)
|
||||
+ unsigned int avg_bit_rate)
|
||||
{
|
||||
SILK_state* st = malloc(sizeof(SILK_state));
|
||||
if(st == NULL) {
|
||||
@@ -195,24 +197,28 @@ static long SILK_create(unsigned int rtp_Hz,
|
||||
return 0;
|
||||
}
|
||||
|
||||
-long SILK_NB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description)
|
||||
+long SILK_NB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description)
|
||||
{
|
||||
- return SILK_create(8000,20000,format_parameters,format_description);
|
||||
+ return SILK_create(8000,20000);
|
||||
}
|
||||
|
||||
-long SILK_MB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description)
|
||||
+long SILK_MB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description)
|
||||
{
|
||||
- return SILK_create(12000,25000,format_parameters,format_description);
|
||||
+ return SILK_create(12000,25000);
|
||||
}
|
||||
|
||||
-long SILK_WB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description)
|
||||
+long SILK_WB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description)
|
||||
{
|
||||
- return SILK_create(16000,30000,format_parameters,format_description);
|
||||
+ return SILK_create(16000,30000);
|
||||
}
|
||||
|
||||
-long SILK_UB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description)
|
||||
+long SILK_UB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description)
|
||||
{
|
||||
- return SILK_create(24000,40000,format_parameters,format_description);
|
||||
+ return SILK_create(24000,40000);
|
||||
}
|
||||
|
||||
void SILK_destroy(long handle)
|
||||
diff --git a/core/plug-in/speex/speex.c b/core/plug-in/speex/speex.c
|
||||
index 2917b17..992c841 100644
|
||||
--- a/core/plug-in/speex/speex.c
|
||||
+++ b/core/plug-in/speex/speex.c
|
||||
@@ -79,9 +79,12 @@ int Pcm16_2_Speex( unsigned char* out_buf, unsigned char* in_buf, unsigned int s
|
||||
int Speex_2_Pcm16( unsigned char* out_buf, unsigned char* in_buf, unsigned int size,
|
||||
unsigned int channels, unsigned int rate, long h_codec );
|
||||
|
||||
-long speexNB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
-long speexWB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
-long speexUB_create(const char* format_parameters, amci_codec_fmt_info_t* format_description);
|
||||
+long speexNB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
+long speexWB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
+long speexUB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description);
|
||||
void speex_destroy(long handle);
|
||||
|
||||
/* static unsigned int speex_bytes2samples(long, unsigned int); */
|
||||
@@ -130,9 +133,10 @@ typedef struct {
|
||||
unsigned int frames_per_packet; /* in samples */
|
||||
unsigned int frame_size;
|
||||
|
||||
+ amci_codec_fmt_info_t fmt_info[3];
|
||||
} SpeexState;
|
||||
|
||||
-#if 0
|
||||
+#if 0 /* SDP parameters ignored ? */
|
||||
|
||||
/*
|
||||
Search for a parameter assignement in input string.
|
||||
@@ -145,7 +149,7 @@ static char* read_param(char* input, const char *param, char** param_value)
|
||||
int param_size;
|
||||
|
||||
/* Eat spaces and semi-colons */
|
||||
- while (*input && *input==' ' && *input==';' && *input!='"')
|
||||
+ while (*input && (*input==' ' || *input==';' || *input=='"'))
|
||||
input++;
|
||||
|
||||
*param_value = NULL;
|
||||
@@ -222,7 +226,7 @@ void decode_format_parameters(const char* format_parameters, SpeexState* ss) {
|
||||
|
||||
long speex_create(unsigned int sample_rate,
|
||||
const char* format_parameters,
|
||||
- amci_codec_fmt_info_t* format_description)
|
||||
+ amci_codec_fmt_info_t** format_description)
|
||||
{
|
||||
int speex_mode = 0, on=1, quality=0;
|
||||
SpeexState* ss=NULL;
|
||||
@@ -272,17 +276,19 @@ long speex_create(unsigned int sample_rate,
|
||||
ss->decoder.state = speex_decoder_init(speex_lib_get_mode(speex_mode));
|
||||
speex_decoder_ctl(ss->decoder.state, SPEEX_SET_ENH, &on);
|
||||
|
||||
- format_description[0].id = AMCI_FMT_FRAME_LENGTH;
|
||||
- format_description[0].value = SPEEX_FRAME_MS * ss->frames_per_packet;
|
||||
+ ss->fmt_info[0].id = AMCI_FMT_FRAME_LENGTH;
|
||||
+ ss->fmt_info[0].value = SPEEX_FRAME_MS * ss->frames_per_packet;
|
||||
|
||||
ss->frame_size = SPEEX_FRAME_MS * (sample_rate / 1000);
|
||||
- format_description[1].id = AMCI_FMT_FRAME_SIZE;
|
||||
- format_description[1].value = ss->frame_size * ss->frames_per_packet;
|
||||
+ ss->fmt_info[1].id = AMCI_FMT_FRAME_SIZE;
|
||||
+ ss->fmt_info[1].value = ss->frame_size * ss->frames_per_packet;
|
||||
|
||||
- format_description[2].id = 0;
|
||||
+ ss->fmt_info[2].id = 0;
|
||||
|
||||
- DBG("set AMCI_FMT_FRAME_LENGTH to %d\n", format_description[0].value);
|
||||
- DBG("set AMCI_FMT_FRAME_SIZE to %d\n", format_description[1].value);
|
||||
+ *format_description = ss->fmt_info;
|
||||
+
|
||||
+ DBG("set AMCI_FMT_FRAME_LENGTH to %d\n", ss->fmt_info[0].value);
|
||||
+ DBG("set AMCI_FMT_FRAME_SIZE to %d\n", ss->fmt_info[1].value);
|
||||
|
||||
DBG("SpeexState %p inserted with %d frames per packet,\n",
|
||||
ss, ss->frames_per_packet);
|
||||
@@ -290,20 +296,20 @@ long speex_create(unsigned int sample_rate,
|
||||
return (long)ss;
|
||||
}
|
||||
|
||||
-long speexNB_create(const char* format_parameters,
|
||||
- amci_codec_fmt_info_t* format_description)
|
||||
+long speexNB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description)
|
||||
{
|
||||
return speex_create(8000,format_parameters,format_description);
|
||||
}
|
||||
|
||||
-long speexWB_create(const char* format_parameters,
|
||||
- amci_codec_fmt_info_t* format_description)
|
||||
+long speexWB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description)
|
||||
{
|
||||
return speex_create(16000,format_parameters,format_description);
|
||||
}
|
||||
|
||||
-long speexUB_create(const char* format_parameters,
|
||||
- amci_codec_fmt_info_t* format_description)
|
||||
+long speexUB_create(const char* format_parameters, const char** format_parameters_out,
|
||||
+ amci_codec_fmt_info_t** format_description)
|
||||
{
|
||||
return speex_create(32000,format_parameters,format_description);
|
||||
}
|
||||
--
|
||||
2.1.4
|
||||
|
||||
@ -1,42 +0,0 @@
|
||||
From 42df04a7b48e5a98ad73e003affebc77a10697d5 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Sayer <stefan.sayer@googlemail.com>
|
||||
Date: Thu, 29 Dec 2022 10:13:04 +0100
|
||||
Subject: MT#55831 core:amci: call codec module init function with
|
||||
mod_config_path param
|
||||
|
||||
(real ticket number: TT#13019)
|
||||
|
||||
---
|
||||
core/AmPlugIn.cpp | 2 +-
|
||||
core/amci/amci.h | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/core/AmPlugIn.cpp b/core/AmPlugIn.cpp
|
||||
index a677c17..3e82557 100644
|
||||
--- a/core/AmPlugIn.cpp
|
||||
+++ b/core/AmPlugIn.cpp
|
||||
@@ -526,7 +526,7 @@ int AmPlugIn::loadAudioPlugIn(amci_exports_t* exports)
|
||||
}
|
||||
|
||||
if (exports->module_load) {
|
||||
- if (exports->module_load() < 0) {
|
||||
+ if (exports->module_load(AmConfig::ModConfigPath.c_str()) < 0) {
|
||||
ERROR("initializing audio plug-in!\n");
|
||||
return -1;
|
||||
}
|
||||
diff --git a/core/amci/amci.h b/core/amci/amci.h
|
||||
index de6dbdb..68617f2 100644
|
||||
--- a/core/amci/amci.h
|
||||
+++ b/core/amci/amci.h
|
||||
@@ -227,7 +227,7 @@ typedef int (*amci_file_mem_close_t)( unsigned char* mptr,
|
||||
* this function initializes the codec module.
|
||||
* @return 0 on success, <0 on error
|
||||
*/
|
||||
-typedef int (*amci_codec_module_load_t)(void);
|
||||
+typedef int (*amci_codec_module_load_t)(const char* ModConfigPath);
|
||||
|
||||
/**
|
||||
* \brief Codec's module's destroy function pointer.
|
||||
--
|
||||
2.1.4
|
||||
|
||||
@ -1,63 +0,0 @@
|
||||
From c7800eabce5aeb190dc57484d1b550a81035f409 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Sayer <stefan.sayer@googlemail.com>
|
||||
Date: Thu, 29 Dec 2022 10:13:05 +0100
|
||||
Subject: MT#55831 core:rtp stream: take fmt params in payload initialization
|
||||
|
||||
(real ticket number: TT#13019)
|
||||
|
||||
---
|
||||
core/AmRtpAudio.cpp | 5 +++++
|
||||
core/AmRtpStream.cpp | 1 +
|
||||
core/AmRtpStream.h | 1 +
|
||||
3 files changed, 7 insertions(+)
|
||||
|
||||
diff --git a/core/AmRtpAudio.cpp b/core/AmRtpAudio.cpp
|
||||
index a6bd259..6df11e2 100644
|
||||
--- a/core/AmRtpAudio.cpp
|
||||
+++ b/core/AmRtpAudio.cpp
|
||||
@@ -44,6 +44,10 @@ AmAudioRtpFormat::~AmAudioRtpFormat()
|
||||
int AmAudioRtpFormat::setCurrentPayload(Payload pl)
|
||||
{
|
||||
if (this->codec_id != pl.codec_id) {
|
||||
+ DBG("setCurrentPayload({%u, '%s', %u, %u, %u, '%s'})\n",
|
||||
+ pl.pt, pl.name.c_str(), pl.clock_rate, pl.advertised_clock_rate,
|
||||
+ pl.codec_id, pl.format_parameters.c_str());
|
||||
+ log_demangled_stacktrace(3);
|
||||
this->codec_id = pl.codec_id;
|
||||
DBG("fmt.codec_id = %d", this->codec_id);
|
||||
this->channels = 1;
|
||||
@@ -52,6 +56,7 @@ int AmAudioRtpFormat::setCurrentPayload(Payload pl)
|
||||
this->advertized_rate = pl.advertised_clock_rate;
|
||||
DBG("fmt.advertized_rate = %d", this->advertized_rate);
|
||||
this->frame_size = 20*this->rate/1000;
|
||||
+ this->sdp_format_parameters = pl.format_parameters;
|
||||
DBG("fmt.sdp_format_parameters = %s", this->sdp_format_parameters.c_str());
|
||||
if (this->codec != NULL) {
|
||||
destroyCodec();
|
||||
diff --git a/core/AmRtpStream.cpp b/core/AmRtpStream.cpp
|
||||
index 00903cb..c580278 100644
|
||||
--- a/core/AmRtpStream.cpp
|
||||
+++ b/core/AmRtpStream.cpp
|
||||
@@ -636,6 +636,7 @@ int AmRtpStream::init(const AmSdp& local,
|
||||
p_it->codec_id = a_pl->codec_id;
|
||||
p_it->clock_rate = a_pl->sample_rate;
|
||||
p_it->advertised_clock_rate = sdp_it->clock_rate;
|
||||
+ p_it->format_parameters = sdp_it->sdp_format_parameters;
|
||||
|
||||
pl_map[sdp_it->payload_type].index = i;
|
||||
pl_map[sdp_it->payload_type].remote_pt = -1;
|
||||
diff --git a/core/AmRtpStream.h b/core/AmRtpStream.h
|
||||
index d1eb270..8396ab0 100644
|
||||
--- a/core/AmRtpStream.h
|
||||
+++ b/core/AmRtpStream.h
|
||||
@@ -137,6 +137,7 @@ struct Payload {
|
||||
unsigned int clock_rate;
|
||||
unsigned int advertised_clock_rate; // differs for G722
|
||||
int codec_id;
|
||||
+ string format_parameters;
|
||||
};
|
||||
|
||||
/**
|
||||
--
|
||||
2.1.4
|
||||
|
||||
@ -1,258 +0,0 @@
|
||||
From bbb13a13954da9e566b664f7916362dd0313e4d1 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Sayer <stefan.sayer@googlemail.com>
|
||||
Date: Thu, 29 Dec 2022 10:13:06 +0100
|
||||
Subject: MT#55831 opus: configurable codec settings for OPUS codec
|
||||
|
||||
opus.conf may contain an fmtp line with opus codec parameters,
|
||||
all in one line, e.g.
|
||||
maxplaybackrate=16000;stereo=0;useinbandfec=1
|
||||
|
||||
supported parameters:
|
||||
maxplaybackrate
|
||||
stereo
|
||||
useinbandfec
|
||||
(real ticket number: TT#13019)
|
||||
|
||||
---
|
||||
core/plug-in/opus/opus.c | 179 +++++++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 172 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/core/plug-in/opus/opus.c b/core/plug-in/opus/opus.c
|
||||
index 57a92bc..a8ad70e 100644
|
||||
--- a/core/plug-in/opus/opus.c
|
||||
+++ b/core/plug-in/opus/opus.c
|
||||
@@ -47,6 +47,7 @@
|
||||
*/
|
||||
|
||||
#include <opus/opus.h>
|
||||
+#include <stdio.h>
|
||||
|
||||
#define _OPUS_APPLICATION_ OPUS_APPLICATION_VOIP
|
||||
/* Allowed values:
|
||||
@@ -88,6 +89,10 @@ static long opus_create(const char* format_parameters, const char** format_param
|
||||
amci_codec_fmt_info_t** format_description);
|
||||
static void opus_destroy(long h_inst);
|
||||
|
||||
+static int opus_negotiate_fmt(int is_offer, const char* params_in, char* params_out, unsigned int params_out_len);
|
||||
+
|
||||
+static int opus_load(const char* ModConfigPath);
|
||||
+
|
||||
#if SYSTEM_SAMPLECLOCK_RATE >= 48000
|
||||
#define _OPUS_RATE 48000
|
||||
#elif SYSTEM_SAMPLECLOCK_RATE >= 24000
|
||||
@@ -103,13 +108,14 @@ static void opus_destroy(long h_inst);
|
||||
static amci_codec_fmt_info_t opus_fmt_description[] = { {AMCI_FMT_FRAME_LENGTH, 20},
|
||||
{AMCI_FMT_FRAME_SIZE, 20 * _OPUS_RATE / 1000}, {0,0}};
|
||||
|
||||
-BEGIN_EXPORTS( "opus" , AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY )
|
||||
+BEGIN_EXPORTS( "opus" , opus_load, AMCI_NO_MODULEDESTROY )
|
||||
|
||||
BEGIN_CODECS
|
||||
- CODEC( CODEC_OPUS, pcm16_2_opus, opus_2_pcm16, opus_plc,
|
||||
+ CODEC_WITH_FMT( CODEC_OPUS, pcm16_2_opus, opus_2_pcm16, opus_plc,
|
||||
opus_create,
|
||||
opus_destroy,
|
||||
- NULL, NULL )
|
||||
+ NULL, NULL ,
|
||||
+ opus_negotiate_fmt)
|
||||
END_CODECS
|
||||
|
||||
BEGIN_PAYLOADS
|
||||
@@ -126,13 +132,155 @@ typedef struct {
|
||||
OpusDecoder* opus_dec;
|
||||
} opus_state_t;
|
||||
|
||||
+/* e.g. "maxplaybackrate=8000; stereo=0; useinbandfec=1" */
|
||||
+char default_format_parameters[80];
|
||||
+
|
||||
+int opus_load(const char* ModConfigPath) {
|
||||
+ default_format_parameters[0]='\0';
|
||||
+ char conf_file[256];
|
||||
+ if (NULL != ModConfigPath) {
|
||||
+ sprintf(conf_file, "%sopus.conf",ModConfigPath);
|
||||
+ FILE* fp = fopen(conf_file, "rt");
|
||||
+ if (fp) {
|
||||
+ char line[80];
|
||||
+ while(fgets(line, 80, fp) != NULL) {
|
||||
+ if (!line[0] ||line[0]=='#')
|
||||
+ continue;
|
||||
+ strcpy(default_format_parameters, line);
|
||||
+ break;
|
||||
+ }
|
||||
+ DBG("initialized default format parameters as '%s'\n", default_format_parameters);
|
||||
+ fclose(fp);
|
||||
+ }
|
||||
+ }
|
||||
+ DBG("OPUS: initialized\n");
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int opus_negotiate_fmt(int is_offer, const char* params_in, char* params_out, unsigned int params_out_len) {
|
||||
+ // todo: properly negotiating features
|
||||
+ strncpy(params_out, default_format_parameters, params_out_len);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ Search for a parameter assignement in input string.
|
||||
+ If it's not found *param_value is null, otherwise *param_value points to the
|
||||
+ right hand term.
|
||||
+ In both cases a pointer suitable for a new search is returned
|
||||
+*/
|
||||
+static char* read_param(char* input, const char *param, char** param_value)
|
||||
+{
|
||||
+ int param_size;
|
||||
+
|
||||
+ /* Eat spaces and semi-colons */
|
||||
+ while (*input && (*input==' ' || *input==';' || *input=='"'))
|
||||
+ input++;
|
||||
+
|
||||
+ *param_value = NULL;
|
||||
+ param_size = strlen(param);
|
||||
+ if (strncmp(input, param, param_size))
|
||||
+ return input;
|
||||
+ if (*(input+param_size) != '=')
|
||||
+ return input;
|
||||
+ input+=param_size+1;
|
||||
+
|
||||
+ /* Found and discarded a matching parameter */
|
||||
+ *param_value = input;
|
||||
+ while (*input && *input!=' ' && *input!=';' && *input!='"')
|
||||
+ input++;
|
||||
+ if (*input=='"')
|
||||
+ {
|
||||
+ *param_value = *param_value+1; /* remove " */
|
||||
+ /* string will end after next: " */
|
||||
+ while (*input && *input!='"' && *input!='\r' && *input!='\n')
|
||||
+ input++;
|
||||
+ if (*input=='"')
|
||||
+ input--; /* remove " */
|
||||
+ }
|
||||
+ if (*input)
|
||||
+ *input++ = 0;
|
||||
+
|
||||
+ return input;
|
||||
+}
|
||||
+
|
||||
+#define BLEN 63
|
||||
+
|
||||
+void decode_format_parameters(const char* format_parameters, unsigned int* maxbandwidth, int* useinbandfec, int* stereo) {
|
||||
+ if (format_parameters && strlen(format_parameters)<=BLEN){
|
||||
+
|
||||
+ char buffer2[BLEN+1];
|
||||
+ char *buffer = buffer2;
|
||||
+
|
||||
+ strcpy(buffer, format_parameters);
|
||||
+
|
||||
+ while (*buffer) {
|
||||
+ char *param_value;
|
||||
+
|
||||
+ /* maxplaybackrate */
|
||||
+ buffer=read_param(buffer, "maxplaybackrate", ¶m_value);
|
||||
+ if (param_value) {
|
||||
+ *maxbandwidth = atoi(param_value);
|
||||
+ if (!*maxbandwidth) {
|
||||
+ *maxbandwidth = _OPUS_RATE;
|
||||
+ DBG("wrong maxbandwidth value '%s'\n", param_value);
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* stereo */
|
||||
+ buffer=read_param(buffer, "stereo", ¶m_value);
|
||||
+ if (param_value) {
|
||||
+ if (*param_value == '1')
|
||||
+ *stereo = 1;
|
||||
+ else
|
||||
+ *stereo = 0;
|
||||
+
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* useinbandfec */
|
||||
+ buffer=read_param(buffer, "useinbandfec", ¶m_value);
|
||||
+ if (param_value) {
|
||||
+ if (*param_value == '1')
|
||||
+ *useinbandfec = 1;
|
||||
+ else
|
||||
+ *useinbandfec = 0;
|
||||
+
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* Unknown parameter */
|
||||
+ if (*buffer) {
|
||||
+ param_value = buffer;
|
||||
+ while (*buffer && *buffer!=';')
|
||||
+ buffer++;
|
||||
+
|
||||
+ if (*buffer)
|
||||
+ *buffer++ = 0;
|
||||
+
|
||||
+ DBG("OPUS: SDP parameter fmtp: %s ignored in creating encoder.\n", param_value);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
long opus_create(const char* format_parameters, const char** format_parameters_out,
|
||||
amci_codec_fmt_info_t** format_description) {
|
||||
opus_state_t* codec_inst;
|
||||
int error;
|
||||
-
|
||||
+
|
||||
+ unsigned int maxbandwidth = _OPUS_RATE;
|
||||
+ int useinbandfec = _OPUS_INBAND_FEC_;
|
||||
+ int stereo = 0;
|
||||
+
|
||||
if (format_parameters) {
|
||||
+ DBG("\n\n\n");
|
||||
DBG("OPUS params: >>%s<<.\n", format_parameters);
|
||||
+ DBG("\n\n\n");
|
||||
+
|
||||
+ decode_format_parameters(format_parameters, &maxbandwidth, &useinbandfec, &stereo);
|
||||
}
|
||||
|
||||
codec_inst = (opus_state_t*)malloc(sizeof(opus_state_t));
|
||||
@@ -140,17 +288,34 @@ long opus_create(const char* format_parameters, const char** format_parameters_o
|
||||
if (!codec_inst)
|
||||
return -1;
|
||||
|
||||
+ DBG("OPUS: creating encoder with maxbandwidth=%u, stereo=%s, useinbandfec=%s\n",
|
||||
+ maxbandwidth, stereo?"true":"false", useinbandfec?"true":"false");
|
||||
+
|
||||
codec_inst->opus_enc = opus_encoder_create(_OPUS_RATE,1,_OPUS_APPLICATION_,&error);
|
||||
if (error) {
|
||||
DBG("OPUS: error %d while creating encoder state.\n", error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
- opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_FORCE_CHANNELS(1));
|
||||
- opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_MAX_BANDWIDTH(_OPUS_MAX_BANDWIDTH_));
|
||||
+ opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_FORCE_CHANNELS(stereo ? 2:1));
|
||||
+
|
||||
+ unsigned int opus_set_bw = _OPUS_RATE;
|
||||
+ if (maxbandwidth <= 8000) {
|
||||
+ opus_set_bw = OPUS_BANDWIDTH_NARROWBAND;
|
||||
+ } else if (maxbandwidth <= 12000) {
|
||||
+ opus_set_bw = OPUS_BANDWIDTH_MEDIUMBAND;
|
||||
+ } else if (maxbandwidth <= 16000) {
|
||||
+ opus_set_bw = OPUS_BANDWIDTH_WIDEBAND;
|
||||
+ } else if (maxbandwidth <= 24000) {
|
||||
+ opus_set_bw = OPUS_BANDWIDTH_SUPERWIDEBAND;
|
||||
+ } else {
|
||||
+ opus_set_bw = OPUS_BANDWIDTH_FULLBAND;
|
||||
+ }
|
||||
+ opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_MAX_BANDWIDTH(opus_set_bw));
|
||||
+
|
||||
opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_PACKET_LOSS_PERC(_OPUS_PKT_LOSS_PCT_));
|
||||
opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_COMPLEXITY(_OPUS_COMPLEXITY_));
|
||||
- opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_INBAND_FEC(_OPUS_INBAND_FEC_));
|
||||
+ opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_INBAND_FEC(useinbandfec ? 1:0));
|
||||
opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_DTX(_OPUS_DTX_));
|
||||
|
||||
codec_inst->opus_dec = opus_decoder_create(_OPUS_RATE,1,&error);
|
||||
--
|
||||
2.1.4
|
||||
|
||||
@ -1,27 +0,0 @@
|
||||
From f407e4dfec0f9e011db94b847c9f6f4b9156af93 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Sayer <stefan.sayer@googlemail.com>
|
||||
Date: Thu, 29 Dec 2022 10:13:07 +0100
|
||||
Subject: MT#55831 :fixes c7800ea: remove leftover stacktrace in
|
||||
setCurrentPayload
|
||||
|
||||
(real ticket number: TT#13019)
|
||||
|
||||
---
|
||||
core/AmRtpAudio.cpp | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/core/AmRtpAudio.cpp b/core/AmRtpAudio.cpp
|
||||
index 6df11e2..5d20a94 100644
|
||||
--- a/core/AmRtpAudio.cpp
|
||||
+++ b/core/AmRtpAudio.cpp
|
||||
@@ -47,7 +47,6 @@ int AmAudioRtpFormat::setCurrentPayload(Payload pl)
|
||||
DBG("setCurrentPayload({%u, '%s', %u, %u, %u, '%s'})\n",
|
||||
pl.pt, pl.name.c_str(), pl.clock_rate, pl.advertised_clock_rate,
|
||||
pl.codec_id, pl.format_parameters.c_str());
|
||||
- log_demangled_stacktrace(3);
|
||||
this->codec_id = pl.codec_id;
|
||||
DBG("fmt.codec_id = %d", this->codec_id);
|
||||
this->channels = 1;
|
||||
--
|
||||
2.1.4
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
From 0843bee8ae90a8d3cb35efa8485332b088e49183 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Sayer <stefan.sayer@googlemail.com>
|
||||
Date: Thu, 29 Dec 2022 10:13:08 +0100
|
||||
Subject: MT#55831 b/f:fix bbb13a1: remove excessive debug info
|
||||
|
||||
(real ticket number: TT#13019)
|
||||
|
||||
---
|
||||
core/plug-in/opus/opus.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/core/plug-in/opus/opus.c b/core/plug-in/opus/opus.c
|
||||
index a8ad70e..cc2b6e7 100644
|
||||
--- a/core/plug-in/opus/opus.c
|
||||
+++ b/core/plug-in/opus/opus.c
|
||||
@@ -276,10 +276,7 @@ long opus_create(const char* format_parameters, const char** format_parameters_o
|
||||
int stereo = 0;
|
||||
|
||||
if (format_parameters) {
|
||||
- DBG("\n\n\n");
|
||||
DBG("OPUS params: >>%s<<.\n", format_parameters);
|
||||
- DBG("\n\n\n");
|
||||
-
|
||||
decode_format_parameters(format_parameters, &maxbandwidth, &useinbandfec, &stereo);
|
||||
}
|
||||
|
||||
--
|
||||
2.1.4
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
From 4b2fc5d117242c659e4df0395c6e12f4fcb75edc Mon Sep 17 00:00:00 2001
|
||||
From: Peter Lemenkov <lemenkov@gmail.com>
|
||||
Date: Thu, 29 Dec 2022 10:13:09 +0100
|
||||
Subject: MT#55831 Fix for C++11
|
||||
|
||||
Fix for C++11
|
||||
|
||||
(real ticket number: TT#6431)
|
||||
---
|
||||
apps/sbc/RegisterCache.cpp | 2 +-
|
||||
apps/sbc/RegisterDialog.cpp | 2 +-
|
||||
core/sip/resolver.cpp | 2 +-
|
||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/apps/sbc/RegisterCache.cpp b/apps/sbc/RegisterCache.cpp
|
||||
index cbd3c30..5cd1235 100644
|
||||
--- a/apps/sbc/RegisterCache.cpp
|
||||
+++ b/apps/sbc/RegisterCache.cpp
|
||||
@@ -955,7 +955,7 @@ bool _RegisterCache::throttleRegister(RegisterCacheCtx& ctx,
|
||||
return false; // fwd
|
||||
}
|
||||
|
||||
- alias_updates.push_back(make_pair<string,long int>(reg_binding.alias,
|
||||
+ alias_updates.push_back(make_pair(reg_binding.alias,
|
||||
contact_expires));
|
||||
}
|
||||
|
||||
diff --git a/apps/sbc/RegisterDialog.cpp b/apps/sbc/RegisterDialog.cpp
|
||||
index 820e03d..88b94cb 100644
|
||||
--- a/apps/sbc/RegisterDialog.cpp
|
||||
+++ b/apps/sbc/RegisterDialog.cpp
|
||||
@@ -239,7 +239,7 @@ int RegisterDialog::fixUacContacts(const AmSipRequest& req)
|
||||
continue;
|
||||
}
|
||||
|
||||
- alias_updates.push_back(make_pair<string,long int>(reg_binding.alias,
|
||||
+ alias_updates.push_back(make_pair(reg_binding.alias,
|
||||
contact_expires));
|
||||
}
|
||||
|
||||
diff --git a/core/sip/resolver.cpp b/core/sip/resolver.cpp
|
||||
index 9793069..7bc6ff7 100644
|
||||
--- a/core/sip/resolver.cpp
|
||||
+++ b/core/sip/resolver.cpp
|
||||
@@ -823,7 +823,7 @@ dns_entry_map::insert(const dns_entry_map::value_type& x)
|
||||
bool dns_entry_map::insert(const string& key, dns_entry* e)
|
||||
{
|
||||
std::pair<iterator, bool> res =
|
||||
- insert(make_pair<const key_type&,mapped_type>(key,e));
|
||||
+ insert(make_pair(key,e));
|
||||
|
||||
if(res.second) {
|
||||
inc_ref(e);
|
||||
@ -1 +1 @@
|
||||
3.0 (quilt)
|
||||
3.0 (native)
|
||||
|
||||
Loading…
Reference in new issue