MT#55831 Stop using patching with quilt

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: Ifa4b4aabcc05802deff87f7a92ce857cc7d60d1e
mr11.2.1
Donat Zenichev 4 years ago
parent 544c77403c
commit 6c054d35d1

6
debian/changelog vendored

@ -1,3 +1,9 @@
ngcp-sems (1:1.6.0+0~mr11.2.0.0) unstable; urgency=medium
* New release.
-- Sipwise Jenkins Builder <jenkins@sipwise.com> Sun, 29 Dec 2022 16:32:00 +0200
ngcp-sems (1:1.6.0-1+0~mr11.2.0.0) unstable; urgency=medium
* New release.

@ -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", &param_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", &param_value);
+ if (param_value) {
+ if (*param_value == '1')
+ *stereo = 1;
+ else
+ *stereo = 0;
+
+ continue;
+ }
+
+ /* useinbandfec */
+ buffer=read_param(buffer, "useinbandfec", &param_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…
Cancel
Save