From 6c054d35d1cdf5afe101a1788ddbc86ad0ae27a5 Mon Sep 17 00:00:00 2001 From: Donat Zenichev Date: Thu, 29 Dec 2022 16:34:00 +0100 Subject: [PATCH] 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 --- debian/changelog | 6 + debian/patches/build-fix-bit-rot.patch | 130 - debian/patches/build-fix-excludes.patch | 74 - debian/patches/build-fix-pie.patch | 24 - debian/patches/build-system-revamp.patch | 1496 ------------ .../fix-build-with-newer-openssl.patch | 24 - debian/patches/no_config.patch | 62 - debian/patches/py_sems_path.patch | 16 - debian/patches/series | 45 - ...s-and-sems-pbx-to-write-pid-file-whe.patch | 67 - ...685-add_header_pattern_match_support.patch | 39 - ...erence-set-callgroup-to-conference-c.patch | 29 - .../patches/sipwise/0006-rename_xdigits.patch | 37 - ...ions-macros-for-modules-replaceParam.patch | 49 - ...15-confpin-simple-pin-conference-app.patch | 559 ----- ...reate-CF-map-if-CF-is-denied-by-prof.patch | 195 -- ...-username_with_domain-option-to-use-.patch | 165 -- ...T-1640-core_increase-max-config-line.patch | 19 - .../0020-TT-9521-fix-200OK-without-SPD.patch | 22 - .../MT-20649-add-vsc-for-block-in-clir | 244 -- .../sipwise/MT-20649-change-config-validation | 696 ------ debian/patches/sipwise/MT-20649-use-macros | 565 ----- .../sipwise/add-vsc-to-disable_all_cf.patch | 438 ---- ...rt_for_peering_outbound_registration.patch | 1816 -------------- ...ct_emergency_calls_and_let_them_pass.patch | 145 -- .../sipwise/db_reg_agent_auth_header.patch | 333 --- .../dsm_mod_curl_fix_ordered_comparison.patch | 47 - ...m_modutils_fix_utils_get_count_files.patch | 65 - .../sipwise/handle_bye_after_180.patch | 24 - .../sipwise/introduce_forcesdp_from_pbx.patch | 104 - debian/patches/sipwise/port_to_py3k.patch | 957 -------- debian/patches/sipwise/session_timers | 34 - ...p_outbound_auth_if_credentials_empty.patch | 34 - debian/patches/sipwise/sw_vcs.patch | 2093 ----------------- debian/patches/sipwise/tt52455.patch | 46 - .../patches/sipwise/upgrade_to_bullseye.patch | 19 - debian/patches/sipwise/usage-reporting.patch | 53 - ...eading-encoding-param-in-readPayload.patch | 27 - ...ompare-encoding_param-only-if-both-0.patch | 27 - ...support-for-fmt-params-negotiation-f.patch | 773 ------ ...odec-module-init-function-with-mod_c.patch | 42 - ...take-fmt-params-in-payload-initializ.patch | 63 - ...urable-codec-settings-for-OPUS-codec.patch | 258 -- ...a-remove-leftover-stacktrace-in-setC.patch | 27 - ...-bbb13a1-remove-excessive-debug-info.patch | 29 - .../patches/upstream/0008-fix-for-c++11.patch | 53 - debian/source/format | 2 +- 47 files changed, 7 insertions(+), 12065 deletions(-) delete mode 100644 debian/patches/build-fix-bit-rot.patch delete mode 100644 debian/patches/build-fix-excludes.patch delete mode 100644 debian/patches/build-fix-pie.patch delete mode 100644 debian/patches/build-system-revamp.patch delete mode 100644 debian/patches/fix-build-with-newer-openssl.patch delete mode 100644 debian/patches/no_config.patch delete mode 100644 debian/patches/py_sems_path.patch delete mode 100644 debian/patches/series delete mode 100644 debian/patches/sipwise/0001-TT-34704-Fix-sems-and-sems-pbx-to-write-pid-file-whe.patch delete mode 100644 debian/patches/sipwise/0001-TT-53685-add_header_pattern_match_support.patch delete mode 100644 debian/patches/sipwise/0002-b-f-dsm-mod_conference-set-callgroup-to-conference-c.patch delete mode 100644 debian/patches/sipwise/0006-rename_xdigits.patch delete mode 100644 debian/patches/sipwise/0008-dsm-helper-functions-macros-for-modules-replaceParam.patch delete mode 100644 debian/patches/sipwise/0015-confpin-simple-pin-conference-app.patch delete mode 100644 debian/patches/sipwise/0017-MT-13599-don-t-create-CF-map-if-CF-is-denied-by-prof.patch delete mode 100644 debian/patches/sipwise/0018-db_reg_agent-add-username_with_domain-option-to-use-.patch delete mode 100644 debian/patches/sipwise/0019-TT-1640-core_increase-max-config-line.patch delete mode 100644 debian/patches/sipwise/0020-TT-9521-fix-200OK-without-SPD.patch delete mode 100644 debian/patches/sipwise/MT-20649-add-vsc-for-block-in-clir delete mode 100644 debian/patches/sipwise/MT-20649-change-config-validation delete mode 100644 debian/patches/sipwise/MT-20649-use-macros delete mode 100644 debian/patches/sipwise/add-vsc-to-disable_all_cf.patch delete mode 100644 debian/patches/sipwise/add_support_for_peering_outbound_registration.patch delete mode 100644 debian/patches/sipwise/cpslimit_detect_emergency_calls_and_let_them_pass.patch delete mode 100644 debian/patches/sipwise/db_reg_agent_auth_header.patch delete mode 100644 debian/patches/sipwise/dsm_mod_curl_fix_ordered_comparison.patch delete mode 100644 debian/patches/sipwise/dsm_modutils_fix_utils_get_count_files.patch delete mode 100644 debian/patches/sipwise/handle_bye_after_180.patch delete mode 100644 debian/patches/sipwise/introduce_forcesdp_from_pbx.patch delete mode 100644 debian/patches/sipwise/port_to_py3k.patch delete mode 100644 debian/patches/sipwise/session_timers delete mode 100644 debian/patches/sipwise/skip_outbound_auth_if_credentials_empty.patch delete mode 100644 debian/patches/sipwise/sw_vcs.patch delete mode 100644 debian/patches/sipwise/tt52455.patch delete mode 100644 debian/patches/sipwise/upgrade_to_bullseye.patch delete mode 100644 debian/patches/sipwise/usage-reporting.patch delete mode 100644 debian/patches/upstream/0000-b-f-sbc-fixed-reading-encoding-param-in-readPayload.patch delete mode 100644 debian/patches/upstream/0001-b-f-sbc-codecs-compare-encoding_param-only-if-both-0.patch delete mode 100644 debian/patches/upstream/0002-core-codec-init-support-for-fmt-params-negotiation-f.patch delete mode 100644 debian/patches/upstream/0003-core-amci-call-codec-module-init-function-with-mod_c.patch delete mode 100644 debian/patches/upstream/0004-core-rtp-stream-take-fmt-params-in-payload-initializ.patch delete mode 100644 debian/patches/upstream/0005-opus-configurable-codec-settings-for-OPUS-codec.patch delete mode 100644 debian/patches/upstream/0006-b-f-fixes-c7800ea-remove-leftover-stacktrace-in-setC.patch delete mode 100644 debian/patches/upstream/0007-b-f-fix-bbb13a1-remove-excessive-debug-info.patch delete mode 100644 debian/patches/upstream/0008-fix-for-c++11.patch diff --git a/debian/changelog b/debian/changelog index bfffb7e6..3deaa1f0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +ngcp-sems (1:1.6.0+0~mr11.2.0.0) unstable; urgency=medium + + * New release. + + -- Sipwise Jenkins Builder 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. diff --git a/debian/patches/build-fix-bit-rot.patch b/debian/patches/build-fix-bit-rot.patch deleted file mode 100644 index e61bf54c..00000000 --- a/debian/patches/build-fix-bit-rot.patch +++ /dev/null @@ -1,130 +0,0 @@ -From efbb87f805fcf4325060c9dbfd6c92c01537886b Mon Sep 17 00:00:00 2001 -From: Guillem Jover -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(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& 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)"); - } diff --git a/debian/patches/build-fix-excludes.patch b/debian/patches/build-fix-excludes.patch deleted file mode 100644 index c1756ad6..00000000 --- a/debian/patches/build-fix-excludes.patch +++ /dev/null @@ -1,74 +0,0 @@ -From efbb87f805fcf4325060c9dbfd6c92c01537886d Mon Sep 17 00:00:00 2001 -From: Guillem Jover -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 *) ) - diff --git a/debian/patches/build-fix-pie.patch b/debian/patches/build-fix-pie.patch deleted file mode 100644 index 85a6f07f..00000000 --- a/debian/patches/build-fix-pie.patch +++ /dev/null @@ -1,24 +0,0 @@ -From efbb87f805fcf4325060c9dbfd6c92c01537886c Mon Sep 17 00:00:00 2001 -From: Guillem Jover -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) diff --git a/debian/patches/build-system-revamp.patch b/debian/patches/build-system-revamp.patch deleted file mode 100644 index 2505e17c..00000000 --- a/debian/patches/build-system-revamp.patch +++ /dev/null @@ -1,1496 +0,0 @@ -From efbb87f805fcf4325060c9dbfd6c92c01537886e Mon Sep 17 00:00:00 2001 -From: Guillem Jover -Date: Thu, 29 Dec 2022 10:14:16 +0100 -Subject: MT#55831 Revamp the build system - - - Make errors fatal, so that they do not get ignored anymore. - - Use sane make variables that a shell will accept as valid, otherwise - the exports do not work at all. - - Do not use system paths when we should use in-tree ones. - -(real ticket number: TT#6850) - ---- - ---- - Makefile | 13 +-- - Makefile.defs | 124 +++++++++++++++--------------- - apps/Makefile | 16 ++- - apps/diameter_client/lib_dbase/Makefile | 2 - apps/dsm/Makefile | 6 - - apps/dsm/mods/Makefile | 16 ++- - apps/dsm/mods/Makefile.dsm_module | 53 ++++++------ - apps/examples/Makefile | 16 ++- - apps/examples/out_of_tree/Makefile | 4 - apps/examples/tutorial/Makefile | 16 ++- - apps/ivr/Makefile | 6 - - apps/ivr/Makefile.ivr_application | 34 ++++---- - apps/monitoring/Makefile | 2 - apps/monitoring/tools/Makefile | 9 +- - apps/msg_storage/Makefile | 2 - apps/py_sems/Makefile | 8 - - apps/py_sems/Makefile.defs | 2 - apps/py_sems/Makefile.py_sems_application | 17 ++-- - apps/rtmp/flash_phone/Makefile | 8 + - apps/rtmp/librtmp/Makefile | 2 - apps/sbc/Makefile | 8 - - apps/sbc/call_control/Makefile | 14 ++- - apps/sbc/tools/Makefile | 9 +- - apps/voicemail/Makefile | 12 +- - apps/webconference/Makefile | 2 - apps/webconference/tools/Makefile | 9 +- - core/Makefile | 72 ++++++++--------- - core/plug-in/Makefile | 16 ++- - core/plug-in/Makefile.app_module | 53 ++++++------ - core/plug-in/Makefile.audio_module | 6 - - core/plug-in/gsm/gsm-1.0-pl10/Makefile | 56 ++++++------- - core/plug-in/ilbc/iLBC_rfc3951/Makefile | 2 - core/plug-in/stats/Makefile | 6 - - core/resample/Makefile | 4 - core/sip/Makefile | 4 - core/tests/Makefile | 18 ++-- - pkg/rpm/sems.spec | 20 ++-- - tools/Makefile | 15 +-- - 38 files changed, 363 insertions(+), 319 deletions(-) - ---- a/Makefile -+++ b/Makefile -@@ -12,8 +12,9 @@ subdirs = core apps tools - - .PHONY: clean - clean: -- -@rm -f *.so -- -@for r in $(subdirs) doc "" ; do \ -+ @rm -f *.so -+ @set -e; \ -+ for r in $(subdirs) doc "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "making $$r" ; \ -@@ -23,7 +24,8 @@ clean: - - .PHONY: modules - modules: -- -@for r in $(subdirs) "" ; do \ -+ @set -e; \ -+ for r in $(subdirs) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "making $$r" ; \ -@@ -33,7 +35,8 @@ modules: - - .PHONY: install - install: -- -@for r in $(subdirs) "" ; do \ -+ @set -e; \ -+ for r in $(subdirs) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -43,7 +46,7 @@ install: - @echo "" - @echo "*** install complete. Run SEMS with " - @echo "*** " -- @echo "*** $(bin-target)$(NAME) -f $(cfg-target)sems.conf" -+ @echo "*** $(bin_target)$(NAME) -f $(cfg_target)sems.conf" - - - .PHONY: dist ---- a/Makefile.defs -+++ b/Makefile.defs -@@ -261,55 +261,55 @@ BASEDIR ?= - basedir = $(BASEDIR) - - # Redhat users should use sems.redhat instead of sems --# the file will be to $(bin-prefix)/$(bin-dir)/sems copied. --start-script = sems.redhat -+# the file will be to $(bin_prefix)/$(bin_dir)/sems copied. -+start_script = sems.redhat - - # install prefixes for various stuff --cfg-prefix = $(basedir)$(prefix) --bin-prefix = $(basedir)$(prefix) --modules-prefix = $(basedir)$(prefix) --doc-prefix = $(basedir)$(prefix) --audio-prefix = $(basedir)$(prefix) --lib-prefix = $(basedir)$(prefix) -+cfg_prefix = $(basedir)$(prefix) -+bin_prefix = $(basedir)$(prefix) -+modules_prefix = $(basedir)$(prefix) -+doc_prefix = $(basedir)$(prefix) -+audio_prefix = $(basedir)$(prefix) -+lib_prefix = $(basedir)$(prefix) - - # dirs --cfg-dir = etc/$(APP_NAME)/ -+cfg_dir = etc/$(APP_NAME)/ - --bin-dir = sbin/ --modules-dir = lib/$(APP_NAME)/plug-in/ --audio-dir = lib/$(APP_NAME)/audio/ --lib-dir = lib/$(APP_NAME)/ -+bin_dir = sbin/ -+modules_dir = lib/$(APP_NAME)/plug-in/ -+audio_dir = lib/$(APP_NAME)/audio/ -+lib_dir = lib/$(APP_NAME)/ - - ifeq ($(OS), linux) -- doc-dir = share/doc/$(APP_NAME)/ -- man-dir = share/man/ -+ doc_dir = share/doc/$(APP_NAME)/ -+ man_dir = share/man/ - else - ifeq ($(OS), freebsd) -- doc-dir = share/doc/$(APP_NAME)/ -- man-dir = man/ -+ doc_dir = share/doc/$(APP_NAME)/ -+ man_dir = man/ - else - ifeq ($(OS), openbsd) -- doc-dir = share/doc/$(APP_NAME)/ -- man-dir = man/ -+ doc_dir = share/doc/$(APP_NAME)/ -+ man_dir = man/ - else - ifeq ($(OS), netbsd) -- doc-dir = share/doc/$(APP_NAME) -- man-dir = man/ -+ doc_dir = share/doc/$(APP_NAME) -+ man_dir = man/ - else -- doc-dir = doc/$(APP_NAME)/ -- man-dir = man/ -+ doc_dir = doc/$(APP_NAME)/ -+ man_dir = man/ - endif - endif - endif - endif - - # target dirs for various stuff --bin-target = $(prefix)/$(bin-dir) --cfg-target ?= $(prefix)/$(cfg-dir) --app-cfg-target = $(cfg-target)etc/ --modules-target = $(prefix)/$(modules-dir) --audio-target = $(prefix)/$(audio-dir) --lib-target = $(prefix)/$(lib-dir) -+bin_target = $(prefix)/$(bin_dir) -+cfg_target ?= $(prefix)/$(cfg_dir) -+app_cfg_target = $(cfg_target)etc/ -+modules_target = $(prefix)/$(modules_dir) -+audio_target = $(prefix)/$(audio_dir) -+lib_target = $(prefix)/$(lib_dir) - - ifeq ($(OS), solaris) - #use GNU versions -@@ -320,24 +320,24 @@ INSTALL ?= install - TAR ?= tar - endif - --INSTALL-TOUCH = touch # used to create the file first (good to -+INSTALL_TOUCH = touch # used to create the file first (good to - # make solaris install work) --INSTALL-CFG = $(INSTALL) -m 644 --INSTALL-BIN = $(INSTALL) -m 755 --INSTALL-MODULES = $(INSTALL) -m 755 --INSTALL-DOC = $(INSTALL) -m 644 --INSTALL-AUDIO = $(INSTALL) -m 644 -+INSTALL_CFG = $(INSTALL) -m 644 -+INSTALL_BIN = $(INSTALL) -m 755 -+INSTALL_MODULES = $(INSTALL) -m 755 -+INSTALL_DOC = $(INSTALL) -m 644 -+INSTALL_AUDIO = $(INSTALL) -m 644 - - #export stuff to sub-makes - export REL_VERSION RELEASE OS ARCH - export CPPFLAGS CXXFLAGS LDFLAGS CFLAGS LIB_LDFLAGS - export CXX CC LD --export DESTDIR PREFIX prefix basedir ser-prefix --export start-script --export cfg-prefix bin-prefix modules-prefix doc-prefix audio-prefix lib-prefix --export cfg-dir bin-dir modules-dir audio-dir lib-dir doc-dir man-dir --export bin-target cfg-target app-cfg-target modules-target audio-target lib-target --export INSTALL TAR INSTALL-TOUCH INSTALL-CFG INSTALL-BIN INSTALL-MODULES INSTALL-DOC INSTALL-AUDIO -+export DESTDIR PREFIX prefix basedir ser_prefix -+export start_script -+export cfg_prefix bin_prefix modules_prefix doc_prefix audio_prefix lib_prefix -+export cfg_dir bin_dir modules_dir audio_dir lib_dir doc_dir man_dir -+export bin_target cfg_target app_cfg_target modules_target audio_target lib_target -+export INSTALL TAR INSTALL_TOUCH INSTALL_CFG INSTALL_BIN INSTALL_MODULES INSTALL_DOC INSTALL_AUDIO - export APP_NAME - - export USE_SPANDSP LIBSPANDSP_STATIC LIBSPANDSP_LDIR -@@ -347,27 +347,27 @@ export USE_MONITORING - export exclude_core_modules exclude_app_modules - endif # ifeq ($(makefile_defs, 1) - --mk-install-dirs: $(DESTDIR)$(cfg-target) \ -- $(DESTDIR)$(app-cfg-target) \ -- $(DESTDIR)$(bin-prefix)/$(bin-dir) \ -- $(DESTDIR)$(modules-prefix)/$(modules-dir) \ -- $(DESTDIR)$(audio-prefix)/$(audio-dir) \ -- $(DESTDIR)$(doc-prefix)/$(doc-dir) -- --$(DESTDIR)$(cfg-target): -- mkdir -p $(DESTDIR)$(cfg-target) -- --$(DESTDIR)$(app-cfg-target): -- mkdir -p $(DESTDIR)$(app-cfg-target) -- --$(DESTDIR)$(bin-prefix)/$(bin-dir): -- mkdir -p $(DESTDIR)$(bin-prefix)/$(bin-dir) -+mk-install-dirs: $(DESTDIR)$(cfg_target) \ -+ $(DESTDIR)$(app_cfg_target) \ -+ $(DESTDIR)$(bin_prefix)/$(bin_dir) \ -+ $(DESTDIR)$(modules_prefix)/$(modules_dir) \ -+ $(DESTDIR)$(audio_prefix)/$(audio_dir) \ -+ $(DESTDIR)$(doc_prefix)/$(doc_dir) -+ -+$(DESTDIR)$(cfg_target): -+ mkdir -p $(DESTDIR)$(cfg_target) -+ -+$(DESTDIR)$(app_cfg_target): -+ mkdir -p $(DESTDIR)$(app_cfg_target) -+ -+$(DESTDIR)$(bin_prefix)/$(bin_dir): -+ mkdir -p $(DESTDIR)$(bin_prefix)/$(bin_dir) - --$(DESTDIR)$(modules-prefix)/$(modules-dir): -- mkdir -p $(DESTDIR)$(modules-prefix)/$(modules-dir) -+$(DESTDIR)$(modules_prefix)/$(modules_dir): -+ mkdir -p $(DESTDIR)$(modules_prefix)/$(modules_dir) - --$(DESTDIR)$(audio-prefix)/$(audio-dir): -- mkdir -p $(DESTDIR)$(audio-prefix)/$(audio-dir) -+$(DESTDIR)$(audio_prefix)/$(audio_dir): -+ mkdir -p $(DESTDIR)$(audio_prefix)/$(audio_dir) - --$(DESTDIR)$(doc-prefix)/$(doc-dir): -- mkdir -p $(DESTDIR)$(doc-prefix)/$(doc-dir) -+$(DESTDIR)$(doc_prefix)/$(doc_dir): -+ mkdir -p $(DESTDIR)$(doc_prefix)/$(doc_dir) ---- a/apps/Makefile -+++ b/apps/Makefile -@@ -41,8 +41,9 @@ all: modules - - .PHONY: clean - clean: -- -@rm -f *.so -- -@for r in $(app_modules) "" ; do \ -+ @rm -f *.so -+ @set -e; \ -+ for r in $(app_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "Cleaning $$r" ; \ -@@ -53,7 +54,8 @@ clean: - - .PHONY: modules - modules: -- -@for r in $(app_modules) "" ; do \ -+ @set -e; \ -+ for r in $(app_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "Making $$r" ; \ -@@ -67,7 +69,8 @@ install: install-bin - - .PHONY: install-bin - install-bin: -- -@for r in $(app_modules) "" ; do \ -+ @set -e; \ -+ for r in $(app_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "Installing $$r binaries" ; \ -@@ -77,8 +80,9 @@ install-bin: - done - - .PHONY: install-cfg --install-cfg: $(DESTDIR)$(cfg-target) -- -@for r in $(app_modules) "" ; do \ -+install-cfg: $(DESTDIR)$(cfg_target) -+ @set -e; \ -+ for r in $(app_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "Installing $$r configuration" ; \ ---- a/apps/diameter_client/lib_dbase/Makefile -+++ b/apps/diameter_client/lib_dbase/Makefile -@@ -25,7 +25,7 @@ RANLIB = ranlib - - .PHONY: clean - clean: -- -@rm -f $(objs) $(depends) $(lib_name) -+ @rm -f $(objs) $(depends) $(lib_name) - - -include $(depends) - ---- a/apps/dsm/Makefile -+++ b/apps/dsm/Makefile -@@ -12,10 +12,10 @@ COREPATH ?=../../core - include $(COREPATH)/plug-in/Makefile.app_module - - make_dsm_mods: -- -@$(MAKE) -C mods -+ @$(MAKE) -C mods - - install_dsm_mods: -- -@$(MAKE) -C mods/ install -+ @$(MAKE) -C mods/ install - - clean_dsm_mods: -- -@$(MAKE) -C mods/ clean -+ @$(MAKE) -C mods/ clean ---- a/apps/dsm/mods/Makefile -+++ b/apps/dsm/mods/Makefile -@@ -25,8 +25,9 @@ all: modules - - .PHONY: clean - clean: -- -@rm -f lib/*.so -- -@for r in $(dsm_modules) "" ; do \ -+ @rm -f lib/*.so -+ @set -e; \ -+ for r in $(dsm_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -36,7 +37,8 @@ clean: - - .PHONY: modules - modules: -- -@for r in $(dsm_modules) "" ; do \ -+ @set -e; \ -+ for r in $(dsm_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -49,7 +51,8 @@ install: install-bin - - .PHONY: install-bin - install-bin: -- -@for r in $(dsm_modules) "" ; do \ -+ @set -e; \ -+ for r in $(dsm_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -58,8 +61,9 @@ install-bin: - done - - .PHONY: install-cfg --install-cfg: $(DESTDIR)$(cfg-target) -- -@for r in $(dsm_modules) "" ; do \ -+install-cfg: $(DESTDIR)$(cfg_target) -+ @set -e; \ -+ for r in $(dsm_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ ---- a/apps/dsm/mods/Makefile.dsm_module -+++ b/apps/dsm/mods/Makefile.dsm_module -@@ -33,51 +33,54 @@ module_package: $(extra_target) $(lib_na - - .PHONY: clean - clean: $(extra_clean) -- -@rm -f $(objs) $(depends) $(lib_name) -+ @rm -f $(objs) $(depends) $(lib_name) - - .PHONY: install - install: all $(extra_install) -- mkdir -p $(DESTDIR)$(lib-prefix)/$(lib-dir)/dsm -+ mkdir -p $(DESTDIR)$(lib_prefix)/$(lib_dir)/dsm - if [ -f "$(lib_name)" ]; then \ -- $(INSTALL-TOUCH) $(DESTDIR)$(lib-prefix)/$(lib-dir)/dsm/; \ -- $(INSTALL-MODULES) $(lib_name) $(DESTDIR)$(lib-prefix)/$(lib-dir)/dsm/; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(lib_prefix)/$(lib_dir)/dsm/; \ -+ $(INSTALL_MODULES) $(lib_name) $(DESTDIR)$(lib_prefix)/$(lib_dir)/dsm/; \ - fi - - .PHONY: install-cfg - install-cfg: -- mkdir -p $(DESTDIR)$(cfg-target) -- -@for r in $(module_conf_files); do \ -+ mkdir -p $(DESTDIR)$(cfg_target) -+ @set -e; \ -+ for r in $(module_conf_files); do \ - echo installing $$r ; \ -- $(INSTALL-TOUCH) $(DESTDIR)$(cfg-target)$$r ; \ -- sed -e "s#/usr/.*lib/sems/audio/#$(audio-target)#g" \ -- -e "s#/usr/.*lib/sems/plug-in/#$(modules-target)#g" \ -- -e "s#/usr/.*lib/sems/ivr/#$(lib-target)ivr/#g" \ -- -e "s#/usr/.*lib/sems/dsm/#$(lib-target)dsm/#g" \ -- -e "s#/usr/.*lib/sems/py_sems/#$(lib-target)py_sems/#g" \ -- -e "s#/usr/.*etc/sems/#$(cfg-target)#g" \ -- < $$r > $(DESTDIR)$(cfg-target)$$r; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(cfg_target)$$r ; \ -+ sed -e "s#/usr/.*lib/sems/audio/#$(audio_target)#g" \ -+ -e "s#/usr/.*lib/sems/plug-in/#$(modules_target)#g" \ -+ -e "s#/usr/.*lib/sems/ivr/#$(lib_target)ivr/#g" \ -+ -e "s#/usr/.*lib/sems/dsm/#$(lib_target)dsm/#g" \ -+ -e "s#/usr/.*lib/sems/py_sems/#$(lib_target)py_sems/#g" \ -+ -e "s#/usr/.*etc/sems/#$(cfg_target)#g" \ -+ < $$r > $(DESTDIR)$(cfg_target)$$r; \ - done - --$(DESTDIR)(audio-prefix)/$(audio-dir): -- mkdir -p $(DESTDIR)$(audio-prefix)/$(audio-dir) -+$(DESTDIR)$(audio_prefix)/$(audio_dir): -+ mkdir -p $(DESTDIR)$(audio_prefix)/$(audio_dir) - - .PHONY: $(plug_in_name)_audio --$(plug_in_name)_audio: $(DESTDIR)$(audio-prefix)/$(audio-dir) -- mkdir -p $(DESTDIR)$(audio-prefix)/$(audio-dir)$(plug_in_name) -- -@for f in $(AUDIO_FILES) ; do \ -+$(plug_in_name)_audio: $(DESTDIR)$(audio_prefix)/$(audio_dir) -+ mkdir -p $(DESTDIR)$(audio_prefix)/$(audio_dir)$(plug_in_name) -+ @set -e; \ -+ for f in $(AUDIO_FILES) ; do \ - if [ -n "wav/$$f" ]; then \ -- $(INSTALL-TOUCH) $(DESTDIR)$(audio-prefix)/$(audio-dir)$(plug_in_name)/$$f; \ -- $(INSTALL-AUDIO) wav/$$f $(DESTDIR)$(audio-prefix)/$(audio-dir)$(plug_in_name)/$$f; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(audio_prefix)/$(audio_dir)$(plug_in_name)/$$f; \ -+ $(INSTALL_AUDIO) wav/$$f $(DESTDIR)$(audio_prefix)/$(audio_dir)$(plug_in_name)/$$f; \ - fi ; \ - done - - .PHONY: $(plug_in_name)_lib - $(plug_in_name)_lib: -- mkdir -p $(DESTDIR)$(lib-prefix)/$(lib-dir)/$(plug_in_name) -- -@for f in $(EXTRA_LIB_FILES) ; do \ -+ mkdir -p $(DESTDIR)$(lib_prefix)/$(lib_dir)/$(plug_in_name) -+ @set -e; \ -+ for f in $(EXTRA_LIB_FILES) ; do \ - if [ -n "$(EXTRA_LIB_DIR)/$$f" ]; then \ -- $(INSTALL-TOUCH) $(DESTDIR)$(lib-prefix)/$(lib-dir)/$(plug_in_name)/$$f; \ -- $(INSTALL-AUDIO) $(EXTRA_LIB_DIR)$$f $(DESTDIR)$(lib-prefix)/$(lib-dir)/$(plug_in_name)/$$f; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(lib_prefix)/$(lib_dir)/$(plug_in_name)/$$f; \ -+ $(INSTALL_AUDIO) $(EXTRA_LIB_DIR)$$f $(DESTDIR)$(lib_prefix)/$(lib_dir)/$(plug_in_name)/$$f; \ - fi ; \ - done - ---- a/apps/examples/Makefile -+++ b/apps/examples/Makefile -@@ -13,8 +13,9 @@ all: modules - - .PHONY: clean - clean: -- -@rm -f *.so -- -@for r in $(modules) "" ; do \ -+ @rm -f *.so -+ @set -e; \ -+ for r in $(modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -24,7 +25,8 @@ clean: - - .PHONY: modules - modules: -- -@for r in $(modules) "" ; do \ -+ @set -e; \ -+ for r in $(modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -37,7 +39,8 @@ install: install-bin - - .PHONY: install-bin - install-bin: -- -@for r in $(modules) "" ; do \ -+ @set -e; \ -+ for r in $(modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -46,8 +49,9 @@ install-bin: - done - - .PHONY: install-cfg --install-cfg: $(DESTDIR)$(cfg-target) -- -@for r in $(modules) "" ; do \ -+install-cfg: $(DESTDIR)$(cfg_target) -+ @set -e; \ -+ for r in $(modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ ---- a/apps/examples/out_of_tree/Makefile -+++ b/apps/examples/out_of_tree/Makefile -@@ -3,8 +3,8 @@ plug_in_name = myapp - module_ldflags = - module_cflags = - --COREPATH ?=/usr/include/sems --DEFSPATH ?=/usr/include/sems -+COREPATH ?=$(CURDIR)/../../../core -+DEFSPATH ?=$(COREPATH)/.. - app_module_dir=. - - include $(COREPATH)/plug-in/Makefile.app_module ---- a/apps/examples/tutorial/Makefile -+++ b/apps/examples/tutorial/Makefile -@@ -13,8 +13,9 @@ all: modules - - .PHONY: clean - clean: -- -@rm -f *.so -- -@for r in $(modules) "" ; do \ -+ @rm -f *.so -+ @set -e; \ -+ for r in $(modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -24,7 +25,8 @@ clean: - - .PHONY: modules - modules: -- -@for r in $(modules) "" ; do \ -+ @set -e; \ -+ for r in $(modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -37,7 +39,8 @@ install: install-bin - - .PHONY: install-bin - install-bin: -- -@for r in $(modules) "" ; do \ -+ @set -e; \ -+ for r in $(modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -46,8 +49,9 @@ install-bin: - done - - .PHONY: install-cfg --install-cfg: $(DESTDIR)$(cfg-target) -- -@for r in $(modules) "" ; do \ -+install-cfg: $(DESTDIR)$(cfg_target) -+ @set -e; \ -+ for r in $(modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ ---- a/apps/ivr/Makefile -+++ b/apps/ivr/Makefile -@@ -91,12 +91,12 @@ endif - endif - - .PHONY: install_python_files --install_python_files: $(DESTDIR)$(modules-prefix)/$(modules-dir) -+install_python_files: $(DESTDIR)$(modules_prefix)/$(modules_dir) - echo "Installing Python object files..." - for f in $(py_obj) ; do \ - if [ -n "py/$$f" ]; then \ -- $(INSTALL-TOUCH) $(DESTDIR)$(modules-prefix)/$(modules-dir)/$$f; \ -- $(INSTALL-MODULES) py/$$f $(DESTDIR)$(modules-prefix)/$(modules-dir)/$$f; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(modules_prefix)/$(modules_dir)/$$f; \ -+ $(INSTALL_MODULES) py/$$f $(DESTDIR)$(modules_prefix)/$(modules_dir)/$$f; \ - fi ; \ - done - ---- a/apps/ivr/Makefile.ivr_application -+++ b/apps/ivr/Makefile.ivr_application -@@ -10,9 +10,9 @@ include $(COREPATH)/../Makefile.defs - include $(IVRPATH)/Makefile.defs - - # --ivr-modules-dir?=lib/$(APP_NAME)/ivr -+ivr_modules_dir?=lib/$(APP_NAME)/ivr - --LIB_INSTALLDIR?=$(modules-prefix)/$(ivr-modules-dir) -+LIB_INSTALLDIR?=$(modules_prefix)/$(ivr_modules_dir) - TARBALL_PREFIX=sems-app-${NAME} - TARBALL="${TARBALL_PREFIX}-${VERSION}.tar.gz" - -@@ -50,26 +50,28 @@ endif - - .PHONY: install-cfg - install-cfg: -- mkdir -p $(DESTDIR)$(app-cfg-target) -- -@for r in $(module_conf_files); do \ -+ mkdir -p $(DESTDIR)$(app_cfg_target) -+ @set -e; \ -+ for r in $(module_conf_files); do \ - echo installing $$r ; \ -- $(INSTALL-TOUCH) $(DESTDIR)$(app-cfg-target)$$r ; \ -- sed -e "s#/usr/.*lib/sems/audio/#$(audio-target)#g" \ -- -e "s#/usr/.*lib/sems/plug-in/#$(modules-target)#g" \ -- -e "s#/usr/.*etc/sems/#$(app-cfg-target)#g" \ -- < etc/$$r > $(DESTDIR)$(app-cfg-target)$$r; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(app_cfg_target)$$r ; \ -+ sed -e "s#/usr/.*lib/sems/audio/#$(audio_target)#g" \ -+ -e "s#/usr/.*lib/sems/plug-in/#$(modules_target)#g" \ -+ -e "s#/usr/.*etc/sems/#$(app_cfg_target)#g" \ -+ < etc/$$r > $(DESTDIR)$(app_cfg_target)$$r; \ - done - --$(DESTDIR)(audio-prefix)/$(audio-dir): -- mkdir -p $(DESTDIR)$(audio-prefix)/$(audio-dir) -+$(DESTDIR)$(audio_prefix)/$(audio_dir): -+ mkdir -p $(DESTDIR)$(audio_prefix)/$(audio_dir) - - .PHONY: $(NAME)_audio --$(NAME)_audio: $(DESTDIR)$(audio-prefix)/$(audio-dir) -- mkdir -p $(DESTDIR)$(audio-prefix)/$(audio-dir)$(NAME) -- -@for f in $(AUDIO_FILES) ; do \ -+$(NAME)_audio: $(DESTDIR)$(audio_prefix)/$(audio_dir) -+ mkdir -p $(DESTDIR)$(audio_prefix)/$(audio_dir)$(NAME) -+ @set -e; \ -+ for f in $(AUDIO_FILES) ; do \ - if [ -n "wav/$$f" ]; then \ -- $(INSTALL-TOUCH) $(DESTDIR)$(audio-prefix)/$(audio-dir)$(NAME)/$$f; \ -- $(INSTALL-AUDIO) wav/$$f $(DESTDIR)$(audio-prefix)/$(audio-dir)$(NAME)/$$f; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(audio_prefix)/$(audio_dir)$(NAME)/$$f; \ -+ $(INSTALL_AUDIO) wav/$$f $(DESTDIR)$(audio_prefix)/$(audio_dir)$(NAME)/$$f; \ - fi ; \ - done - ---- a/apps/monitoring/Makefile -+++ b/apps/monitoring/Makefile -@@ -9,4 +9,4 @@ COREPATH ?=../../core - include $(COREPATH)/plug-in/Makefile.app_module - - install_tools: -- -@$(MAKE) -C tools/ install -+ @$(MAKE) -C tools/ install ---- a/apps/monitoring/tools/Makefile -+++ b/apps/monitoring/tools/Makefile -@@ -6,12 +6,13 @@ monitoring_scripts = $(wildcard sems-*) - all: install_tools - install: install_tools - --install_tools: $(DESTDIR)$(bin-prefix)/$(bin-dir) -- -@for r in $(monitoring_scripts) ; do \ -+install_tools: $(DESTDIR)$(bin_prefix)/$(bin_dir) -+ @set -e; \ -+ for r in $(monitoring_scripts) ; do \ - x=`echo $$r | sed s/sems-/$(APP_NAME)-/g` ; \ - echo "installing $$r -> $$x" ; \ -- $(INSTALL-TOUCH) $(DESTDIR)$(bin-prefix)/$(bin-dir)/$$x ; \ -- $(INSTALL-BIN) $$r $(DESTDIR)$(bin-prefix)/$(bin-dir)/$$x ; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(bin_prefix)/$(bin_dir)/$$x ; \ -+ $(INSTALL_BIN) $$r $(DESTDIR)$(bin_prefix)/$(bin_dir)/$$x ; \ - done - - ---- a/apps/msg_storage/Makefile -+++ b/apps/msg_storage/Makefile -@@ -9,4 +9,4 @@ COREPATH ?=../../core - include $(COREPATH)/plug-in/Makefile.app_module - - spooldir: -- -mkdir -p $(DESTDIR)/var/spool/voicebox -+ mkdir -p $(DESTDIR)/var/spool/voicebox ---- a/apps/py_sems/Makefile -+++ b/apps/py_sems/Makefile -@@ -85,17 +85,17 @@ endif - endif - - .PHONY: install_python_files --install_python_files: $(DESTDIR)$(modules-prefix)/$(modules-dir) -+install_python_files: $(DESTDIR)$(modules_prefix)/$(modules_dir) - echo "Installing Python object files..." - for f in $(py_obj) ; do \ - if [ -n "py/$$f" ]; then \ -- $(INSTALL-TOUCH) $(DESTDIR)$(modules-prefix)/$(modules-dir)/$$f; \ -- $(INSTALL-MODULES) py/$$f $(DESTDIR)$(modules-prefix)/$(modules-dir)/$$f; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(modules_prefix)/$(modules_dir)/$$f; \ -+ $(INSTALL_MODULES) py/$$f $(DESTDIR)$(modules_prefix)/$(modules_dir)/$$f; \ - fi ; \ - done - - echo "Installing py_sems script path..." -- $(INSTALL-MODULES) -d $(DESTDIR)$(modules-prefix)/$(py-sems-modules-dir) -+ $(INSTALL_MODULES) -d $(DESTDIR)$(modules_prefix)/$(py_sems_modules_dir) - - .PHONY: clean_py_sems_lib - clean_py_sems_lib: ---- a/apps/py_sems/Makefile.defs -+++ b/apps/py_sems/Makefile.defs -@@ -15,4 +15,4 @@ PYTHON_DIR = $(shell $(PY_EXE) ./python_ - PYTHON_LIBDIR = $(shell $(PY_EXE) ./python_lib.py) - - # --py-sems-modules-dir?=lib/$(APP_NAME)/py_sems -+py_sems_modules_dir?=lib/$(APP_NAME)/py_sems ---- a/apps/py_sems/Makefile.py_sems_application -+++ b/apps/py_sems/Makefile.py_sems_application -@@ -7,7 +7,7 @@ PYSEMSPATH ?= ../py_sems - include $(COREPATH)/../Makefile.defs - include $(PYSEMSPATH)/Makefile.defs - --LIB_INSTALLDIR?=$(modules-prefix)/$(py-sems-modules-dir) -+LIB_INSTALLDIR?=$(modules_prefix)/$(py_sems_modules_dir) - TARBALL_PREFIX=sems-app-${NAME} - TARBALL="${TARBALL_PREFIX}-${VERSION}.tar.gz" - -@@ -42,14 +42,15 @@ install: all - - .PHONY: install-cfg - install-cfg: -- mkdir -p $(cfg-target) -- -@for r in $(module_conf_files); do \ -+ mkdir -p $(cfg_target) -+ @set -e; \ -+ for r in $(module_conf_files); do \ - echo installing $$r ; \ -- $(INSTALL-TOUCH) $(cfg-target)$$r ; \ -- sed -e "s#/usr/.*lib/sems/audio/#$(audio-target)#g" \ -- -e "s#/usr/.*lib/sems/plug-in/#$(modules-target)#g" \ -- -e "s#/usr/.*etc/sems/#$(cfg-target)#g" \ -- < etc/$$r > $(DESTDIR)$(cfg-target)$$r; \ -+ $(INSTALL_TOUCH) $(cfg_target)$$r ; \ -+ sed -e "s#/usr/.*lib/sems/audio/#$(audio_target)#g" \ -+ -e "s#/usr/.*lib/sems/plug-in/#$(modules_target)#g" \ -+ -e "s#/usr/.*etc/sems/#$(cfg_target)#g" \ -+ < etc/$$r > $(DESTDIR)$(cfg_target)$$r; \ - done - - ---- a/apps/rtmp/flash_phone/Makefile -+++ b/apps/rtmp/flash_phone/Makefile -@@ -21,10 +21,14 @@ MXMLC_OPTS= \ - APP=sono - SOURCES= $(APP).mxml $(wildcard *.as) - --all: $(APP).swf -+ifneq ($(wildcard $(FLEX_SDK)),) -+TARGET=$(APP).swf -+endif -+ -+all: $(TARGET) - - clean: -- rm *.swf -+ rm -f *.swf - - %.swf: $(SOURCES) Makefile - $(MXMLC) $(MXMLC_OPTS) $< ---- a/apps/rtmp/librtmp/Makefile -+++ b/apps/rtmp/librtmp/Makefile -@@ -78,7 +78,7 @@ librtmp.pc: librtmp.pc.in Makefile - install: install_base $(SO_INST) - - install_base: librtmp.a librtmp.pc -- -mkdir -p $(INCDIR) $(LIBDIR)/pkgconfig $(MANDIR)/man3 -+ mkdir -p $(INCDIR) $(LIBDIR)/pkgconfig $(MANDIR)/man3 - cp amf.h http.h log.h rtmp.h $(INCDIR) - cp librtmp.a $(LIBDIR) - cp librtmp.pc $(LIBDIR)/pkgconfig ---- a/apps/sbc/Makefile -+++ b/apps/sbc/Makefile -@@ -11,15 +11,15 @@ COREPATH ?= ../../core - include $(COREPATH)/plug-in/Makefile.app_module - - install_tools: -- -@$(MAKE) -C tools/ install -+ @$(MAKE) -C tools/ install - - make_call_control_mods: -- -@$(MAKE) -C call_control -+ @$(MAKE) -C call_control - - install_call_control_mods: -- -@$(MAKE) -C call_control/ install -+ @$(MAKE) -C call_control/ install - - clean_call_control_mods: -- -@$(MAKE) -C call_control/ clean -+ @$(MAKE) -C call_control/ clean - - ---- a/apps/sbc/call_control/Makefile -+++ b/apps/sbc/call_control/Makefile -@@ -16,7 +16,8 @@ all: modules - - .PHONY: clean - clean: -- -@for r in $(cc_modules) "" ; do \ -+ @set -e; \ -+ for r in $(cc_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -26,7 +27,8 @@ clean: - - .PHONY: modules - modules: -- -@for r in $(cc_modules) "" ; do \ -+ @set -e; \ -+ for r in $(cc_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -39,7 +41,8 @@ install: install-bin install-cfg - - .PHONY: install-bin - install-bin: -- -@for r in $(cc_modules) "" ; do \ -+ @set -e; \ -+ for r in $(cc_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -48,8 +51,9 @@ install-bin: - done - - .PHONY: install-cfg --install-cfg: $(DESTDIR)$(cfg-target) -- -@for r in $(dsm_modules) "" ; do \ -+install-cfg: $(DESTDIR)$(cfg_target) -+ @set -e; \ -+ for r in $(dsm_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ ---- a/apps/sbc/tools/Makefile -+++ b/apps/sbc/tools/Makefile -@@ -8,12 +8,13 @@ sbc_scripts = $(wildcard sems-sbc-*) - all: install_tools - install: install_tools - --install_tools: $(DESTDIR)$(bin-prefix)/$(bin-dir) -- -@for r in $(sbc_scripts) ; do \ -+install_tools: $(DESTDIR)$(bin_prefix)/$(bin_dir) -+ @set -e; \ -+ for r in $(sbc_scripts) ; do \ - x=`echo $$r | sed s/sems-/$(APP_NAME)-/g` ; \ - echo "installing $$r -> $$x" ; \ -- $(INSTALL-TOUCH) $(DESTDIR)$(bin-prefix)/$(bin-dir)/$$x ; \ -- $(INSTALL-BIN) $$r $(DESTDIR)$(bin-prefix)/$(bin-dir)/$$x ; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(bin_prefix)/$(bin_dir)/$$x ; \ -+ $(INSTALL_BIN) $$r $(DESTDIR)$(bin_prefix)/$(bin_dir)/$$x ; \ - done - - ---- a/apps/voicemail/Makefile -+++ b/apps/voicemail/Makefile -@@ -21,12 +21,12 @@ extra_install = install_email_template $ - vm_module: all - - .PHONY: install_email_template --install_email_template: $(DESTDIR)$(app-cfg-target) -- $(INSTALL-TOUCH) $(DESTDIR)$(app-cfg-target)default.template.sample -- $(INSTALL-CFG) default.template.sample $(DESTDIR)$(app-cfg-target) -- if [ ! -f $(DESTDIR)$(app-cfg-target)default.template ]; then \ -- cp -f $(DESTDIR)$(app-cfg-target)default.template.sample \ -- $(DESTDIR)$(app-cfg-target)default.template; \ -+install_email_template: $(DESTDIR)$(app_cfg_target) -+ $(INSTALL_TOUCH) $(DESTDIR)$(app_cfg_target)default.template.sample -+ $(INSTALL_CFG) default.template.sample $(DESTDIR)$(app_cfg_target) -+ if [ ! -f $(DESTDIR)$(app_cfg_target)default.template ]; then \ -+ cp -f $(DESTDIR)$(app_cfg_target)default.template.sample \ -+ $(DESTDIR)$(app_cfg_target)default.template; \ - fi - - ---- a/apps/webconference/Makefile -+++ b/apps/webconference/Makefile -@@ -9,4 +9,4 @@ COREPATH ?=../../core - include $(COREPATH)/plug-in/Makefile.app_module - - install_tools: -- -@$(MAKE) -C tools/ install -+ @$(MAKE) -C tools/ install ---- a/apps/webconference/tools/Makefile -+++ b/apps/webconference/tools/Makefile -@@ -7,12 +7,13 @@ wc_scripts = $(wildcard sems-webconferen - all: install_tools - install: install_tools - --install_tools: $(DESTDIR)$(bin-prefix)/$(bin-dir) -- -@for r in $(wc_scripts) ; do \ -+install_tools: $(DESTDIR)$(bin_prefix)/$(bin_dir) -+ @set -e; \ -+ for r in $(wc_scripts) ; do \ - x=`echo $$r | sed s/sems-/$(APP_NAME)-/g` ; \ - echo "installing $$r -> $$x" ; \ -- $(INSTALL-TOUCH) $(DESTDIR)$(bin-prefix)/$(bin-dir)/$$x ; \ -- $(INSTALL-BIN) $$r $(DESTDIR)$(bin-prefix)/$(bin-dir)/$$x ; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(bin_prefix)/$(bin_dir)/$$x ; \ -+ $(INSTALL_BIN) $$r $(DESTDIR)$(bin_prefix)/$(bin_dir)/$$x ; \ - done - - ---- a/core/Makefile -+++ b/core/Makefile -@@ -20,29 +20,29 @@ all: ../Makefile.defs $(NAME) modules - - .PHONY: clean - clean: -- -@rm -f $(OBJS) $(DEPS) $(NAME) -- -@rm -f lib/*.so compat/getos compat/getarch -- -@$(MAKE) -C $(SIP_STACK_DIR) clean -- -@$(MAKE) -C $(RESAMPLE_DIR) clean -- -@$(MAKE) -C $(PLUGIN_DIR) clean -+ @rm -f $(OBJS) $(DEPS) $(NAME) -+ @rm -f lib/*.so compat/getos compat/getarch -+ @$(MAKE) -C $(SIP_STACK_DIR) clean -+ @$(MAKE) -C $(RESAMPLE_DIR) clean -+ @$(MAKE) -C $(PLUGIN_DIR) clean - - .PHONY: sip_stack - sip_stack: -- -@echo "" -- -@echo "making SIP stack" -- -@cd $(SIP_STACK_DIR); $(MAKE) all -+ @echo "" -+ @echo "making SIP stack" -+ @cd $(SIP_STACK_DIR); $(MAKE) all - - .PHONY: modules - modules: -- -@echo "" -- -@echo "making core modules" -- -@cd $(PLUGIN_DIR); $(MAKE) modules -+ @echo "" -+ @echo "making core modules" -+ @cd $(PLUGIN_DIR); $(MAKE) modules - - .PHONY: test - test: -- -@echo "" -- -@echo "making tests" -- -@cd $(TEST_DIR); $(MAKE) -+ @echo "" -+ @echo "making tests" -+ @cd $(TEST_DIR); $(MAKE) - - .PHONY: core - core: $(OBJS) ../Makefile.defs -@@ -78,9 +78,9 @@ OBJS += $(RESAMPLE_DIR)/libresample.a - - .PHONY: resample_lib - resample_lib: -- -@echo "" -- -@echo "making internal resampler" -- -@cd $(RESAMPLE_DIR); $(MAKE) all -+ @echo "" -+ @echo "making internal resampler" -+ @cd $(RESAMPLE_DIR); $(MAKE) all - - else - -@@ -110,8 +110,8 @@ endif - $(CXX) -MMD -c -o $@ $< $(CPPFLAGS) $(CXXFLAGS) - - $(NAME): sip_stack resample_lib core ../Makefile.defs -- -@echo "" -- -@echo "making $(NAME) executable" -+ @echo "" -+ @echo "making $(NAME) executable" - $(LD) -o $(NAME) $(OBJS) $(LDFLAGS) $(EXTRA_LDFLAGS) - - -@@ -122,34 +122,34 @@ install: all mk-install-dirs \ - - - # note: on solaris 8 sed: ? or \(...\)* (a.s.o) do not work --install-cfg: $(DESTDIR)$(cfg-target) $(DESTDIR)$(app-cfg-target) -- sed -e "s#/usr/.*lib/sems/audio/#$(audio-target)#g" \ -- -e "s#/usr/.*lib/sems/plug-in/#$(modules-target)#g" \ -- -e "s#/usr/.*etc/sems/#$(cfg-target)#g" \ -- < etc/sems.conf.sample > $(DESTDIR)$(cfg-target)sems.conf.default -- chmod 644 $(DESTDIR)$(cfg-target)sems.conf.default -- if [ ! -f $(DESTDIR)$(cfg-target)sems.conf ]; then \ -- cp -f $(DESTDIR)$(cfg-target)sems.conf.default \ -- $(DESTDIR)$(cfg-target)sems.conf; \ -+install-cfg: $(DESTDIR)$(cfg_target) $(DESTDIR)$(app_cfg_target) -+ sed -e "s#/usr/.*lib/sems/audio/#$(audio_target)#g" \ -+ -e "s#/usr/.*lib/sems/plug-in/#$(modules_target)#g" \ -+ -e "s#/usr/.*etc/sems/#$(cfg_target)#g" \ -+ < etc/sems.conf.sample > $(DESTDIR)$(cfg_target)sems.conf.default -+ chmod 644 $(DESTDIR)$(cfg_target)sems.conf.default -+ if [ ! -f $(DESTDIR)$(cfg_target)sems.conf ]; then \ -+ cp -f $(DESTDIR)$(cfg_target)sems.conf.default \ -+ $(DESTDIR)$(cfg_target)sems.conf; \ - fi - -- $(INSTALL-CFG) etc/app_mapping.conf.sample $(DESTDIR)$(app-cfg-target)app_mapping.conf -+ $(INSTALL_CFG) etc/app_mapping.conf.sample $(DESTDIR)$(app_cfg_target)app_mapping.conf - --install-bin: $(DESTDIR)$(bin-prefix)/$(bin-dir) -- $(INSTALL-TOUCH) $(DESTDIR)$(bin-prefix)/$(bin-dir)$(NAME) -- $(INSTALL-BIN) $(NAME) $(DESTDIR)$(bin-prefix)/$(bin-dir) -+install-bin: $(DESTDIR)$(bin_prefix)/$(bin_dir) -+ $(INSTALL_TOUCH) $(DESTDIR)$(bin_prefix)/$(bin_dir)$(NAME) -+ $(INSTALL_BIN) $(NAME) $(DESTDIR)$(bin_prefix)/$(bin_dir) - --install-modules: $(PLUGIN_DIR) $(DESTDIR)$(modules-prefix)/$(modules-dir) -+install-modules: $(PLUGIN_DIR) $(DESTDIR)$(modules_prefix)/$(modules_dir) - $(MAKE) -C $(PLUGIN_DIR) install - - install-modules-cfg: $(PLUGIN_DIR) - $(MAKE) -C $(PLUGIN_DIR) install-cfg - --install-audio: $(DESTDIR)$(audio-prefix)/$(audio-dir) -+install-audio: $(DESTDIR)$(audio_prefix)/$(audio_dir) - for f in $(AUDIO_FILES) ; do \ - if [ -n "wav/$$f" ]; then \ -- $(INSTALL-TOUCH) $(DESTDIR)$(audio-prefix)/$(audio-dir)$$f; \ -- $(INSTALL-AUDIO) wav/$$f $(DESTDIR)$(audio-prefix)/$(audio-dir)$$f; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(audio_prefix)/$(audio_dir)$$f; \ -+ $(INSTALL_AUDIO) wav/$$f $(DESTDIR)$(audio_prefix)/$(audio_dir)$$f; \ - fi ; \ - done - ---- a/core/plug-in/Makefile -+++ b/core/plug-in/Makefile -@@ -12,8 +12,9 @@ all: modules - - .PHONY: clean - clean: -- -@rm -f *.so -- -@for r in $(core_modules) "" ; do \ -+ @rm -f *.so -+ @set -e; \ -+ for r in $(core_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -23,7 +24,8 @@ clean: - - .PHONY: modules - modules: -- -@for r in $(core_modules) "" ; do \ -+ @set -e; \ -+ for r in $(core_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -33,7 +35,8 @@ modules: - - .PHONY: install - install: -- -@for r in $(core_modules) "" ; do \ -+ @set -e; \ -+ for r in $(core_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ -@@ -42,8 +45,9 @@ install: - done - - .PHONY: install-cfg --install-cfg: $(DESTDIR)$(cfg-target) -- -@for r in $(core_modules) "" ; do \ -+install-cfg: $(DESTDIR)$(cfg_target) -+ @set -e; \ -+ for r in $(core_modules) "" ; do \ - if [ -n "$$r" ]; then \ - echo "" ; \ - echo "" ; \ ---- a/core/plug-in/Makefile.app_module -+++ b/core/plug-in/Makefile.app_module -@@ -34,49 +34,52 @@ module_package: $(extra_target) $(lib_na - - .PHONY: clean - clean: $(extra_clean) -- -@rm -f $(objs) $(depends) $(lib_name) -+ @rm -f $(objs) $(depends) $(lib_name) - - .PHONY: install --install: all $(extra_install) $(DESTDIR)$(modules-prefix)/$(modules-dir) -+install: all $(extra_install) $(DESTDIR)$(modules_prefix)/$(modules_dir) - if [ -f "$(lib_name)" ]; then \ -- $(INSTALL-TOUCH) $(DESTDIR)$(modules-prefix)/$(modules-dir)/$(lib_name) ; \ -- $(INSTALL-MODULES) $(lib_name) $(DESTDIR)$(modules-prefix)/$(modules-dir); \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(modules_prefix)/$(modules_dir)/$(lib_name) ; \ -+ $(INSTALL_MODULES) $(lib_name) $(DESTDIR)$(modules_prefix)/$(modules_dir); \ - fi - - .PHONY: install-cfg --install-cfg: $(DESTDIR)$(app-cfg-target) -- -@for r in $(module_conf_files); do \ -+install-cfg: $(DESTDIR)$(app_cfg_target) -+ @set -e; \ -+ for r in $(module_conf_files); do \ - echo installing $$r ; \ -- $(INSTALL-TOUCH) $(DESTDIR)$(app-cfg-target)$$r ; \ -- sed -e "s#/usr/.*lib/sems/audio/#$(audio-target)#g" \ -- -e "s#/usr/.*lib/sems/plug-in/#$(modules-target)#g" \ -- -e "s#/usr/.*lib/sems/ivr/#$(lib-target)ivr/#g" \ -- -e "s#/usr/.*lib/sems/dsm/#$(lib-target)dsm/#g" \ -- -e "s#/usr/.*lib/sems/py_sems/#$(lib-target)py_sems/#g" \ -- -e "s#/usr/.*etc/sems#$(app-cfg-target)#g" \ -- < etc/$$r > $(DESTDIR)$(app-cfg-target)$$r; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(app_cfg_target)$$r ; \ -+ sed -e "s#/usr/.*lib/sems/audio/#$(audio_target)#g" \ -+ -e "s#/usr/.*lib/sems/plug-in/#$(modules_target)#g" \ -+ -e "s#/usr/.*lib/sems/ivr/#$(lib_target)ivr/#g" \ -+ -e "s#/usr/.*lib/sems/dsm/#$(lib_target)dsm/#g" \ -+ -e "s#/usr/.*lib/sems/py_sems/#$(lib_target)py_sems/#g" \ -+ -e "s#/usr/.*etc/sems#$(app_cfg_target)#g" \ -+ < etc/$$r > $(DESTDIR)$(app_cfg_target)$$r; \ - done - --$(DESTDIR)(audio-prefix)/$(audio-dir): -- mkdir -p $(DESTDIR)$(audio-prefix)/$(audio-dir) -+$(DESTDIR)$(audio_prefix)/$(audio_dir): -+ mkdir -p $(DESTDIR)$(audio_prefix)/$(audio_dir) - - .PHONY: $(plug_in_name)_audio --$(plug_in_name)_audio: $(DESTDIR)$(audio-prefix)/$(audio-dir) -- mkdir -p $(DESTDIR)$(audio-prefix)/$(audio-dir)$(plug_in_name) -- -@for f in $(AUDIO_FILES) ; do \ -+$(plug_in_name)_audio: $(DESTDIR)$(audio_prefix)/$(audio_dir) -+ mkdir -p $(DESTDIR)$(audio_prefix)/$(audio_dir)$(plug_in_name) -+ @set -e; \ -+ for f in $(AUDIO_FILES) ; do \ - if [ -n "wav/$$f" ]; then \ -- $(INSTALL-TOUCH) $(DESTDIR)$(audio-prefix)/$(audio-dir)$(plug_in_name)/$$f; \ -- $(INSTALL-AUDIO) wav/$$f $(DESTDIR)$(audio-prefix)/$(audio-dir)$(plug_in_name)/$$f; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(audio_prefix)/$(audio_dir)$(plug_in_name)/$$f; \ -+ $(INSTALL_AUDIO) wav/$$f $(DESTDIR)$(audio_prefix)/$(audio_dir)$(plug_in_name)/$$f; \ - fi ; \ - done - - .PHONY: $(plug_in_name)_lib - $(plug_in_name)_lib: -- mkdir -p $(DESTDIR)$(lib-prefix)/$(lib-dir)/$(plug_in_name) -- -@for f in $(EXTRA_LIB_FILES) ; do \ -+ mkdir -p $(DESTDIR)$(lib_prefix)/$(lib_dir)/$(plug_in_name) -+ @set -e; \ -+ for f in $(EXTRA_LIB_FILES) ; do \ - if [ -n "$(EXTRA_LIB_DIR)/$$f" ]; then \ -- $(INSTALL-TOUCH) $(DESTDIR)$(lib-prefix)/$(lib-dir)/$(plug_in_name)/$$f; \ -- $(INSTALL-AUDIO) $(EXTRA_LIB_DIR)$$f $(DESTDIR)$(lib-prefix)/$(lib-dir)/$(plug_in_name)/$$f; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(lib_prefix)/$(lib_dir)/$(plug_in_name)/$$f; \ -+ $(INSTALL_AUDIO) $(EXTRA_LIB_DIR)$$f $(DESTDIR)$(lib_prefix)/$(lib_dir)/$(plug_in_name)/$$f; \ - fi ; \ - done - ---- a/core/plug-in/Makefile.audio_module -+++ b/core/plug-in/Makefile.audio_module -@@ -32,9 +32,9 @@ clean: $(extra_clean) - - .PHONY: install - install: $(lib_name) $(extra_install) -- mkdir -p $(DESTDIR)$(modules-prefix)/$(modules-dir) -- $(INSTALL-TOUCH) $(DESTDIR)$(modules-prefix)/$(modules-dir)/$(lib_name) ; \ -- $(INSTALL-MODULES) $(lib_name) $(DESTDIR)$(modules-prefix)/$(modules-dir) -+ mkdir -p $(DESTDIR)$(modules_prefix)/$(modules_dir) -+ $(INSTALL_TOUCH) $(DESTDIR)$(modules_prefix)/$(modules_dir)/$(lib_name) ; \ -+ $(INSTALL_MODULES) $(lib_name) $(DESTDIR)$(modules_prefix)/$(modules_dir) - - .PHONY: install-cfg - install-cfg : $(extra_install_cfg) ---- a/core/plug-in/gsm/gsm-1.0-pl10/Makefile -+++ b/core/plug-in/gsm/gsm-1.0-pl10/Makefile -@@ -276,32 +276,32 @@ TOAST_INSTALL_TARGETS = \ - - .c.o: - $(CC) $(CFLAGS) $? -- @-mv `$(BASENAME) $@` $@ > /dev/null 2>&1 -+ @mv `$(BASENAME) $@` $@ > /dev/null 2>&1 - - # Target rules - - all: $(LIBGSM) $(TOAST) $(TCAT) $(UNTOAST) -- @-echo $(ROOT): Done. -+ @echo $(ROOT): Done. - - tst: $(TST)/lin2cod $(TST)/cod2lin $(TOAST) $(TST)/test-result -- @-echo tst: Done. -+ @echo tst: Done. - - addtst: $(ADDTST)/add $(ADDTST)/add_test.dta - $(ADDTST)/add < $(ADDTST)/add_test.dta > /dev/null -- @-echo addtst: Done. -+ @echo addtst: Done. - - misc: $(TLS)/sweet $(TLS)/bitter $(TLS)/sour $(TLS)/ginger \ - $(TST)/lin2txt $(TST)/cod2txt $(TST)/gsm2cod -- @-echo misc: Done. -+ @echo misc: Done. - - install: toastinstall gsminstall -- @-echo install: Done. -+ @echo install: Done. - - - # The basic API: libgsm - - $(LIBGSM): $(LIB) $(GSM_OBJECTS) -- -rm -f $(RMFLAGS) $(LIBGSM) -+ rm -f $(RMFLAGS) $(LIBGSM) - $(AR) $(ARFLAGS) $(LIBGSM) $(GSM_OBJECTS) - $(RANLIB) $(LIBGSM) - -@@ -312,11 +312,11 @@ $(TOAST): $(BIN) $(TOAST_OBJECTS) $(LIBG - $(LD) $(LFLAGS) -o $(TOAST) $(TOAST_OBJECTS) $(LIBGSM) $(LDLIB) - - $(UNTOAST): $(BIN) $(TOAST) -- -rm $(RMFLAGS) $(UNTOAST) -+ rm -f $(RMFLAGS) $(UNTOAST) - $(LN) $(TOAST) $(UNTOAST) - - $(TCAT): $(BIN) $(TOAST) -- -rm $(RMFLAGS) $(TCAT) -+ rm -f $(RMFLAGS) $(TCAT) - $(LN) $(TOAST) $(TCAT) - - -@@ -332,70 +332,70 @@ $(LIB): - # Installation - - gsminstall: -- -if [ x"$(GSM_INSTALL_ROOT)" != x ] ; then \ -- make $(GSM_INSTALL_TARGETS) ; \ -+ if [ x"$(GSM_INSTALL_ROOT)" != x ] ; then \ -+ $(MAKE) $(GSM_INSTALL_TARGETS) ; \ - fi - - toastinstall: -- -if [ x"$(TOAST_INSTALL_ROOT)" != x ]; then \ -- make $(TOAST_INSTALL_TARGETS); \ -+ if [ x"$(TOAST_INSTALL_ROOT)" != x ]; then \ -+ $(MAKE) $(TOAST_INSTALL_TARGETS); \ - fi - - gsmuninstall: -- -if [ x"$(GSM_INSTALL_ROOT)" != x ] ; then \ -+ if [ x"$(GSM_INSTALL_ROOT)" != x ] ; then \ - rm $(RMFLAGS) $(GSM_INSTALL_TARGETS) ; \ - fi - - toastuninstall: -- -if [ x"$(TOAST_INSTALL_ROOT)" != x ] ; then \ -+ if [ x"$(TOAST_INSTALL_ROOT)" != x ] ; then \ - rm $(RMFLAGS) $(TOAST_INSTALL_TARGETS); \ - fi - - $(TOAST_INSTALL_BIN)/toast: $(TOAST) -- -rm $@ -+ rm -f $@ - cp $(TOAST) $@ - chmod 755 $@ - - $(TOAST_INSTALL_BIN)/untoast: $(TOAST_INSTALL_BIN)/toast -- -rm $@ -+ rm -f $@ - ln $? $@ - - $(TOAST_INSTALL_BIN)/tcat: $(TOAST_INSTALL_BIN)/toast -- -rm $@ -+ rm -f $@ - ln $? $@ - - $(TOAST_INSTALL_MAN)/toast.1: $(MAN)/toast.1 -- -rm $@ -+ rm -f $@ - cp $? $@ - chmod 444 $@ - - $(GSM_INSTALL_MAN)/gsm.3: $(MAN)/gsm.3 -- -rm $@ -+ rm -f $@ - cp $? $@ - chmod 444 $@ - - $(GSM_INSTALL_MAN)/gsm_option.3: $(MAN)/gsm_option.3 -- -rm $@ -+ rm -f $@ - cp $? $@ - chmod 444 $@ - - $(GSM_INSTALL_MAN)/gsm_explode.3: $(MAN)/gsm_explode.3 -- -rm $@ -+ rm -f $@ - cp $? $@ - chmod 444 $@ - - $(GSM_INSTALL_MAN)/gsm_print.3: $(MAN)/gsm_print.3 -- -rm $@ -+ rm -f $@ - cp $? $@ - chmod 444 $@ - - $(GSM_INSTALL_INC)/gsm.h: $(INC)/gsm.h -- -rm $@ -+ rm -f $@ - cp $? $@ - chmod 444 $@ - - $(GSM_INSTALL_LIB)/libgsm.a: $(LIBGSM) -- -rm $@ -+ rm -f $@ - cp $? $@ - chmod 444 $@ - -@@ -414,17 +414,17 @@ gsm-1.0.tar.Z: $(STUFF) $(SOURCES) $(HEA - # Clean - - uninstall: toastuninstall gsmuninstall -- @-echo uninstall: Done. -+ @echo uninstall: Done. - - semi-clean: -- -@rm -Rf $(RMFLAGS) */*.o \ -+ @rm -Rf $(RMFLAGS) */*.o \ - $(TST)/lin2cod $(TST)/lin2txt \ - $(TST)/cod2lin $(TST)/cod2txt \ - $(TST)/gsm2cod \ - $(TST)/*.*.* - - clean: semi-clean -- -@rm -Rf $(RMFLAGS) $(LIBGSM) $(ADDTST)/add \ -+ @rm -Rf $(RMFLAGS) $(LIBGSM) $(ADDTST)/add \ - $(TOAST) $(TCAT) $(UNTOAST) \ - $(ROOT)/gsm-1.0.tar.Z - ---- a/core/plug-in/ilbc/iLBC_rfc3951/Makefile -+++ b/core/plug-in/ilbc/iLBC_rfc3951/Makefile -@@ -16,7 +16,7 @@ RANLIB = ranlib - - .PHONY: clean - clean: -- -@rm -f $(objs) $(depends) $(lib_name) -+ @rm -f $(objs) $(depends) $(lib_name) - - -include $(depends) - ---- a/core/plug-in/stats/Makefile -+++ b/core/plug-in/stats/Makefile -@@ -19,9 +19,9 @@ include ../Makefile.app_module - $(QUERY_STATS_NAME): query_stats.o Makefile - $(LD) -o $(QUERY_STATS_NAME) query_stats.o $(LDFLAGS) $(EXTRA_LDFLAGS) - --install_query_stats: $(QUERY_STATS_NAME) $(DESTDIR)$(bin-prefix)/$(bin-dir) -- $(INSTALL-TOUCH) $(DESTDIR)$(bin-prefix)/$(bin-dir)$(QUERY_STATS_DEST_NAME) -- $(INSTALL-BIN) $(QUERY_STATS_NAME) $(DESTDIR)$(bin-prefix)/$(bin-dir)/$(QUERY_STATS_DEST_NAME) -+install_query_stats: $(QUERY_STATS_NAME) $(DESTDIR)$(bin_prefix)/$(bin_dir) -+ $(INSTALL_TOUCH) $(DESTDIR)$(bin_prefix)/$(bin_dir)$(QUERY_STATS_DEST_NAME) -+ $(INSTALL_BIN) $(QUERY_STATS_NAME) $(DESTDIR)$(bin_prefix)/$(bin_dir)/$(QUERY_STATS_DEST_NAME) - - clean_query_stats: - rm -f $(QUERY_STATS_NAME) query_stats.o query_stats.d ---- a/core/resample/Makefile -+++ b/core/resample/Makefile -@@ -24,6 +24,6 @@ CPPFLAGS += -I$(COREPATH) - $(CXX) -MMD -c -o $@ $< $(CPPFLAGS) $(CXXFLAGS) - - $(LIBNAME): $(OBJS) $(COREPATH)/../Makefile.defs -- -@echo "" -- -@echo "making $(LIBNAME)" -+ @echo "" -+ @echo "making $(LIBNAME)" - $(AR) rvs $(LIBNAME) $(OBJS) ---- a/core/sip/Makefile -+++ b/core/sip/Makefile -@@ -48,8 +48,8 @@ endif - $(CXX) -MMD -c -o $@ $< $(CPPFLAGS) $(CXXFLAGS) - - $(LIBNAME): $(OBJS) $(COREPATH)/../Makefile.defs -- -@echo "" -- -@echo "making $(LIBNAME)" -+ @echo "" -+ @echo "making $(LIBNAME)" - $(AR) rvs $(LIBNAME) $(OBJS) - - -include $(DEPS) ---- a/core/tests/Makefile -+++ b/core/tests/Makefile -@@ -29,21 +29,21 @@ EXTRA_LDFLAGS += -lresolv -levent -leven - - .PHONY: all - all: ../../Makefile.defs sip_stack libresample -- -@$(MAKE) core_deps && $(MAKE) sbc_deps && $(MAKE) deps && \ -+ @$(MAKE) core_deps && $(MAKE) sbc_deps && $(MAKE) deps && \ - $(MAKE) $(NAME) && \ - ./$(NAME) - - .PHONY: sip_stack - sip_stack: -- -@echo "" -- -@echo "making SIP stack" -- -@cd $(SIP_STACK_DIR); $(MAKE) all -+ @echo "" -+ @echo "making SIP stack" -+ @cd $(SIP_STACK_DIR); $(MAKE) all - - .PHONY: libresample - libresample: -- -@echo "" -- -@echo "making libresample" -- -@cd $(RESAMPLE_DIR); $(MAKE) all -+ @echo "" -+ @echo "making libresample" -+ @cd $(RESAMPLE_DIR); $(MAKE) all - - SIP_STACK: sip_stack - -@@ -83,8 +83,8 @@ include ../../Makefile.defs - $(CXX) -MM $< $(CPPFLAGS) $(CXXFLAGS) > $@ - - $(NAME): $(OBJS) $(CORE_OBJS) $(SBC_OBJS) $(AUTH_OBJS) $(SIP_STACK) $(LIBRESAMPLE) ../../Makefile.defs -- -@echo "" -- -@echo "making $(NAME)" -+ @echo "" -+ @echo "making $(NAME)" - $(LD) -o $(NAME) $(OBJS) $(CORE_OBJS) $(SBC_OBJS) $(SIP_STACK) $(LIBRESAMPLE) $(LDFLAGS) $(EXTRA_LDFLAGS) $(AUTH_OBJS) - - ifeq '$(NAME)' '$(MAKECMDGOALS)' ---- a/pkg/rpm/sems.spec -+++ b/pkg/rpm/sems.spec -@@ -112,16 +112,16 @@ make install TTS="y" exclude_modules="ex - DESTDIR=$RPM_BUILD_ROOT \ - basedir= \ - prefix=%{_prefix} \ -- modules-prefix= \ -- modules-dir=%{_libdir}/sems/plug-in \ -- modules-target=%{_libdir}/sems/plug-in \ -- ivr-modules-dir=%{_libdir}/sems/ivr \ -- cfg-prefix= \ -- cfg-target=%{_sysconfdir}/sems/ \ -- doc-prefix= \ -- doc-dir=%{_docdir}/sems/ \ -- audio-prefix= \ -- audio-dir=%{_libdir}/sems/audio/ -+ modules_prefix= \ -+ modules_dir=%{_libdir}/sems/plug-in \ -+ modules_target=%{_libdir}/sems/plug-in \ -+ ivr_modules_dir=%{_libdir}/sems/ivr \ -+ cfg_prefix= \ -+ cfg_target=%{_sysconfdir}/sems/ \ -+ doc_prefix= \ -+ doc_dir=%{_docdir}/sems/ \ -+ audio_prefix= \ -+ audio_dir=%{_libdir}/sems/audio/ - - install -D -p -m755 pkg/rpm/sems.init $RPM_BUILD_ROOT/%{_sysconfdir}/init.d/sems - ---- a/tools/Makefile -+++ b/tools/Makefile -@@ -3,18 +3,19 @@ all: make_tools - COREPATH ?= ../core - include $(COREPATH)/../Makefile.defs - --sems-tools = sems-logfile-callextract -+sems_tools = sems-logfile-callextract - --install: $(sems-tools) install_tools -+install: $(sems_tools) install_tools - --make_tools: $(sems-tools) -+make_tools: $(sems_tools) - --install_tools: $(DESTDIR)$(bin-prefix)/$(bin-dir) -- -@for r in $(sems-tools) ; do \ -+install_tools: $(DESTDIR)$(bin_prefix)/$(bin_dir) -+ @set -e; \ -+ for r in $(sems_tools) ; do \ - x=`echo $$r | sed s/sems-/$(APP_NAME)-/g` ; \ - echo "installing $$r -> $$x" ; \ -- $(INSTALL-TOUCH) $(DESTDIR)$(bin-prefix)/$(bin-dir)/$$x ; \ -- $(INSTALL-BIN) $$r $(DESTDIR)$(bin-prefix)/$(bin-dir)/$$x ; \ -+ $(INSTALL_TOUCH) $(DESTDIR)$(bin_prefix)/$(bin_dir)/$$x ; \ -+ $(INSTALL_BIN) $$r $(DESTDIR)$(bin_prefix)/$(bin_dir)/$$x ; \ - done - - sems-logfile-callextract: logfile-splitter.o diff --git a/debian/patches/fix-build-with-newer-openssl.patch b/debian/patches/fix-build-with-newer-openssl.patch deleted file mode 100644 index 3eabb6a8..00000000 --- a/debian/patches/fix-build-with-newer-openssl.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 5634f22d2b3423b7988d7ca932846d8daa5e34f2 Mon Sep 17 00:00:00 2001 -From: Guillem Jover -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; - diff --git a/debian/patches/no_config.patch b/debian/patches/no_config.patch deleted file mode 100644 index b87b18f6..00000000 --- a/debian/patches/no_config.patch +++ /dev/null @@ -1,62 +0,0 @@ -From e580ff5ca6db1d455d6dc8e8942b8f29e0913ca7 Mon Sep 17 00:00:00 2001 -From: Victor Seva -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 - diff --git a/debian/patches/py_sems_path.patch b/debian/patches/py_sems_path.patch deleted file mode 100644 index d509ab8f..00000000 --- a/debian/patches/py_sems_path.patch +++ /dev/null @@ -1,16 +0,0 @@ -From cc61483b348ea0a5aa0c6effa0d2961aee5bcb57 Mon Sep 17 00:00:00 2001 -From: Victor Seva -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 diff --git a/debian/patches/series b/debian/patches/series deleted file mode 100644 index b3f1dfc0..00000000 --- a/debian/patches/series +++ /dev/null @@ -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 diff --git a/debian/patches/sipwise/0001-TT-34704-Fix-sems-and-sems-pbx-to-write-pid-file-whe.patch b/debian/patches/sipwise/0001-TT-34704-Fix-sems-and-sems-pbx-to-write-pid-file-whe.patch deleted file mode 100644 index 748b374d..00000000 --- a/debian/patches/sipwise/0001-TT-34704-Fix-sems-and-sems-pbx-to-write-pid-file-whe.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 12ea81babb899cd637426afd13740dc9729ca8d3 Mon Sep 17 00:00:00 2001 -From: Roman Romanchenko -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& 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 - diff --git a/debian/patches/sipwise/0001-TT-53685-add_header_pattern_match_support.patch b/debian/patches/sipwise/0001-TT-53685-add_header_pattern_match_support.patch deleted file mode 100644 index 4081e168..00000000 --- a/debian/patches/sipwise/0001-TT-53685-add_header_pattern_match_support.patch +++ /dev/null @@ -1,39 +0,0 @@ -From e3f342754ac8c736b551c8b52376c15cb6e7f8dd Mon Sep 17 00:00:00 2001 -From: Kirill Solomko -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 -(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 -+#include - - 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::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)); diff --git a/debian/patches/sipwise/0002-b-f-dsm-mod_conference-set-callgroup-to-conference-c.patch b/debian/patches/sipwise/0002-b-f-dsm-mod_conference-set-callgroup-to-conference-c.patch deleted file mode 100644 index aa361f6e..00000000 --- a/debian/patches/sipwise/0002-b-f-dsm-mod_conference-set-callgroup-to-conference-c.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 5ec9bf2d042f90f0f29b7de2bb215a8cf6ba7169 Mon Sep 17 00:00:00 2001 -From: Stefan Sayer -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) - diff --git a/debian/patches/sipwise/0006-rename_xdigits.patch b/debian/patches/sipwise/0006-rename_xdigits.patch deleted file mode 100644 index 09f7cbd8..00000000 --- a/debian/patches/sipwise/0006-rename_xdigits.patch +++ /dev/null @@ -1,37 +0,0 @@ -From d1f87cfcb35f4fe27078f7760e9b4a5fff8e189c Mon Sep 17 00:00:00 2001 -From: Andrew Pogrebennyk -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); - } - diff --git a/debian/patches/sipwise/0008-dsm-helper-functions-macros-for-modules-replaceParam.patch b/debian/patches/sipwise/0008-dsm-helper-functions-macros-for-modules-replaceParam.patch deleted file mode 100644 index 9ba42c57..00000000 --- a/debian/patches/sipwise/0008-dsm-helper-functions-macros-for-modules-replaceParam.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 4ec1e1d2d06359c599d9fc551478d443934c616c Mon Sep 17 00:00:00 2001 -From: Stefan Sayer -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* event_params); - -+/** return string q with variables/params/selects replaced */ -+string replaceParams(const string& q, AmSession* sess, DSMSession* sc_sess, -+ map* 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 VarMapT; - typedef map AVarMapT; - diff --git a/debian/patches/sipwise/0015-confpin-simple-pin-conference-app.patch b/debian/patches/sipwise/0015-confpin-simple-pin-conference-app.patch deleted file mode 100644 index 17eb9da8..00000000 --- a/debian/patches/sipwise/0015-confpin-simple-pin-conference-app.patch +++ /dev/null @@ -1,559 +0,0 @@ -From fe53372de8a97d3af08dc3e54d842a4291449190 Mon Sep 17 00:00:00 2001 -From: Stefan Sayer -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 " % 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 " % 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 " % 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]]]) diff --git a/debian/patches/sipwise/0017-MT-13599-don-t-create-CF-map-if-CF-is-denied-by-prof.patch b/debian/patches/sipwise/0017-MT-13599-don-t-create-CF-map-if-CF-is-denied-by-prof.patch deleted file mode 100644 index 4c98cf49..00000000 --- a/debian/patches/sipwise/0017-MT-13599-don-t-create-CF-map-if-CF-is-denied-by-prof.patch +++ /dev/null @@ -1,195 +0,0 @@ -From 89c3172468d4bc02fb7484e20c4feae58ccd23e2 Mon Sep 17 00:00:00 2001 -From: Andrew Pogrebennyk -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); diff --git a/debian/patches/sipwise/0018-db_reg_agent-add-username_with_domain-option-to-use-.patch b/debian/patches/sipwise/0018-db_reg_agent-add-username_with_domain-option-to-use-.patch deleted file mode 100644 index ff8e3099..00000000 --- a/debian/patches/sipwise/0018-db_reg_agent-add-username_with_domain-option-to-use-.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 1f02da5c8cc9dc711ded015059ae85a5126dd269 Mon Sep 17 00:00:00 2001 -From: Stefan Sayer -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::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= - # 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) - diff --git a/debian/patches/sipwise/0019-TT-1640-core_increase-max-config-line.patch b/debian/patches/sipwise/0019-TT-1640-core_increase-max-config-line.patch deleted file mode 100644 index 8ac8009f..00000000 --- a/debian/patches/sipwise/0019-TT-1640-core_increase-max-config-line.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 1f02da5c8cc9dc711ded015059ae85a5126dd269 Mon Sep 17 00:00:00 2001 -From: Andrew Pogrebennyk -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" - - /** diff --git a/debian/patches/sipwise/0020-TT-9521-fix-200OK-without-SPD.patch b/debian/patches/sipwise/0020-TT-9521-fix-200OK-without-SPD.patch deleted file mode 100644 index 6158dfc4..00000000 --- a/debian/patches/sipwise/0020-TT-9521-fix-200OK-without-SPD.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 564d4c09263c021aa7e651edbfbd22e8b895a3bf Mon Sep 17 00:00:00 2001 -From: Jozef Kenyeres -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 { diff --git a/debian/patches/sipwise/MT-20649-add-vsc-for-block-in-clir b/debian/patches/sipwise/MT-20649-add-vsc-for-block-in-clir deleted file mode 100644 index 6731d1cf..00000000 --- a/debian/patches/sipwise/MT-20649-add-vsc-for-block-in-clir +++ /dev/null @@ -1,244 +0,0 @@ -From cd20d43797777716900311f95a43dc864bb546c3 Mon Sep 17 00:00:00 2001 -From: Andreas Granig -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 -+ diff --git a/debian/patches/sipwise/MT-20649-change-config-validation b/debian/patches/sipwise/MT-20649-change-config-validation deleted file mode 100644 index 542e6f4d..00000000 --- a/debian/patches/sipwise/MT-20649-change-config-validation +++ /dev/null @@ -1,696 +0,0 @@ -From f40a8b932a1dabd664995014d2fc2c9f2bcc9722 Mon Sep 17 00:00:00 2001 -From: Andreas Granig -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) - { diff --git a/debian/patches/sipwise/MT-20649-use-macros b/debian/patches/sipwise/MT-20649-use-macros deleted file mode 100644 index fe8c7010..00000000 --- a/debian/patches/sipwise/MT-20649-use-macros +++ /dev/null @@ -1,565 +0,0 @@ -From f40a8b932a1dabd664995014d2fc2c9f2bcc9723 Mon Sep 17 00:00:00 2001 -From: Andreas Granig -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) diff --git a/debian/patches/sipwise/add-vsc-to-disable_all_cf.patch b/debian/patches/sipwise/add-vsc-to-disable_all_cf.patch deleted file mode 100644 index 5ee6e900..00000000 --- a/debian/patches/sipwise/add-vsc-to-disable_all_cf.patch +++ /dev/null @@ -1,438 +0,0 @@ -From 7ce85a46b4d4ba01c1c98309a5c6d28c654efae3 Mon Sep 17 00:00:00 2001 -From: Marco Capetta -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)?.*$ diff --git a/debian/patches/sipwise/add_support_for_peering_outbound_registration.patch b/debian/patches/sipwise/add_support_for_peering_outbound_registration.patch deleted file mode 100644 index ae7eb65a..00000000 --- a/debian/patches/sipwise/add_support_for_peering_outbound_registration.patch +++ /dev/null @@ -1,1816 +0,0 @@ -From afa952009459f9a9c24ad7a649e1ba759229d128 Mon Sep 17 00:00:00 2001 -From: Donat Zenichev -Date: Thu, 29 Dec 2022 10:14:30 +0100 -Subject: MT#55831 add support of SIP peering registrations based on XMLRPC requests - -We need to add a possibility to control (add/modify/delete) registrations -for SIP peerings using NGCP-panel. For that to work NGCP-panel uses XMLRPC -requests being sent towards SEMS, which in its turn takes care of work with: -- locally cached map structures: -* registrations / registrations_peers -* registration_ltags / registration_ltags_peers -* registration_timers / registration_timers_peers -- MySQL database (our scope of interest is 'sems_registrations') -- triggering events - -Main amount of work is concentrated on interaction with map structures which keep -an actual information on registrations of either subscribers and peerings, -and less amount of work is related to the SQL side. - -Basically, the main idea is to add an identifier, which will be used by -NGCP-panel when sending XMLRPC messages to SEMS, which will let SEMS know, -whether it's an event for a usual subscriber or a SIP peering. - -Also we take care of loading time, when SEMS retrieves all previously saved data -from the DB using: peer / subscriber auth preferences and loads this to be usable. -A new query has been added for peering type, to let peerings be loadable after restart. -(real ticket number: TT#66577) - ---- a/apps/db_reg_agent/DBRegAgent.cpp -+++ b/apps/db_reg_agent/DBRegAgent.cpp -@@ -36,7 +36,8 @@ DEFINE_MODULE_INSTANCE(DBRegAgent, MOD_N - mysqlpp::Connection DBRegAgent::MainDBConnection(mysqlpp::use_exceptions); - mysqlpp::Connection DBRegAgent::ProcessorDBConnection(mysqlpp::use_exceptions); - --string DBRegAgent::joined_query; -+string DBRegAgent::joined_query_subscribers; -+string DBRegAgent::joined_query_peerings; - string DBRegAgent::registrations_table = "registrations"; - - double DBRegAgent::reregister_interval = 0.5; -@@ -59,8 +60,8 @@ bool DBRegAgent::save_auth_replies = fal - - unsigned int DBRegAgent::error_retry_interval = 300; - --static void _timer_cb(RegTimer* timer, long subscriber_id, int data2) { -- DBRegAgent::instance()->timer_cb(timer, subscriber_id, data2); -+static void _timer_cb(RegTimer* timer, long object_id, int data2, const string& type) { -+ DBRegAgent::instance()->timer_cb(timer, object_id, data2, type); - } - - DBRegAgent::DBRegAgent(const string& _app_name) -@@ -213,12 +214,13 @@ int DBRegAgent::onLoad() - AmEventDispatcher::instance()->addEventQueue(MOD_NAME,this); - - if (!AmPlugIn::registerDIInterface(MOD_NAME, this)) { -- ERROR("registering "MOD_NAME" DI interface\n"); -+ ERROR("registering %s DI interface\n", MOD_NAME); - return -1; - } - -- joined_query = cfg.getParameter("joined_query"); -- if (joined_query.empty()) { -+ joined_query_subscribers = cfg.getParameter("joined_query_subscribers"); -+ joined_query_peerings = cfg.getParameter("joined_query_peerings"); -+ if (joined_query_subscribers.empty() || joined_query_peerings.empty()) { - // todo: name! - ERROR("joined_query must be set\n"); - return -1; -@@ -230,7 +232,11 @@ int DBRegAgent::onLoad() - DBG("using registrations table '%s'\n", registrations_table.c_str()); - - if (!loadRegistrations()) { -- ERROR("loading registrations from DB\n"); -+ ERROR("REGISTER: loading registrations for subscribers from DB\n"); -+ return -1; -+ } -+ if (!loadRegistrationsPeerings()) { -+ ERROR("REGISTER: loading registrations for peerings from DB\n"); - return -1; - } - -@@ -270,117 +276,242 @@ bool DBRegAgent::loadRegistrations() { - try { - time_t now_time = time(NULL); - -- mysqlpp::Query query = DBRegAgent::MainDBConnection.query(); -+ mysqlpp::Query query_sb = DBRegAgent::MainDBConnection.query(); -+ string query_string_subscribers, table; -+ query_string_subscribers = joined_query_subscribers; - -- string query_string, table; -+ DBG("REGISTER: querying all registrations for subscribers with : '%s'\n", query_string_subscribers.c_str()); - -- query_string = joined_query; -+ query_sb << query_string_subscribers; -+ mysqlpp::UseQueryResult res_sb = query_sb.use(); - -- DBG("querying all registrations with : '%s'\n", -- query_string.c_str()); -+ while (mysqlpp::Row row = res_sb.fetch_row()) { -+ int status = 0; -+ string type = TYPE_SUBSCRIBER; -+ long object_id = row[COLNAME_SUBSCRIBER_ID]; - -- query << query_string; -- mysqlpp::UseQueryResult res = query.use(); -- -- // mysqlpp::Row::size_type row_count = res.num_rows(); -- // DBG("got %zd subscriptions\n", row_count); -+ if (object_id == NULL || object_id == 0) { -+ WARN("REGISTER: object_id is NULL or 0 for this subscriber, skipping..\n"); -+ continue; -+ } - -- while (mysqlpp::Row row = res.fetch_row()) { -- int status = 0; -- long subscriber_id = row[COLNAME_SUBSCRIBER_ID]; -+ DBG("REGISTER: Triggering for subscriber with object_id=<%d>\n", object_id); - - string contact_uri; - if (db_read_contact && row[COLNAME_CONTACT] != mysqlpp::null) { -- contact_uri = (string) row[COLNAME_CONTACT]; -+ contact_uri = (string) row[COLNAME_CONTACT]; - } - - if (row[COLNAME_STATUS] != mysqlpp::null) -- status = row[COLNAME_STATUS]; -+ status = row[COLNAME_STATUS]; - else { -- DBG("registration status entry for id %ld does not exist, creating...\n", -- subscriber_id); -- createDBRegistration(subscriber_id, ProcessorDBConnection); -+ DBG("registration status entry for id %ld does not exist, creating...\n", -+ object_id); -+ createDBRegistration(object_id, type, ProcessorDBConnection); - } - - DBG("got subscriber '%s@%s' status %i\n", -- string(row[COLNAME_USER]).c_str(), string(row[COLNAME_REALM]).c_str(), -- status); -+ string(row[COLNAME_USER]).c_str(), string(row[COLNAME_REALM]).c_str(), status); - - switch (status) { -- case REG_STATUS_INACTIVE: -- case REG_STATUS_PENDING: // try again -- case REG_STATUS_FAILED: // try again -- { -- createRegistration(subscriber_id, -- (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_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) { -- dt_expiry = (time_t)((mysqlpp::DateTime)row[COLNAME_EXPIRY]); -- } -- -- time_t dt_registration_ts = now_time; -- if (row[COLNAME_REGISTRATION_TS] != mysqlpp::null) { -- dt_registration_ts = (time_t)((mysqlpp::DateTime)row[COLNAME_REGISTRATION_TS]); -- } -- -- DBG("got expiry '%ld, registration_ts %ld, now %ld'\n", -- dt_expiry, dt_registration_ts, now_time); -- -- if (dt_registration_ts > now_time) { -- WARN("needed to sanitize last_registration timestamp TS from the %ld (now %ld) - " -- "DB host time mismatch?\n", dt_registration_ts, now_time); -- dt_registration_ts = now_time; -- } -- -- // if expired add to pending registrations, else schedule re-regstration -- if (dt_expiry <= now_time) { -- DBG("scheduling imminent re-registration for subscriber %ld\n", subscriber_id); -- scheduleRegistration(subscriber_id); -- } else { -- setRegistrationTimer(subscriber_id, dt_expiry, dt_registration_ts, now_time); -- } -- -- }; break; -- case REG_STATUS_REMOVED: -- { -- DBG("ignoring removed registration %ld %s@%s", subscriber_id, -- ((string)row[COLNAME_USER]).c_str(), ((string)row[COLNAME_REALM]).c_str()); -- } break; -- -- case REG_STATUS_TO_BE_REMOVED: -- { -- 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_AUTH_USER], -- (string)row[COLNAME_USER], -- (string)row[COLNAME_PASS], -- (string)row[COLNAME_REALM], -- contact_uri -- ); -- scheduleDeregistration(subscriber_id); -- }; -+ case REG_STATUS_INACTIVE: -+ case REG_STATUS_PENDING: // try again -+ case REG_STATUS_FAILED: // try again -+ { -+ createRegistration(object_id, -+ (string)row[COLNAME_AUTH_USER], -+ (string)row[COLNAME_USER], -+ (string)row[COLNAME_PASS], -+ (string)row[COLNAME_REALM], -+ contact_uri, -+ type); -+ scheduleRegistration(object_id, type); -+ }; break; -+ -+ case REG_STATUS_ACTIVE: -+ { -+ createRegistration(object_id, -+ (string)row[COLNAME_AUTH_USER], -+ (string)row[COLNAME_USER], -+ (string)row[COLNAME_PASS], -+ (string)row[COLNAME_REALM], -+ contact_uri, -+ type); -+ -+ time_t dt_expiry = now_time; -+ if (row[COLNAME_EXPIRY] != mysqlpp::null) { -+ dt_expiry = (time_t)((mysqlpp::DateTime)row[COLNAME_EXPIRY]); -+ } -+ -+ time_t dt_registration_ts = now_time; -+ if (row[COLNAME_REGISTRATION_TS] != mysqlpp::null) { -+ dt_registration_ts = (time_t)((mysqlpp::DateTime)row[COLNAME_REGISTRATION_TS]); -+ } -+ -+ DBG("got expiry '%ld, registration_ts %ld, now %ld'\n", -+ dt_expiry, dt_registration_ts, now_time); -+ -+ if (dt_registration_ts > now_time) { -+ WARN("needed to sanitize last_registration timestamp TS from the %ld (now %ld) - " -+ "DB host time mismatch?\n", dt_registration_ts, now_time); -+ dt_registration_ts = now_time; -+ } -+ -+ // if expired add to pending registrations, else schedule re-regstration -+ if (dt_expiry <= now_time) { -+ DBG("scheduling imminent re-registration for subscriber %ld\n", object_id); -+ scheduleRegistration(object_id, type); -+ } else { -+ setRegistrationTimer(object_id, dt_expiry, dt_registration_ts, now_time, type); -+ } -+ }; break; -+ -+ case REG_STATUS_REMOVED: -+ { -+ DBG("ignoring removed registration %ld %s@%s of type: %s\n", object_id, -+ ((string)row[COLNAME_USER]).c_str(), ((string)row[COLNAME_REALM]).c_str(), type.c_str()); -+ } break; -+ -+ case REG_STATUS_TO_BE_REMOVED: -+ { -+ DBG("Scheduling Deregister of registration %ld %s@%s of type: %s\n", object_id, -+ ((string)row[COLNAME_USER]).c_str(), ((string)row[COLNAME_REALM]).c_str(), type.c_str()); -+ createRegistration(object_id, -+ (string)row[COLNAME_AUTH_USER], -+ (string)row[COLNAME_USER], -+ (string)row[COLNAME_PASS], -+ (string)row[COLNAME_REALM], -+ contact_uri, -+ type); -+ scheduleDeregistration(object_id, type); -+ }; - } - } - -+ } catch (const mysqlpp::Exception& er) { -+ // Catch-all for any MySQL++ exceptions -+ ERROR("MySQL++ error: %s\n", er.what()); -+ return false; -+ } -+ -+ return true; -+} -+ -+bool DBRegAgent::loadRegistrationsPeerings() { -+ try { -+ time_t now_time = time(NULL); -+ -+ mysqlpp::Query query_pr = DBRegAgent::MainDBConnection.query(); -+ string query_string_peerings, table; -+ query_string_peerings = joined_query_peerings; -+ -+ DBG("REGISTER: querying all registrations for peerings with : '%s'\n", query_string_peerings.c_str()); -+ -+ query_pr << query_string_peerings; -+ mysqlpp::UseQueryResult res_pr = query_pr.use(); -+ -+ while (mysqlpp::Row row = res_pr.fetch_row()) { -+ int status = 0; -+ string type = TYPE_PEERING; -+ long object_id = row[COLNAME_PEER_ID]; -+ -+ if (object_id == NULL || object_id == 0) { -+ WARN("REGISTER: object_id is NULL or 0 for this peering, skipping..\n"); -+ continue; -+ } -+ -+ DBG("REGISTER: Triggering for peering with object_id=<%d>\n", object_id); -+ -+ string contact_uri; -+ if (db_read_contact && row[COLNAME_CONTACT] != mysqlpp::null) { -+ contact_uri = (string) row[COLNAME_CONTACT]; -+ } -+ -+ if (row[COLNAME_STATUS] != mysqlpp::null) -+ status = row[COLNAME_STATUS]; -+ else { -+ DBG("registration status entry for id %ld does not exist, creating...\n", -+ object_id); -+ createDBRegistration(object_id, type, ProcessorDBConnection); -+ } -+ -+ DBG("got subscriber '%s@%s' status %i\n", -+ string(row[COLNAME_USER]).c_str(), string(row[COLNAME_REALM]).c_str(), status); -+ -+ switch (status) { -+ case REG_STATUS_INACTIVE: -+ case REG_STATUS_PENDING: // try again -+ case REG_STATUS_FAILED: // try again -+ { -+ createRegistration(object_id, -+ (string)row[COLNAME_AUTH_USER], -+ (string)row[COLNAME_USER], -+ (string)row[COLNAME_PASS], -+ (string)row[COLNAME_REALM], -+ contact_uri, -+ type); -+ scheduleRegistration(object_id, type); -+ }; break; -+ -+ case REG_STATUS_ACTIVE: -+ { -+ createRegistration(object_id, -+ (string)row[COLNAME_AUTH_USER], -+ (string)row[COLNAME_USER], -+ (string)row[COLNAME_PASS], -+ (string)row[COLNAME_REALM], -+ contact_uri, -+ type); -+ -+ time_t dt_expiry = now_time; -+ if (row[COLNAME_EXPIRY] != mysqlpp::null) { -+ dt_expiry = (time_t)((mysqlpp::DateTime)row[COLNAME_EXPIRY]); -+ } -+ -+ time_t dt_registration_ts = now_time; -+ if (row[COLNAME_REGISTRATION_TS] != mysqlpp::null) { -+ dt_registration_ts = (time_t)((mysqlpp::DateTime)row[COLNAME_REGISTRATION_TS]); -+ } -+ -+ DBG("got expiry '%ld, registration_ts %ld, now %ld'\n", -+ dt_expiry, dt_registration_ts, now_time); -+ -+ if (dt_registration_ts > now_time) { -+ WARN("needed to sanitize last_registration timestamp TS from the %ld (now %ld) - " -+ "DB host time mismatch?\n", dt_registration_ts, now_time); -+ dt_registration_ts = now_time; -+ } -+ -+ // if expired add to pending registrations, else schedule re-regstration -+ if (dt_expiry <= now_time) { -+ DBG("scheduling imminent re-registration for subscriber %ld\n", object_id); -+ scheduleRegistration(object_id, type); -+ } else { -+ setRegistrationTimer(object_id, dt_expiry, dt_registration_ts, now_time, type); -+ } -+ }; break; -+ -+ case REG_STATUS_REMOVED: -+ { -+ DBG("ignoring removed registration %ld %s@%s of type: %s\n", object_id, -+ ((string)row[COLNAME_USER]).c_str(), ((string)row[COLNAME_REALM]).c_str(), type.c_str()); -+ } break; -+ -+ case REG_STATUS_TO_BE_REMOVED: -+ { -+ DBG("Scheduling Deregister of registration %ld %s@%s of type: %s\n", object_id, -+ ((string)row[COLNAME_USER]).c_str(), ((string)row[COLNAME_REALM]).c_str(), type.c_str()); -+ createRegistration(object_id, -+ (string)row[COLNAME_AUTH_USER], -+ (string)row[COLNAME_USER], -+ (string)row[COLNAME_PASS], -+ (string)row[COLNAME_REALM], -+ contact_uri, -+ type); -+ scheduleDeregistration(object_id, type); -+ }; -+ } -+ } - - } catch (const mysqlpp::Exception& er) { - // Catch-all for any MySQL++ exceptions -@@ -392,14 +523,16 @@ bool DBRegAgent::loadRegistrations() { - } - - /** create registration in our list */ --void DBRegAgent::createRegistration(long subscriber_id, -+void DBRegAgent::createRegistration(long object_id, - const string& auth_user, - const string& user, - const string& pass, - const string& realm, -- const string& contact) { -+ const string& contact, -+ const string& type) { - -- string auth_user_temp = auth_user.empty() ? user : auth_user; -+ string auth_user_temp = (auth_user.empty() || auth_user == "" || auth_user == "NULL") ? user : auth_user; -+ DBG("REGISTER: authentication user picked out: <%s> \n", auth_user_temp.c_str()); - - string _user = user; - if (username_with_domain && user.find('@')!=string::npos) { -@@ -420,30 +553,51 @@ void DBRegAgent::createRegistration(long - 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()); -+ DBG(" >>> realm '%s', user '%s', auth_user '%s', pass '%s', outbound_proxy '%s', contact_uri '%s', type '%s'\n", -+ realm.c_str(), user.c_str(), auth_user.c_str(), pass.c_str(), -+ outbound_proxy.c_str(), contact_uri.c_str(), type.c_str()); - - registrations_mut.lock(); - try { -- if (registrations.find(subscriber_id) != registrations.end()) { -- registrations_mut.unlock(); -- WARN("registration with ID %ld already exists, removing\n", subscriber_id); -- removeRegistration(subscriber_id); -- clearRegistrationTimer(subscriber_id); -- registrations_mut.lock(); -+ // remove already existing registration for a peering -+ if (type == TYPE_PEERING) { -+ if (registrations_peers.find(object_id) != registrations_peers.end()) { -+ registrations_mut.unlock(); -+ WARN("registration for a Peering with ID %ld already exists, removing\n", object_id); -+ removeRegistration(object_id, type); -+ clearRegistrationTimer(object_id, type); -+ registrations_mut.lock(); -+ } -+ // remove already existing for a usual subscriber -+ } else if (type == TYPE_SUBSCRIBER || type == TYPE_UNDEFINED) { -+ if (registrations.find(object_id) != registrations.end()) { -+ registrations_mut.unlock(); -+ WARN("registration for a Subscriber with ID %ld already exists, removing\n", object_id); -+ removeRegistration(object_id, type); -+ clearRegistrationTimer(object_id, type); -+ registrations_mut.lock(); -+ } - } - - AmSIPRegistration* reg = new AmSIPRegistration(handle, reg_info, "" /*MOD_NAME*/); -+ -+ // a simple fix in case expires is for some reason 0. Not the best solution. -+ //if (expires == 0) expires = 60; - reg->setExpiresInterval(expires); - -- registrations[subscriber_id] = reg; -- registration_ltags[handle] = subscriber_id; -+ if (type == TYPE_PEERING) { -+ registrations_peers[object_id] = reg; -+ registration_ltags_peers[handle] = object_id; -+ } else if (type == TYPE_SUBSCRIBER || type == TYPE_UNDEFINED) { -+ registrations[object_id] = reg; -+ registration_ltags[handle] = object_id; -+ } - - if (NULL != uac_auth_i) { -- DBG("enabling UAC Auth for new registration.\n"); -+ DBG("REGISTER: Enabling UAC Auth for new registration of type: <%s>\n", type.c_str()); - - // get a sessionEventHandler from uac_auth -- AmArg di_args,ret; -+ AmArg di_args, ret; - AmArg a; - a.setBorrowedPointer(reg); - di_args.push(a); -@@ -451,20 +605,17 @@ DBG(" >>> realm '%s' - user '%s' - auth_ - - uac_auth_i->invoke("getHandler", di_args, ret); - if (!ret.size()) { -- ERROR("Can not add auth handler to new registration!\n"); -+ ERROR("Can not add auth handler to new registration!\n"); - } else { -- AmObject* p = ret.get(0).asObject(); -- if (p != NULL) { -- AmSessionEventHandler* h = dynamic_cast(p); -- if (h != NULL) -- reg->setSessionEventHandler(h); -- } -+ AmObject* p = ret.get(0).asObject(); -+ if (p != NULL) { -+ AmSessionEventHandler* h = dynamic_cast(p); -+ if (h != NULL) reg->setSessionEventHandler(h); -+ } - } - } -- } catch (const AmArg::OutOfBoundsException& e) { -- ERROR("OutOfBoundsException"); -- } catch (const AmArg::TypeMismatchException& e) { -- ERROR("TypeMismatchException"); -+ } catch (const std::exception& e) { -+ ERROR("%s", e.what()); - } catch (...) { - ERROR("unknown exception occured\n"); - } -@@ -474,18 +625,20 @@ DBG(" >>> realm '%s' - user '%s' - auth_ - // register us as SIP event receiver for this ltag - AmEventDispatcher::instance()->addEventQueue(handle,this); - -- DBG("created new registration with ID %ld and ltag '%s'\n", -- subscriber_id, handle.c_str()); -+ DBG("created new registration with ID <%ld>, ltag '%s' and type '%s'\n", -+ object_id, handle.c_str(), type.c_str()); - } - --void DBRegAgent::updateRegistration(long subscriber_id, -+void DBRegAgent::updateRegistration(long object_id, - const string& auth_user, - const string& user, - const string& pass, - const string& realm, -- const string& contact) { -+ const string& contact, -+ const string& type) { - -- string auth_user_temp = auth_user.empty() ? user : auth_user; -+ string auth_user_temp = (auth_user.empty() || auth_user == "" || auth_user == "NULL") ? user : auth_user; -+ DBG("REGISTER: authentication user picked out: <%s> \n", auth_user_temp.c_str()); - - string _user = user; - if (username_with_domain && user.find('@')!=string::npos) { -@@ -493,14 +646,29 @@ void DBRegAgent::updateRegistration(long - } - - registrations_mut.lock(); -- map::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, auth_user_temp, _user, pass, realm, contact); -- scheduleRegistration(subscriber_id); -- return; -+ -+ map::iterator it; -+ -+ if (type == TYPE_PEERING) { -+ it=registrations_peers.find(object_id); -+ if (it == registrations_peers.end()) { -+ registrations_mut.unlock(); -+ WARN("updateRegistration - registration %ld %s@%s unknown, creating. Type: %s\n", -+ object_id, user.c_str(), realm.c_str(), type.c_str()); -+ createRegistration(object_id, auth_user_temp, user, pass, realm, contact, type); -+ scheduleRegistration(object_id, type); -+ return; -+ } -+ } else if (type == TYPE_SUBSCRIBER || type == TYPE_UNDEFINED) { -+ it=registrations.find(object_id); -+ if (it == registrations.end()) { -+ registrations_mut.unlock(); -+ WARN("updateRegistration - registration %ld %s@%s unknown, creating. Type: %s\n", -+ object_id, user.c_str(), realm.c_str(), type.c_str()); -+ createRegistration(object_id, auth_user_temp, user, pass, realm, contact, type); -+ scheduleRegistration(object_id, type); -+ return; -+ } - } - - bool need_reregister = it->second->getInfo().domain != realm -@@ -511,6 +679,7 @@ void DBRegAgent::updateRegistration(long - - string old_realm = it->second->getInfo().domain; - string old_user = it->second->getInfo().user; -+ string old_auth_user = it->second->getInfo().auth_user; - it->second->setRegistrationInfo(SIPRegistrationInfo(realm, _user, - _user, // name - auth_user_temp, // auth_user -@@ -519,64 +688,78 @@ void DBRegAgent::updateRegistration(long - contact)); // contact - registrations_mut.unlock(); - 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()); -- scheduleRegistration(subscriber_id); -+ DBG("user/realm for registration %ld changed (%s@%s -> %s@%s). Auth user (%s -> %s)." -+ "Triggering immediate re-registration\n", -+ object_id, old_user.c_str(), old_realm.c_str(), -+ user.c_str(), realm.c_str(), old_auth_user.c_str(), auth_user_temp.c_str()); -+ scheduleRegistration(object_id, type); - } - } - - /** remove registration from our list */ --void DBRegAgent::removeRegistration(long subscriber_id) { -+void DBRegAgent::removeRegistration(long object_id, const string& type) { - bool res = false; - string handle; - registrations_mut.lock(); -- map::iterator it = registrations.find(subscriber_id); -- if (it != registrations.end()) { -- handle = it->second->getHandle(); -- registration_ltags.erase(handle); -- delete it->second; -- registrations.erase(it); -- res = true; -+ -+ map::iterator it; -+ if (type == TYPE_PEERING) { // remove reg for peerings -+ it = registrations_peers.find(object_id); -+ if (it != registrations_peers.end()) { -+ handle = it->second->getHandle(); -+ registration_ltags_peers.erase(handle); -+ delete it->second; -+ registrations_peers.erase(it); -+ res = true; -+ } -+ } else if (type == TYPE_SUBSCRIBER || type == TYPE_UNDEFINED) { // remove reg for subscribers -+ it = registrations.find(object_id); -+ if (it != registrations.end()) { -+ handle = it->second->getHandle(); -+ registration_ltags.erase(handle); -+ delete it->second; -+ registrations.erase(it); -+ res = true; -+ } - } -+ - registrations_mut.unlock(); - - if (res) { - // deregister us as SIP event receiver for this ltag - AmEventDispatcher::instance()->delEventQueue(handle); -- -- DBG("removed registration with ID %ld\n", subscriber_id); -+ DBG("removed registration with ID %ld, type: %s \n", object_id, type.c_str()); - } else { -- DBG("registration with ID %ld not found for removing\n", subscriber_id); -+ DBG("registration with ID %ld not found for removing, type: %s \n", object_id, type.c_str()); - } - } - - /** schedule this registration to REGISTER (immediately) */ --void DBRegAgent::scheduleRegistration(long subscriber_id) { -+void DBRegAgent::scheduleRegistration(long object_id, const string& type) { - if (enable_ratelimiting) { - registration_processor. -- postEvent(new RegistrationActionEvent(RegistrationActionEvent::Register, -- subscriber_id)); -+ postEvent(new RegistrationActionEvent(RegistrationActionEvent::Register, -+ object_id, type)); - } else { - // use our own thread - postEvent(new RegistrationActionEvent(RegistrationActionEvent::Register, -- subscriber_id)); -+ object_id, type)); - } -- DBG("added to pending actions: REGISTER of %ld\n", subscriber_id); -+ DBG("Added to pending actions: REGISTER of %ld, type: %s\n", object_id, type.c_str()); - } - - /** schedule this registration to de-REGISTER (immediately) */ --void DBRegAgent::scheduleDeregistration(long subscriber_id) { -+void DBRegAgent::scheduleDeregistration(long object_id, const string& type) { - if (enable_ratelimiting) { - registration_processor. - postEvent(new RegistrationActionEvent(RegistrationActionEvent::Deregister, -- subscriber_id)); -+ object_id, type)); - } else { - // use our own thread - postEvent(new RegistrationActionEvent(RegistrationActionEvent::Deregister, -- subscriber_id)); -+ object_id, type)); - } -- DBG("added to pending actions: DEREGISTER of %ld\n", subscriber_id); -+ DBG("added to pending actions: DEREGISTER of %ld, type: %s\n", object_id, type.c_str()); - } - - void DBRegAgent::process(AmEvent* ev) { -@@ -614,71 +797,108 @@ void DBRegAgent::process(AmEvent* ev) { - // uses ProcessorDBConnection - void DBRegAgent::onRegistrationActionEvent(RegistrationActionEvent* reg_action_ev) { - switch (reg_action_ev->action) { -+ - case RegistrationActionEvent::Register: - { -- DBG("REGISTER of registration %ld\n", reg_action_ev->subscriber_id); -+ DBG("REGISTER of registration %ld, type: %s\n", -+ reg_action_ev->object_id, reg_action_ev->type.c_str()); -+ - registrations_mut.lock(); -- map::iterator it= -- registrations.find(reg_action_ev->subscriber_id); -- if (it==registrations.end()) { -- DBG("ignoring scheduled REGISTER of unknown registration %ld\n", -- reg_action_ev->subscriber_id); -- } else { -- if (!it->second->doRegistration()) { -- updateDBRegistration(ProcessorDBConnection, -- reg_action_ev->subscriber_id, -- 480, ERR_REASON_UNABLE_TO_SEND_REQUEST, -- true, REG_STATUS_FAILED); -- if (error_retry_interval) { -- // schedule register-refresh after error_retry_interval -- setRegistrationTimer(reg_action_ev->subscriber_id, error_retry_interval, -- RegistrationActionEvent::Register); -- } -- } -+ map::iterator it; -+ bool marker = true; -+ -+ if (reg_action_ev->type == TYPE_PEERING) { -+ it = registrations_peers.find(reg_action_ev->object_id); -+ if (it==registrations_peers.end()) { -+ DBG("ignoring scheduled REGISTER of unknown registration %ld\n", -+ reg_action_ev->object_id); -+ marker = false; -+ } -+ } else if (reg_action_ev->type == TYPE_SUBSCRIBER || reg_action_ev->type == TYPE_UNDEFINED) { -+ it = registrations.find(reg_action_ev->object_id); -+ if (it==registrations.end()) { -+ DBG("ignoring scheduled REGISTER of unknown registration %ld\n", -+ reg_action_ev->object_id); -+ marker = false; -+ } - } -+ -+ if (marker) { -+ if (!it->second->doRegistration()) { -+ updateDBRegistration(ProcessorDBConnection, -+ reg_action_ev->object_id, reg_action_ev->type, -+ 480, ERR_REASON_UNABLE_TO_SEND_REQUEST, -+ true, REG_STATUS_FAILED); -+ if (error_retry_interval) { -+ // schedule register-refresh after error_retry_interval -+ setRegistrationTimer(reg_action_ev->object_id, error_retry_interval, -+ RegistrationActionEvent::Register, reg_action_ev->type); -+ } -+ } -+ } -+ - registrations_mut.unlock(); - } break; -+ - case RegistrationActionEvent::Deregister: - { -- DBG("De-REGISTER of registration %ld\n", reg_action_ev->subscriber_id); -+ DBG("De-REGISTER of registration %ld, type: %s\n", -+ reg_action_ev->object_id, reg_action_ev->type.c_str()); -+ - registrations_mut.lock(); -- map::iterator it= -- registrations.find(reg_action_ev->subscriber_id); -- if (it==registrations.end()) { -- DBG("ignoring scheduled De-REGISTER of unknown registration %ld\n", -- reg_action_ev->subscriber_id); -- } else { -- if (!it->second->doUnregister()) { -- if (delete_removed_registrations && delete_failed_deregistrations) { -- DBG("sending de-Register failed - deleting registration %ld " -- "(delete_failed_deregistrations=yes)\n", reg_action_ev->subscriber_id); -- deleteDBRegistration(reg_action_ev->subscriber_id, ProcessorDBConnection); -- } else { -- DBG("failed sending de-register, updating DB with REG_STATUS_TO_BE_REMOVED " -- ERR_REASON_UNABLE_TO_SEND_REQUEST "for subscriber %ld\n", -- reg_action_ev->subscriber_id); -- updateDBRegistration(ProcessorDBConnection, -- reg_action_ev->subscriber_id, -- 480, ERR_REASON_UNABLE_TO_SEND_REQUEST, -- true, REG_STATUS_TO_BE_REMOVED); -- // don't re-try de-registrations if sending failed -- // if (error_retry_interval) { -- // // schedule register-refresh after error_retry_interval -- // setRegistrationTimer(reg_action_ev->subscriber_id, error_retry_interval, -- // RegistrationActionEvent::Deregister); -- // } -- } -- } -+ map::iterator it; -+ bool marker = true; -+ -+ if (reg_action_ev->type == TYPE_PEERING) { -+ it = registrations_peers.find(reg_action_ev->object_id); -+ if (it==registrations_peers.end()) { -+ DBG("ignoring scheduled De-REGISTER of unknown registration %ld\n", -+ reg_action_ev->object_id); -+ marker = false; -+ } -+ } else if (reg_action_ev->type == TYPE_SUBSCRIBER || reg_action_ev->type == TYPE_UNDEFINED) { -+ it = registrations.find(reg_action_ev->object_id); -+ if (it==registrations.end()) { -+ DBG("ignoring scheduled De-REGISTER of unknown registration %ld\n", -+ reg_action_ev->object_id); -+ marker = false; -+ } -+ } -+ -+ if (marker) { -+ if (!it->second->doUnregister()) { -+ if (delete_removed_registrations && delete_failed_deregistrations) { -+ DBG("sending de-Register failed - deleting registration %ld " -+ "(delete_failed_deregistrations=yes)\n", reg_action_ev->object_id); -+ deleteDBRegistration(reg_action_ev->object_id, reg_action_ev->type, ProcessorDBConnection); -+ } else { -+ DBG("failed sending de-register, updating DB with REG_STATUS_TO_BE_REMOVED " -+ ERR_REASON_UNABLE_TO_SEND_REQUEST "for subscriber %ld\n", -+ reg_action_ev->object_id); -+ updateDBRegistration(ProcessorDBConnection, -+ reg_action_ev->object_id, reg_action_ev->type, -+ 480, ERR_REASON_UNABLE_TO_SEND_REQUEST, -+ true, REG_STATUS_TO_BE_REMOVED); -+ } -+ } - } -+ - registrations_mut.unlock(); - } break; - } - } - --void DBRegAgent::createDBRegistration(long subscriber_id, mysqlpp::Connection& conn) { -+void DBRegAgent::createDBRegistration(long object_id, const string& type, mysqlpp::Connection& conn) { -+ -+ string column_id = COLNAME_SUBSCRIBER_ID; -+ if (type == TYPE_PEERING) column_id = COLNAME_PEER_ID; -+ -+ // depending on if that is a registration for a subscriber or for a peering -+ // do a mysql insertion - string insert_query = "insert into "+registrations_table+ -- " (subscriber_id) values ("+ -- long2str(subscriber_id)+");"; -+ " (" + column_id.c_str() + ")" + "values ("+ long2str(object_id)+");"; -+ -+ DBG("MYSQL: trying to execute: <%s>\n", insert_query.c_str()); - - try { - mysqlpp::Query query = conn.query(); -@@ -686,8 +906,8 @@ void DBRegAgent::createDBRegistration(lo - - mysqlpp::SimpleResult res = query.execute(); - if (!res) { -- WARN("creating registration in DB with query '%s' failed: '%s'\n", -- insert_query.c_str(), res.info()); -+ WARN("creating registration in DB with query '%s' failed: '%s', type: %s\n", -+ insert_query.c_str(), res.info(), type.c_str()); - } - } catch (const mysqlpp::Exception& er) { - // Catch-all for any MySQL++ exceptions -@@ -696,9 +916,15 @@ void DBRegAgent::createDBRegistration(lo - } - } - --void DBRegAgent::deleteDBRegistration(long subscriber_id, mysqlpp::Connection& conn) { -+void DBRegAgent::deleteDBRegistration(long object_id, const string& type, mysqlpp::Connection& conn) { -+ -+ string column_id = COLNAME_SUBSCRIBER_ID; -+ if (type == TYPE_PEERING) column_id = COLNAME_PEER_ID; -+ -+ // depending on if that is a de-registration for a subscriber or for a peering -+ // do a mysql deletion - string insert_query = "delete from "+registrations_table+ -- " where subscriber_id=" + long2str(subscriber_id)+";"; -+ " where " + column_id.c_str() + "=" + long2str(object_id) + ";"; - - try { - mysqlpp::Query query = conn.query(); -@@ -706,8 +932,8 @@ void DBRegAgent::deleteDBRegistration(lo - - mysqlpp::SimpleResult res = query.execute(); - if (!res) { -- WARN("removing registration in DB with query '%s' failed: '%s'\n", -- insert_query.c_str(), res.info()); -+ WARN("removing registration in DB with query '%s' failed: '%s', type: %s\n", -+ insert_query.c_str(), res.info(), type.c_str()); - } - } catch (const mysqlpp::Exception& er) { - // Catch-all for any MySQL++ exceptions -@@ -717,7 +943,7 @@ void DBRegAgent::deleteDBRegistration(lo - } - - void DBRegAgent::updateDBRegistration(mysqlpp::Connection& db_connection, -- long subscriber_id, int last_code, -+ long object_id, const string& type, int last_code, - const string& last_reason, - bool update_status, int status, - bool update_ts, unsigned int expiry, -@@ -743,7 +969,12 @@ void DBRegAgent::updateDBRegistration(my - query << ", contacts=" << mysqlpp::quote << contacts; - } - -- query << " where " COLNAME_SUBSCRIBER_ID "="+long2str(subscriber_id) + ";"; -+ // depending on if that is an update for a subscriber or for a peering -+ // do a mysql update -+ if (type == TYPE_SUBSCRIBER) -+ query << " where " COLNAME_SUBSCRIBER_ID "="+long2str(object_id) + ";"; -+ else -+ query << " where " COLNAME_PEER_ID "="+long2str(object_id) + ";"; - string query_str = query.str(); - DBG("updating registration in DB with query '%s'\n", query_str.c_str()); - -@@ -754,8 +985,8 @@ void DBRegAgent::updateDBRegistration(my - } else { - if (!res.rows()) { - // should not happen - DB entry is created on load or on createRegistration -- DBG("creating registration DB entry for subscriber %ld\n", subscriber_id); -- createDBRegistration(subscriber_id, db_connection); -+ DBG("creating registration DB entry for subscriber %ld, type: %s\n", object_id, type.c_str()); -+ createDBRegistration(object_id, type, db_connection); - query.reset(); - query << query_str; - -@@ -794,16 +1025,52 @@ void DBRegAgent::onSipReplyEvent(AmSipRe - #else - ev->reply.local_tag; - #endif -- -- map::iterator it=registration_ltags.find(local_tag); -+ -+ map::iterator it; -+ -+ bool marker = false; -+ string type; -+ -+ // not the best solution to match coming reply against needed object -+ // we need to find a way how to better differentiate, -+ // if that is related to a peering type or subscriber type -+ // now a basic attempt to first look into subscribers cache buckets then into -+ // peerings cache buckets (can this happen that ltag will overlap? must be unique) -+ -+ -+ // first try to find a registration object in a cache for subscribers (most common case) -+ it=registration_ltags.find(local_tag); - if (it!=registration_ltags.end()) { -- long subscriber_id = it->second; -- map::iterator r_it=registrations.find(subscriber_id); -- if (r_it != registrations.end()) { -+ marker=true; -+ type = TYPE_SUBSCRIBER; -+ -+ // secondly, if we didn't find anything before, try in a cache for peerings -+ } else { -+ it=registration_ltags_peers.find(local_tag); -+ if (it!=registration_ltags_peers.end()) { -+ marker=true; -+ type = TYPE_PEERING; -+ } -+ } -+ -+ if (marker) { -+ long object_id = it->second; -+ map::iterator r_it; -+ -+ marker = false; -+ if (type == TYPE_SUBSCRIBER) { // find registration for peering -+ r_it=registrations.find(object_id); -+ if (r_it != registrations.end()) marker = true; -+ } else { // find registration for subscriber -+ r_it=registrations_peers.find(object_id); -+ if (r_it != registrations_peers.end()) marker = true; -+ } -+ -+ if (marker) { - AmSIPRegistration* registration = r_it->second; - if (!registration) { -- ERROR("Internal error: registration object missing\n"); -- return; -+ ERROR("Internal error: registration object missing, type: %s\n", type.c_str()); -+ return; - } - unsigned int cseq_before = registration->getDlg()->cseq; - -@@ -813,7 +1080,7 @@ void DBRegAgent::onSipReplyEvent(AmSipRe - registration->getDlg()->updateStatus(ev->reply); - #endif - -- //update registrations set -+ //update registrations set - bool update_status = false; - int status = 0; - bool update_ts = false; -@@ -822,82 +1089,82 @@ void DBRegAgent::onSipReplyEvent(AmSipRe - bool auth_pending = false; - - if (ev->reply.code >= 300) { -- // REGISTER or de-REGISTER failed -- if ((ev->reply.code == 401 || ev->reply.code == 407) && -- // auth response codes -- // processing reply triggered sending request: resent by auth -- (cseq_before != registration->getDlg()->cseq)) { -- DBG("received negative reply, but still in pending state (auth).\n"); -- auth_pending = true; -- } else { -- if (!registration->getUnregistering()) { -- // REGISTER failed - mark in DB -- DBG("registration failed - mark in DB\n"); -- update_status = true; -- status = REG_STATUS_FAILED; -- if (error_retry_interval) { -- // schedule register-refresh after error_retry_interval -- setRegistrationTimer(subscriber_id, error_retry_interval, -- RegistrationActionEvent::Register); -- } -- } else { -- // de-REGISTER failed -- if (delete_removed_registrations && delete_failed_deregistrations) { -- DBG("de-Register failed - deleting registration %ld " -- "(delete_failed_deregistrations=yes)\n", subscriber_id); -- delete_status = true; -- } else { -- update_status = true; -- status = REG_STATUS_TO_BE_REMOVED; -- } -- } -- } -+ // REGISTER or de-REGISTER failed -+ if ((ev->reply.code == 401 || ev->reply.code == 407) && -+ // auth response codes -+ // processing reply triggered sending request: resent by auth -+ (cseq_before != registration->getDlg()->cseq)) { -+ DBG("received negative reply, but still in pending state (auth).\n"); -+ auth_pending = true; -+ } else { -+ if (!registration->getUnregistering()) { -+ // REGISTER failed - mark in DB -+ DBG("registration failed - mark in DB\n"); -+ update_status = true; -+ status = REG_STATUS_FAILED; -+ if (error_retry_interval) { -+ // schedule register-refresh after error_retry_interval -+ setRegistrationTimer(object_id, error_retry_interval, -+ RegistrationActionEvent::Register, type); -+ } -+ } else { -+ // de-REGISTER failed -+ if (delete_removed_registrations && delete_failed_deregistrations) { -+ DBG("de-Register failed - deleting registration %ld " -+ "(delete_failed_deregistrations=yes)\n", object_id); -+ delete_status = true; -+ } else { -+ update_status = true; -+ status = REG_STATUS_TO_BE_REMOVED; -+ } -+ } -+ } - } else if (ev->reply.code >= 200) { -- // positive reply -- if (!registration->getUnregistering()) { -- time_t now_time = time(0); -- setRegistrationTimer(subscriber_id, registration->getExpiresTS(), -- now_time, now_time); -- -- update_status = true; -- status = REG_STATUS_ACTIVE; -- -- update_ts = true; -- expiry = registration->getExpiresLeft(); -- } else { -- if (delete_removed_registrations) { -- delete_status = true; -- } else { -- update_status = true; -- status = REG_STATUS_REMOVED; -- } -- } -+ // positive reply -+ if (!registration->getUnregistering()) { -+ time_t now_time = time(0); -+ setRegistrationTimer(object_id, registration->getExpiresTS(), -+ now_time, now_time, type); -+ -+ update_status = true; -+ status = REG_STATUS_ACTIVE; -+ -+ update_ts = true; -+ expiry = registration->getExpiresLeft(); -+ } else { -+ if (delete_removed_registrations) { -+ delete_status = true; -+ } else { -+ update_status = true; -+ status = REG_STATUS_REMOVED; -+ } -+ } - } - - // skip provisional replies & auth - if (ev->reply.code >= 200 && !auth_pending) { -- // remove unregistered -- if (registration->getUnregistering()) { -- registrations_mut.unlock(); -- removeRegistration(subscriber_id); -- registrations_mut.lock(); -- } -+ // remove unregistered -+ if (registration->getUnregistering()) { -+ registrations_mut.unlock(); -+ removeRegistration(object_id, type); -+ registrations_mut.lock(); -+ } - } - - if (!delete_status) { -- if (auth_pending && !save_auth_replies) { -- DBG("not updating DB with auth reply %u %s\n", -- ev->reply.code, ev->reply.reason.c_str()); -- } else { -- DBG("update DB with reply %u %s\n", ev->reply.code, ev->reply.reason.c_str()); -- updateDBRegistration(MainDBConnection, -- subscriber_id, ev->reply.code, ev->reply.reason, -- update_status, status, update_ts, expiry, -- save_contacts, ev->reply.contact); -- } -+ if (auth_pending && !save_auth_replies) { -+ DBG("not updating DB with auth reply %u %s\n", -+ ev->reply.code, ev->reply.reason.c_str()); -+ } else { -+ DBG("update DB with reply %u %s\n", ev->reply.code, ev->reply.reason.c_str()); -+ updateDBRegistration(MainDBConnection, -+ object_id, type, ev->reply.code, ev->reply.reason, -+ update_status, status, update_ts, expiry, -+ save_contacts, ev->reply.contact); -+ } - } else { -- DBG("delete DB registration of subscriber %ld\n", subscriber_id); -- deleteDBRegistration(subscriber_id, MainDBConnection); -+ DBG("delete DB registration of subscriber %ld\n", object_id); -+ deleteDBRegistration(object_id, type, MainDBConnection); - } - - } else { -@@ -929,15 +1196,15 @@ void DBRegAgent::run() { - processEvents(); - } - -- DBG("DBRegAgent done, removing all registrations from Event Dispatcher...\n"); -+ DBG("DBRegAgent done, removing all registrations from Event Dispatcher for peerings...\n"); - registrations_mut.lock(); -- for (map::iterator it=registration_ltags.begin(); -- it != registration_ltags.end(); it++) { -+ for (map::iterator it=registration_ltags_peers.begin(); -+ it != registration_ltags_peers.end(); it++) { - AmEventDispatcher::instance()->delEventQueue(it->first); - } - registrations_mut.unlock(); - -- DBG("removing "MOD_NAME" registrations from Event Dispatcher...\n"); -+ DBG("removing %s registrations from Event Dispatcher...\n", MOD_NAME); - AmEventDispatcher::instance()->delEventQueue(MOD_NAME); - - mysqlpp::Connection::thread_end(); -@@ -951,19 +1218,31 @@ void DBRegAgent::on_stop() { - running = false; - } - --void DBRegAgent::setRegistrationTimer(long subscriber_id, unsigned int timeout, -- RegistrationActionEvent::RegAction reg_action) { -+void DBRegAgent::setRegistrationTimer(long object_id, unsigned int timeout, -+ RegistrationActionEvent::RegAction reg_action, const string& type) { - DBG("setting Register timer for subscription %ld, timeout %u, reg_action %u\n", -- subscriber_id, timeout, reg_action); -+ object_id, timeout, reg_action); - - RegTimer* timer = NULL; -- map::iterator it=registration_timers.find(subscriber_id); -- if (it==registration_timers.end()) { -- DBG("timer object for subscription %ld not found\n", subscriber_id); -+ map::iterator it; -+ bool marker = false; -+ -+ if (type == TYPE_PEERING) { -+ it=registration_timers_peers.find(object_id); -+ if (it==registration_timers_peers.end()) marker = true; -+ -+ } else if (type == TYPE_SUBSCRIBER || type == TYPE_UNDEFINED) { -+ it=registration_timers.find(object_id); -+ if (it==registration_timers.end()) marker = true; -+ } -+ -+ if (marker) { -+ DBG("timer object for subscription %ld not found, type: %s\n", object_id, type.c_str()); - timer = new RegTimer(); -- timer->data1 = subscriber_id; -+ timer->data1 = object_id; -+ timer->data3 = type; // 'peering' or 'subscriber' - timer->cb = _timer_cb; -- DBG("created timer object [%p] for subscription %ld\n", timer, subscriber_id); -+ DBG("created timer object [%p] for subscription %ld, type: %s\n", timer, object_id, type.c_str()); - } else { - timer = it->second; - DBG("removing scheduled timer...\n"); -@@ -973,28 +1252,42 @@ void DBRegAgent::setRegistrationTimer(lo - timer->data2 = reg_action; - timer->expires = time(0) + timeout; - -- DBG("placing timer for %ld in T-%u\n", subscriber_id, timeout); -+ DBG("placing timer for %ld in T-%u, type: %s\n", object_id, timeout, type.c_str()); - registration_scheduler.insert_timer(timer); - -- registration_timers.insert(std::make_pair(subscriber_id, timer)); -- -+ if (type == TYPE_PEERING) -+ registration_timers_peers.insert(std::make_pair(object_id, timer)); -+ else if (type == TYPE_SUBSCRIBER || type == TYPE_UNDEFINED) -+ registration_timers.insert(std::make_pair(object_id, timer)); - } - --void DBRegAgent::setRegistrationTimer(long subscriber_id, -- time_t expiry, time_t reg_start_ts, -- time_t now_time) { -- DBG("setting re-Register timer for subscription %ld, expiry %ld, reg_start_t %ld\n", -- subscriber_id, expiry, reg_start_ts); -+void DBRegAgent::setRegistrationTimer(long object_id, -+ time_t expiry, time_t reg_start_ts, -+ time_t now_time, const string& type) { -+ -+ DBG("setting re-Register timer for subscription %ld, expiry %ld, reg_start_t %ld, type: %s\n", -+ object_id, expiry, reg_start_ts, type.c_str()); - - RegTimer* timer = NULL; -- map::iterator it=registration_timers.find(subscriber_id); -- if (it==registration_timers.end()) { -- DBG("timer object for subscription %ld not found\n", subscriber_id); -+ map::iterator it; -+ bool marker = false; -+ -+ if (type == TYPE_PEERING) { -+ it=registration_timers_peers.find(object_id); -+ if (it==registration_timers_peers.end()) marker = true; -+ } else if (type == TYPE_SUBSCRIBER || type == TYPE_UNDEFINED) { -+ it=registration_timers.find(object_id); -+ if (it==registration_timers.end()) marker = true; -+ } -+ -+ if (marker) { -+ DBG("timer object for subscription %ld not found, type: %s\n", object_id, type.c_str()); - timer = new RegTimer(); -- timer->data1 = subscriber_id; -+ timer->data1 = object_id; -+ timer->data3 = type; // 'peering' or 'subscriber' - timer->cb = _timer_cb; -- DBG("created timer object [%p] for subscription %ld\n", timer, subscriber_id); -- registration_timers.insert(std::make_pair(subscriber_id, timer)); -+ DBG("created timer object [%p] for subscription %ld, type: %s\n", timer, object_id, type.c_str()); -+ registration_timers.insert(std::make_pair(object_id, timer)); - } else { - timer = it->second; - DBG("removing scheduled timer...\n"); -@@ -1058,82 +1351,114 @@ void DBRegAgent::setRegistrationTimer(lo - } - } - --void DBRegAgent::clearRegistrationTimer(long subscriber_id) { -- DBG("removing timer for subscription %ld", subscriber_id); -+void DBRegAgent::clearRegistrationTimer(long object_id, const string& type) { -+ DBG("Removing timer for subscription %ld, type: %s", object_id, type.c_str()); -+ -+ map::iterator it; - -- map::iterator it=registration_timers.find(subscriber_id); -- if (it==registration_timers.end()) { -- DBG("timer object for subscription %ld not found\n", subscriber_id); -+ // clear registration timer for peerings -+ if (type == TYPE_PEERING) { -+ it=registration_timers_peers.find(object_id); -+ if (it==registration_timers_peers.end()) { -+ DBG("timer object for subscription %ld not found, type: %s\n", object_id, type.c_str()); -+ return; -+ } -+ // clear registration timer for subscribers -+ } else if (type == TYPE_SUBSCRIBER || type == TYPE_UNDEFINED) { -+ it=registration_timers.find(object_id); -+ if (it==registration_timers.end()) { -+ DBG("timer object for subscription %ld not found, type: %s\n", object_id, type.c_str()); - return; -+ } - } -+ - DBG("removing timer [%p] from scheduler\n", it->second); - registration_scheduler.remove_timer(it->second); - - DBG("deleting timer object [%p]\n", it->second); - delete it->second; - -- registration_timers.erase(it); --} -- --void DBRegAgent::removeRegistrationTimer(long subscriber_id) { -- DBG("removing timer object for subscription %ld", subscriber_id); -+ if (type == TYPE_PEERING) -+ registration_timers_peers.erase(it); -+ else if (type == TYPE_SUBSCRIBER || type == TYPE_UNDEFINED) -+ registration_timers.erase(it); -+} -+ -+void DBRegAgent::removeRegistrationTimer(long object_id, const string& type) { -+ DBG("removing timer object for subscription %ld, type: %s", object_id, type.c_str()); -+ -+ map::iterator it; -+ -+ // remove registration timer for peerings -+ if (type == TYPE_PEERING) { -+ it=registration_timers_peers.find(object_id); -+ if (it==registration_timers_peers.end()) { -+ DBG("timer object for subscription %ld not found, type: %s\n", object_id, type.c_str()); -+ return; -+ } - -- map::iterator it=registration_timers.find(subscriber_id); -- if (it==registration_timers.end()) { -- DBG("timer object for subscription %ld not found\n", subscriber_id); -- return; -+ // remove registration timer for subscribers -+ } else if (type == TYPE_SUBSCRIBER || type == TYPE_UNDEFINED) { -+ it=registration_timers.find(object_id); -+ if (it==registration_timers.end()) { -+ DBG("timer object for subscription %ld not found, type: %s\n", object_id, type.c_str()); -+ return; -+ } - } - - DBG("deleting timer object [%p]\n", it->second); - delete it->second; - -- registration_timers.erase(it); -+ if (type == TYPE_PEERING) -+ registration_timers_peers.erase(it); -+ else if (type == TYPE_SUBSCRIBER || type == TYPE_UNDEFINED) -+ registration_timers.erase(it); - } - --void DBRegAgent::timer_cb(RegTimer* timer, long subscriber_id, int reg_action) { -- DBG("re-registration timer expired: subscriber %ld, timer=[%p], action %d\n", -- subscriber_id, timer, reg_action); -+void DBRegAgent::timer_cb(RegTimer* timer, long object_id, int reg_action, const string& type) { -+ DBG("re-registration timer expired: subscriber %ld, timer=[%p], action %d, type %s\n", -+ object_id, timer, reg_action, type.c_str()); - - registrations_mut.lock(); -- removeRegistrationTimer(subscriber_id); -+ removeRegistrationTimer(object_id, type); - registrations_mut.unlock(); -+ - switch (reg_action) { - case RegistrationActionEvent::Register: -- scheduleRegistration(subscriber_id); break; -+ scheduleRegistration(object_id, type); break; - case RegistrationActionEvent::Deregister: -- scheduleDeregistration(subscriber_id); break; -+ scheduleDeregistration(object_id, type); break; - default: ERROR("internal: unknown reg_action %d for subscriber %ld timer event\n", -- reg_action, subscriber_id); -+ reg_action, object_id); - }; - } - -+void DBRegAgent::DIcreateRegistration(int object_id, const string& user, -+ const string& pass, const string& realm, -+ const string& contact, const string& auth_user, -+ const string& type, AmArg& ret) { - --void DBRegAgent::DIcreateRegistration(int subscriber_id, const string& user, -- const string& pass, const string& realm, -- const string& contact, const string& auth_user, -- AmArg& ret) { -- -- string auth_user_temp = auth_user.empty() ? user : auth_user; -+ string auth_user_temp = (auth_user.empty() || auth_user == "" || auth_user == "NULL") ? user : auth_user; - - DBG("DI method: createRegistration(%i, %s, %s, %s, %s, %s)\n", -- subscriber_id, auth_user_temp.c_str(), user.c_str(), -+ object_id, auth_user_temp.c_str(), user.c_str(), - pass.c_str(), realm.c_str(), contact.c_str()); - -- createRegistration(subscriber_id, auth_user_temp, user, pass, realm, contact); -- scheduleRegistration(subscriber_id); -+ createRegistration(object_id, auth_user_temp, user, pass, realm, contact, type); -+ scheduleRegistration(object_id, type); - ret.push(200); - ret.push("OK"); - } - --void DBRegAgent::DIupdateRegistration(int subscriber_id, const string& user, -- const string& pass, const string& realm, -- const string& contact, const string& auth_user, -- AmArg& ret) { -+void DBRegAgent::DIupdateRegistration(int object_id, const string& user, -+ const string& pass, const string& realm, -+ const string& contact, const string& auth_user, -+ const string& type, AmArg& ret) { - -- string auth_user_temp = auth_user.empty() ? user : auth_user; -+ string auth_user_temp = (auth_user.empty() || auth_user == "" || auth_user == "NULL") ? user : auth_user; - - DBG("DI method: updateRegistration(%i, %s, %s, %s, %s)\n", -- subscriber_id, auth_user_temp.c_str(), user.c_str(), -+ object_id, auth_user_temp.c_str(), user.c_str(), - pass.c_str(), realm.c_str()); - - string contact_uri = contact; -@@ -1141,28 +1466,28 @@ void DBRegAgent::DIupdateRegistration(in - contact_uri = "sip:"+ user + "@" + contact_hostport; - } - -- updateRegistration(subscriber_id, auth_user_temp, user, pass, realm, contact_uri); -+ updateRegistration(object_id, auth_user_temp, user, pass, realm, contact_uri, type); - - ret.push(200); - ret.push("OK"); - } - --void DBRegAgent::DIremoveRegistration(int subscriber_id, AmArg& ret) { -+void DBRegAgent::DIremoveRegistration(int object_id, const string& type, AmArg& ret) { - DBG("DI method: removeRegistration(%i)\n", -- subscriber_id); -- scheduleDeregistration(subscriber_id); -+ object_id); -+ scheduleDeregistration(object_id, type); - - registrations_mut.lock(); -- clearRegistrationTimer(subscriber_id); -+ clearRegistrationTimer(object_id, type); - registrations_mut.unlock(); - - ret.push(200); - ret.push("OK"); - } - --void DBRegAgent::DIrefreshRegistration(int subscriber_id, AmArg& ret) { -- DBG("DI method: refreshRegistration(%i)\n", subscriber_id); -- scheduleRegistration(subscriber_id); -+void DBRegAgent::DIrefreshRegistration(int object_id, const string& type, AmArg& ret) { -+ DBG("DI method: refreshRegistration(%i)\n", object_id); -+ scheduleRegistration(object_id, type); - - ret.push(200); - ret.push("OK"); -@@ -1173,49 +1498,110 @@ void DBRegAgent::DIrefreshRegistration(i - void DBRegAgent::invoke(const string& method, - const AmArg& args, AmArg& ret) - { -+ // create a brand new registration - if (method == "createRegistration"){ -- args.assertArrayFmt("issss"); // subscriber_id, user, pass, realm , auth_user -+ args.assertArrayFmt("issssss"); // object_id, user, pass, realm, contact, auth_user, type - string contact; - string auth_user; -+ string type; // 'peering' or 'subscriber' -+ -+ // for case when: object_id, user, pass, realm, contact - if (args.size() == 5) { - assertArgCStr(args.get(4)); - contact = args.get(4).asCStr(); -- } else if (args.size() > 5) { -+ -+ // for case when: object_id, user, pass, realm, contact, auth_user -+ } else if (args.size() == 6) { -+ assertArgCStr(args.get(4)); -+ assertArgCStr(args.get(5)); -+ contact = args.get(4).asCStr(); -+ auth_user = args.get(5).asCStr(); -+ -+ // for case when: object_id, user, pass, realm, contact, auth_user, type -+ } else if (args.size() == 7) { - assertArgCStr(args.get(4)); - assertArgCStr(args.get(5)); -+ assertArgCStr(args.get(6)); - contact = args.get(4).asCStr(); - auth_user = args.get(5).asCStr(); -+ type = args.get(6).asCStr(); - } -+ -+ // we only allow three possible types: 'peering', 'subscriber' and 'undefined' -+ if (type.empty() || (type != TYPE_PEERING && type != TYPE_SUBSCRIBER && type != TYPE_UNDEFINED)) { -+ DBG("REGISTER: Wrong type of the registration object defined: <%s>. Trying to fix.\n", type.c_str()); -+ type = TYPE_UNDEFINED; -+ } -+ -+ DBG("REGISTER: SEMS is about to Create a registration for: object_id=<%d>, type=<%s>, user=<%s>, realm=<%s> \n", -+ args.get(0).asInt(), type.c_str(), args.get(1).asCStr(), args.get(3).asCStr()); - DIcreateRegistration(args.get(0).asInt(), args.get(1).asCStr(), -- args.get(2).asCStr(), args.get(3).asCStr(), contact, auth_user, ret); -+ args.get(2).asCStr(), args.get(3).asCStr(), contact, auth_user, type, ret); -+ -+ // update an existing registration - } else if (method == "updateRegistration"){ -- args.assertArrayFmt("issss"); // subscriber_id, auth_user, user, pass, realm -+ args.assertArrayFmt("issssss"); // object_id, user, pass, realm, contact, auth_user, type - string contact; - string auth_user; -+ string type; // 'peering' or 'subscriber' -+ -+ // for case when: object_id, user, pass, realm, contact - if (args.size() == 5) { - assertArgCStr(args.get(4)); - contact = args.get(4).asCStr(); -- } else if (args.size() > 5) { -+ -+ // for case when: object_id, user, pass, realm, contact, auth_user -+ } else if (args.size() == 6) { -+ assertArgCStr(args.get(4)); -+ assertArgCStr(args.get(5)); -+ contact = args.get(4).asCStr(); -+ auth_user = args.get(5).asCStr(); -+ -+ // for case when: object_id, user, pass, realm, contact, auth_user, type -+ } else if (args.size() == 7) { - assertArgCStr(args.get(4)); - assertArgCStr(args.get(5)); -+ assertArgCStr(args.get(6)); - contact = args.get(4).asCStr(); - auth_user = args.get(5).asCStr(); -+ type = args.get(6).asCStr(); - } -+ -+ // we only allow three possible types: 'peering', 'subscriber' and 'undefined' -+ if (type.empty() || (type != TYPE_PEERING && type != TYPE_SUBSCRIBER && type != TYPE_UNDEFINED)) { -+ DBG("REGISTER: Wrong type of the registration object defined: <%s>. Trying to fix.\n", type.c_str()); -+ type = TYPE_UNDEFINED; -+ } -+ -+ DBG("REGISTER: SEMS is about to Update a registration for: object_id=<%d>, type=<%s>, user=<%s>, realm=<%s> \n", -+ args.get(0).asInt(), type.c_str(), args.get(1).asCStr(), args.get(3).asCStr()); - DIupdateRegistration(args.get(0).asInt(), args.get(1).asCStr(), -- 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); -- } else if (method == "refreshRegistration"){ -- args.assertArrayFmt("i"); // subscriber_id -- DIrefreshRegistration(args.get(0).asInt(), ret); -- } else if(method == "_list"){ -+ args.get(2).asCStr(), args.get(3).asCStr(), contact, auth_user, type, ret); -+ -+ // remove an existing registration -+ } else if (method == "removeRegistration") { -+ args.assertArrayFmt("is"); // object_id, type -+ string type; // must be 'peering' or 'subscriber' -+ if (args.size() == 2) type = args.get(1).asCStr(); -+ if (type.empty()) type = TYPE_UNDEFINED; -+ DIremoveRegistration(args.get(0).asInt(), type, ret); -+ -+ // refresh an existing registration -+ } else if (method == "refreshRegistration") { -+ args.assertArrayFmt("is"); // object_id, type -+ string type; // must be 'peering' or 'subscriber' -+ if (args.size() == 2) type = args.get(1).asCStr(); -+ if (type.empty()) type = TYPE_UNDEFINED; -+ DIrefreshRegistration(args.get(0).asInt(), type, ret); -+ -+ } else if(method == "_list") { - ret.push(AmArg("createRegistration")); - ret.push(AmArg("updateRegistration")); - ret.push(AmArg("removeRegistration")); - ret.push(AmArg("refreshRegistration")); -- } else -+ } else { - throw AmDynInvoke::NotImplemented(method); -+ } - } - - // /////////////// processor thread ///////////////// ---- 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_PEER_ID "peer_host_id" - #define COLNAME_AUTH_USER "auth_user" - #define COLNAME_USER "user" - #define COLNAME_PASS "pass" -@@ -66,6 +67,11 @@ using std::queue; - #define COLNAME_REGISTRATION_TS "last_registration" - #define COLNAME_LAST_CODE "last_code" - #define COLNAME_LAST_REASON "last_reason" -+#define COLNAME_ID_PK "id" -+ -+#define TYPE_PEERING "peering" -+#define TYPE_SUBSCRIBER "subscriber" -+#define TYPE_UNDEFINED "undefined" - - #define RegistrationActionEventID 117 - -@@ -75,12 +81,13 @@ struct RegistrationActionEvent : public - - enum RegAction { Register=0, Deregister }; - --RegistrationActionEvent(RegAction action, long subscriber_id) -+RegistrationActionEvent(RegAction action, long object_id, const string& type) - : AmEvent(RegistrationActionEventID), -- action(action), subscriber_id(subscriber_id) { } -+ action(action), object_id(object_id), type(type) { } - - RegAction action; -- long subscriber_id; -+ long object_id; -+ const string type; - }; - - class DBRegAgent; -@@ -120,7 +127,8 @@ class DBRegAgent - public AmEventHandler - { - -- static string joined_query; -+ static string joined_query_subscribers; -+ static string joined_query_peerings; - static string registrations_table; - - static double reregister_interval; -@@ -147,9 +155,14 @@ class DBRegAgent - - static unsigned int error_retry_interval; - -- map registrations; -+ map registrations; // usual subscribers - map registration_ltags; - map registration_timers; -+ -+ map registrations_peers; // SIP peerings -+ map registration_ltags_peers; -+ map registration_timers_peers; -+ - AmMutex registrations_mut; - - // connection used in main DBRegAgent thread -@@ -170,59 +183,62 @@ class DBRegAgent - RegistrationTimer registration_scheduler; - DBRegAgentProcessorThread registration_processor; - -- bool loadRegistrations(); -+ bool loadRegistrations(); // for loading subscribers -+ bool loadRegistrationsPeerings(); // for loading peerings - -- void createDBRegistration(long subscriber_id, mysqlpp::Connection& conn); -- void deleteDBRegistration(long subscriber_id, mysqlpp::Connection& conn); -+ void createDBRegistration(long object_id, const string& type, mysqlpp::Connection& conn); -+ void deleteDBRegistration(long object_id, const string& type, mysqlpp::Connection& conn); - void updateDBRegistration(mysqlpp::Connection& db_connection, -- long subscriber_id, int last_code, -+ long object_id, const string& type, int last_code, - const string& last_reason, - bool update_status = false, int status = 0, - bool update_ts=false, unsigned int expiry = 0, - bool update_contacts=false, const string& contacts = ""); - - /** create registration in our list */ -- void createRegistration(long subscriber_id, -+ void createRegistration(long object_id, - const string& auth_user, - const string& user, - const string& pass, - const string& realm, -- const string& contact); -+ const string& contact, -+ const string& type); - /** update registration in our list */ - void updateRegistration(long subscriber_id, - const string& auth_user, - const string& user, - const string& pass, - const string& realm, -- const string& contact); -+ const string& contact, -+ const string& type); - - /** remove registration */ -- void removeRegistration(long subscriber_id); -+ void removeRegistration(long object_id, const string& type); - - /** schedule this subscriber to REGISTER imminently */ -- void scheduleRegistration(long subscriber_id); -+ void scheduleRegistration(long object_id, const string& type); - - /** schedule this subscriber to de-REGISTER imminently*/ -- void scheduleDeregistration(long subscriber_id); -+ void scheduleDeregistration(long object_id, const string& type); - - /** create a timer for the registration - fixed expiry + action */ -- void setRegistrationTimer(long subscriber_id, unsigned int timeout, -- RegistrationActionEvent::RegAction reg_action); -+ void setRegistrationTimer(long object_id, unsigned int timeout, -+ RegistrationActionEvent::RegAction reg_action, const string& type); - - /** create a registration refresh timer for that registration -- @param subscriber_id - ID of subscription -+ @param object_id - ID of subscription - @param expiry - SIP registration expiry time - @param reg_start_ts - start TS of the SIP registration - @param now_time - current time - */ -- void setRegistrationTimer(long subscriber_id, -- time_t expiry, time_t reg_start_ts, time_t now_time); -+ void setRegistrationTimer(long object_id, -+ time_t expiry, time_t reg_start_ts, time_t now_time, const string& type); - - /** clear re-registration timer and remove timer object */ -- void clearRegistrationTimer(long subscriber_id); -+ void clearRegistrationTimer(long object_id, const string& type); - - /** remove timer object */ -- void removeRegistrationTimer(long subscriber_id); -+ void removeRegistrationTimer(long object_id, const string& type); - - // void run_tests(); - -@@ -248,14 +264,14 @@ class DBRegAgent - - AmDynInvoke* uac_auth_i; - -- void DIcreateRegistration(int subscriber_id, const string& user, -+ void DIcreateRegistration(int object_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& contact, const string& auth_user, const string& type, AmArg& ret); -+ void DIupdateRegistration(int object_id, const string& user, - 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); -+ const string& contact, const string& auth_user, const string& type, AmArg& ret); -+ void DIremoveRegistration(int object_id, const string& type, AmArg& ret); -+ void DIrefreshRegistration(int object_id, const string& type, AmArg& ret); - - - public: -@@ -271,7 +287,7 @@ class DBRegAgent - void invoke(const string& method, - const AmArg& args, AmArg& ret); - /** re-registration timer callback */ -- void timer_cb(RegTimer* timer, long subscriber_id, int data2); -+ void timer_cb(RegTimer* timer, long object_id, int data2, const string& type); - - friend class DBRegAgentProcessorThread; - }; ---- a/apps/db_reg_agent/RegistrationTimer.cpp -+++ b/apps/db_reg_agent/RegistrationTimer.cpp -@@ -84,7 +84,7 @@ void RegistrationTimer::place_timer(RegT - void RegistrationTimer::fire_timer(RegTimer* timer) { - if (timer && timer->cb) { - DBG("firing timer [%p]\n", timer); -- timer->cb(timer, timer->data1, timer->data2); -+ timer->cb(timer, timer->data1, timer->data2, timer->data3); - } - } - ---- a/apps/db_reg_agent/RegistrationTimer.h -+++ b/apps/db_reg_agent/RegistrationTimer.h -@@ -34,6 +34,9 @@ - #include "log.h" - #include "AmThread.h" - -+#include -+using std::string; -+ - #define TIMER_BUCKET_LENGTH 10 // 10 sec - #define TIMER_BUCKETS 40000 // 40000 buckets (400000 sec, 111 hrs) - -@@ -41,7 +44,7 @@ - #define TIMER_RESOLUTION 100000 - - class RegTimer; --typedef void (*timer_cb)(RegTimer*, long /*data1*/,int /*data2*/); -+typedef void (*timer_cb)(RegTimer*, long /*data1*/, int /*data2*/, const string& type); - - class RegTimerBucket; - -@@ -52,6 +55,7 @@ class RegTimer { - timer_cb cb; - long data1; - int data2; -+ string data3; - - RegTimer() - : expires(0), cb(0), data1(0), data2(0) { } ---- a/core/AmSipRegistration.cpp -+++ b/core/AmSipRegistration.cpp -@@ -72,9 +72,12 @@ void AmSIPRegistration::setRegistrationI - info = _info; - - cred.realm = info.domain; -- cred.user = info.user; -+ cred.user = info.auth_user.empty() ? info.user : info.auth_user; - cred.pwd = info.pwd; - -+ DBG("REGISTER: new credentials for registrations are: user=<%s>, pass=<%s>, realm=<%s>\n", -+ cred.user.c_str(), cred.pwd.c_str(), cred.realm.c_str()); -+ - req.user = info.user; - req.r_uri = "sip:"+info.domain; - req.from = info.name+" "; diff --git a/debian/patches/sipwise/cpslimit_detect_emergency_calls_and_let_them_pass.patch b/debian/patches/sipwise/cpslimit_detect_emergency_calls_and_let_them_pass.patch deleted file mode 100644 index 81d8f288..00000000 --- a/debian/patches/sipwise/cpslimit_detect_emergency_calls_and_let_them_pass.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 7ffd8f9b54c49e61deada1efc00cfced7616c275 Mon Sep 17 00:00:00 2001 -From: Donat Zenichev -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 app_params; -+ parse_app_params(req.hdrs,app_params); -+ -+ // look into P-App-Param list, try to find 'emergency' marker -+ emergency_flag = false; -+ map::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 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 - #include - -+#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(); diff --git a/debian/patches/sipwise/db_reg_agent_auth_header.patch b/debian/patches/sipwise/db_reg_agent_auth_header.patch deleted file mode 100644 index 12b38b60..00000000 --- a/debian/patches/sipwise/db_reg_agent_auth_header.patch +++ /dev/null @@ -1,333 +0,0 @@ -From 087e126e607c0ec6215cbef7fd47ab29deadd0d0 Mon Sep 17 00:00:00 2001 -From: Fabricio Santolin -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); - diff --git a/debian/patches/sipwise/dsm_mod_curl_fix_ordered_comparison.patch b/debian/patches/sipwise/dsm_mod_curl_fix_ordered_comparison.patch deleted file mode 100644 index a4f597e4..00000000 --- a/debian/patches/sipwise/dsm_mod_curl_fix_ordered_comparison.patch +++ /dev/null @@ -1,47 +0,0 @@ -From b3a3ab6f636394ea214e1f27a1d3702b8c714189 Mon Sep 17 00:00:00 2001 -From: Donat Zenichev -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"); - } - } - } diff --git a/debian/patches/sipwise/dsm_modutils_fix_utils_get_count_files.patch b/debian/patches/sipwise/dsm_modutils_fix_utils_get_count_files.patch deleted file mode 100644 index 8a795ed1..00000000 --- a/debian/patches/sipwise/dsm_modutils_fix_utils_get_count_files.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 2d0775b77c60c8536ecb49302b794a2a36a25a92 Mon Sep 17 00:00:00 2001 -From: Donat Zenichev -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 utils_get_count_files(DSM - - vector 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 -+ - #define MOD_CLS_NAME SCUtilsModule - - DECLARE_MODULE(MOD_CLS_NAME); diff --git a/debian/patches/sipwise/handle_bye_after_180.patch b/debian/patches/sipwise/handle_bye_after_180.patch deleted file mode 100644 index a2230592..00000000 --- a/debian/patches/sipwise/handle_bye_after_180.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 38ad6c8d75fa9e0f3ebcc6320272dd5252505c5f Mon Sep 17 00:00:00 2001 -From: Marco Capetta -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 diff --git a/debian/patches/sipwise/introduce_forcesdp_from_pbx.patch b/debian/patches/sipwise/introduce_forcesdp_from_pbx.patch deleted file mode 100644 index 2522e783..00000000 --- a/debian/patches/sipwise/introduce_forcesdp_from_pbx.patch +++ /dev/null @@ -1,104 +0,0 @@ -From d0d4dc33c2097979deb35464749ec4601d68547b Mon Sep 17 00:00:00 2001 -From: Marco Capetta -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(); } - diff --git a/debian/patches/sipwise/port_to_py3k.patch b/debian/patches/sipwise/port_to_py3k.patch deleted file mode 100644 index 52e2227c..00000000 --- a/debian/patches/sipwise/port_to_py3k.patch +++ /dev/null @@ -1,957 +0,0 @@ -From ef4a7b95cf479acc107792e265d626a6c23bd736 Mon Sep 17 00:00:00 2001 -From: Michael Prokop -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 " % sys.argv[0] -+ print("usage: %s " % 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 " % sys.argv[0] -+ print("usage: %s " % 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 " % sys.argv[0] -+ print("usage: %s " % 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 " % sys.argv[0] -+ print("usage: %s " % 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 " % sys.argv[0] -+ print("usage: %s " % 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 " % sys.argv[0] -+ print("usage: %s " % 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, \ -- 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, -+ 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: diff --git a/debian/patches/sipwise/session_timers b/debian/patches/sipwise/session_timers deleted file mode 100644 index 4ebde2b7..00000000 --- a/debian/patches/sipwise/session_timers +++ /dev/null @@ -1,34 +0,0 @@ -From f47f18c2f666cea2d20a60afe9255ab93ae243bc Mon Sep 17 00:00:00 2001 -From: Marco Capetta -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); diff --git a/debian/patches/sipwise/skip_outbound_auth_if_credentials_empty.patch b/debian/patches/sipwise/skip_outbound_auth_if_credentials_empty.patch deleted file mode 100644 index c55ca2dc..00000000 --- a/debian/patches/sipwise/skip_outbound_auth_if_credentials_empty.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 5ef025a2bf958ba5a78c9091f6f9f7c7fc3c67ce Mon Sep 17 00:00:00 2001 -From: Donat Zenichev -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) && diff --git a/debian/patches/sipwise/sw_vcs.patch b/debian/patches/sipwise/sw_vcs.patch deleted file mode 100644 index 283707f0..00000000 --- a/debian/patches/sipwise/sw_vcs.patch +++ /dev/null @@ -1,2093 +0,0 @@ -From 5d430bb258c024f0b367f0f7d8f957ea53186234 Mon Sep 17 00:00:00 2001 -From: Victor Seva -Date: Thu, 29 Dec 2022 10:14:01 +0100 -Subject: MT#55831 add sw_vcs module - -add sw_vcs module - -(real ticket number: MT#7349) - ---- /dev/null -+++ b/apps/sw_vsc/Makefile -@@ -0,0 +1,10 @@ -+plug_in_name = sw_vsc -+ -+module_ldflags = -lmysqlclient `pcre-config --libs` -lpcrecpp -+module_cflags = -I/usr/include/mysql `pcre-config --cflags` -+module_extra_objs = -+ -+extra_install = $(plug_in_name)_audio -+ -+COREPATH ?=../../core -+include $(COREPATH)/plug-in/Makefile.app_module ---- /dev/null -+++ b/apps/sw_vsc/SW_Vsc.cpp -@@ -0,0 +1,1888 @@ -+#include -+using namespace pcrecpp; -+ -+#include "SW_Vsc.h" -+#include "AmConfig.h" -+#include "AmUtils.h" -+#include "AmPlugIn.h" -+ -+#include "sems.h" -+#include "log.h" -+ -+//#include -+//#include -+#include -+ -+#define MOD_NAME "sw_vsc" -+#define SW_VSC_DATABASE "provisioning" -+ -+#define SW_VSC_GET_ATTRIBUTE_ID "select id from voip_preferences where attribute='%s'" -+#define SW_VSC_GET_SUBSCRIBER_ID "select s.id, d.domain, d.id, s.profile_id, s.username "\ -+ "from voip_subscribers s, voip_domains d "\ -+ "where s.uuid='%s' and s.domain_id = d.id" -+#define SW_VSC_GET_PREFERENCE_ID "select id,value from voip_usr_preferences where subscriber_id=%llu " \ -+ "and attribute_id=%llu" -+#define SW_VSC_DELETE_PREFERENCE_ID "delete from voip_usr_preferences where id=%llu" -+#define SW_VSC_INSERT_PREFERENCE "insert into voip_usr_preferences (subscriber_id, attribute_id, value) "\ -+ "values(%llu, %llu, '%s')" -+#define SW_VSC_UPDATE_PREFERENCE_ID "update voip_usr_preferences set value='%s' where id=%llu" -+#define SW_VSC_INSERT_SPEEDDIAL "replace into voip_speed_dial (subscriber_id, slot, destination) "\ -+ "values(%llu, '%s', '%s')" -+#define SW_VSC_INSERT_REMINDER "replace into voip_reminder (subscriber_id, time, recur) "\ -+ "values(%llu, '%s', '%s')" -+#define SW_VSC_DELETE_REMINDER "delete from voip_reminder where subscriber_id=%llu" -+#define SW_VSC_GET_USER_CALLEE_REWRITE_DPID "select value from " \ -+ "voip_usr_preferences vup, voip_preferences vp where " \ -+ "vup.subscriber_id=%llu and vp.attribute='rewrite_callee_in_dpid' " \ -+ "and vup.attribute_id = vp.id" -+#define SW_VSC_GET_USER_CALLEE_REWRITES \ -+ "select vrr.match_pattern, vrr.replace_pattern from " \ -+ "voip_rewrite_rules vrr, voip_rewrite_rule_sets vrrs " \ -+ "where vrrs.callee_in_dpid=%llu and vrr.set_id = vrrs.id " \ -+ "and vrr.direction='in' and vrr.field='callee' " \ -+ "and vrr.enabled = 1 order by vrr.priority asc" -+#define SW_VSC_GET_DOMAIN_CALLEE_REWRITES \ -+ "select vrr.match_pattern, vrr.replace_pattern " \ -+ "from voip_rewrite_rules vrr, voip_rewrite_rule_sets vrrs, " \ -+ "voip_preferences vp, voip_dom_preferences vdp " \ -+ "where vdp.domain_id=%llu and vp.attribute='rewrite_callee_in_dpid' " \ -+ "and vdp.attribute_id = vp.id and vdp.value = vrrs.callee_in_dpid " \ -+ "and vrr.set_id = vrrs.id and vrr.direction='in' and " \ -+ "vrr.field='callee' and vrr.enabled = 1 order by vrr.priority asc" -+ -+#define SW_VSC_GET_PRIMARY_NUMBER "select alias_username " \ -+ "from kamailio.dbaliases where username='%s' " \ -+ "and domain = '%s' and is_primary" -+ -+#define SW_VSC_DELETE_VSC_DESTSET "delete from voip_cf_destination_sets where "\ -+ "subscriber_id=%llu and name='%s'" -+#define SW_VSC_CREATE_VSC_DESTSET "insert into voip_cf_destination_sets (subscriber_id, name) "\ -+ "values(%llu, '%s')" -+#define SW_VSC_CREATE_VSC_DEST "insert into voip_cf_destinations (destination_set_id, destination, priority) "\ -+ "values(%llu, '%s', %d)" -+#define SW_VSC_DELETE_VSC_CFMAP "delete from voip_cf_mappings where subscriber_id=%llu and type='%s'" -+#define SW_VSC_CREATE_VSC_CFMAP "insert into voip_cf_mappings "\ -+ "(subscriber_id, type, destination_set_id, time_set_id) "\ -+ "values(%llu, '%s', %llu, NULL)" -+ -+#define SW_VSC_GET_SUBPROFILE_ATTRIBUTE "select id from voip_subscriber_profile_attributes "\ -+ "where profile_id=%llu and attribute_id=%llu" -+ -+#define SW_VSC_DESTSET_CFU "cfu_by_vsc" -+#define SW_VSC_DESTSET_CFB "cfb_by_vsc" -+#define SW_VSC_DESTSET_CFT "cft_by_vsc" -+#define SW_VSC_DESTSET_CFNA "cfna_by_vsc" -+ -+EXPORT_SESSION_FACTORY(SW_VscFactory, MOD_NAME); -+ -+SW_VscFactory::SW_VscFactory(const string &_app_name) -+ : AmSessionFactory(_app_name) -+{ -+} -+ -+SW_VscFactory::~SW_VscFactory() -+{ -+ regfree(&m_patterns.cfuOnPattern); -+ regfree(&m_patterns.cfuOffPattern); -+ regfree(&m_patterns.cfbOnPattern); -+ regfree(&m_patterns.cfbOffPattern); -+ regfree(&m_patterns.cftOnPattern); -+ regfree(&m_patterns.cftOffPattern); -+ regfree(&m_patterns.cfnaOnPattern); -+ regfree(&m_patterns.cfnaOffPattern); -+ regfree(&m_patterns.speedDialPattern); -+ regfree(&m_patterns.reminderOnPattern); -+ regfree(&m_patterns.reminderOffPattern); -+} -+ -+int SW_VscFactory::onLoad() -+{ -+ string cfuOnPattern; -+ string cfuOffPattern; -+ string cfbOnPattern; -+ string cfbOffPattern; -+ string cftOnPattern; -+ string cftOffPattern; -+ string cfnaOnPattern; -+ string cfnaOffPattern; -+ string speedDialPattern; -+ string reminderOnPattern; -+ string reminderOffPattern; -+ -+ AmConfigReader cfg; -+ if (cfg.loadFile(AmConfig::ModConfigPath + string(MOD_NAME ".conf"))) -+ return -1; -+ -+ configureModule(cfg); -+ -+ -+ m_patterns.mysqlHost = cfg.getParameter("mysql_host", ""); -+ if (m_patterns.mysqlHost.empty()) -+ { -+ ERROR("MysqlHost is empty\n"); -+ return -1; -+ } -+ m_patterns.mysqlPort = cfg.getParameterInt("mysql_port", 0); -+ if (m_patterns.mysqlPort < 0 || m_patterns.mysqlPort > 65535) -+ { -+ ERROR("MysqlPort is invalid\n"); -+ return -1; -+ } -+ m_patterns.mysqlUser = cfg.getParameter("mysql_user", ""); -+ if (m_patterns.mysqlUser.empty()) -+ { -+ ERROR("MysqlUser is empty\n"); -+ return -1; -+ } -+ m_patterns.mysqlPass = cfg.getParameter("mysql_pass", ""); -+ if (m_patterns.mysqlPass.empty()) -+ { -+ ERROR("MysqlPass is empty\n"); -+ return -1; -+ } -+ -+ m_patterns.audioPath = cfg.getParameter("announce_path", ANNOUNCE_PATH); -+ if (m_patterns.audioPath.empty()) -+ { -+ ERROR("AnnouncePath option announce_path is empty.\n"); -+ return -1; -+ } -+ if (m_patterns.audioPath[m_patterns.audioPath.length() - 1] != '/' ) -+ m_patterns.audioPath += "/"; -+ -+ m_patterns.failAnnouncement = cfg.getParameter("error_announcement", ""); -+ if (m_patterns.failAnnouncement.empty()) -+ { -+ ERROR("ErrorAnnouncement file not set\n"); -+ return -1; -+ } -+ m_patterns.unknownAnnouncement = cfg.getParameter("unknown_announcement", ""); -+ if (m_patterns.unknownAnnouncement.empty()) -+ { -+ ERROR("UnknownAnnouncement file not set\n"); -+ return -1; -+ } -+ m_patterns.cfuOnAnnouncement = cfg.getParameter("cfu_on_announcement", ""); -+ if (m_patterns.cfuOnAnnouncement.empty()) -+ { -+ ERROR("CfuOnAnnouncement file not set\n"); -+ return -1; -+ } -+ m_patterns.cfuOffAnnouncement = cfg.getParameter("cfu_off_announcement", ""); -+ if (m_patterns.cfuOffAnnouncement.empty()) -+ { -+ ERROR("CfuOffAnnouncement file not set\n"); -+ return -1; -+ } -+ m_patterns.cfbOnAnnouncement = cfg.getParameter("cfb_on_announcement", ""); -+ if (m_patterns.cfbOnAnnouncement.empty()) -+ { -+ ERROR("CfbOnAnnouncement file not set\n"); -+ return -1; -+ } -+ m_patterns.cfbOffAnnouncement = cfg.getParameter("cfb_off_announcement", ""); -+ if (m_patterns.cfbOffAnnouncement.empty()) -+ { -+ ERROR("CfbOffAnnouncement file not set\n"); -+ return -1; -+ } -+ m_patterns.cftOnAnnouncement = cfg.getParameter("cft_on_announcement", ""); -+ if (m_patterns.cftOnAnnouncement.empty()) -+ { -+ ERROR("CftOnAnnouncement file not set\n"); -+ return -1; -+ } -+ m_patterns.cftOffAnnouncement = cfg.getParameter("cft_off_announcement", ""); -+ if (m_patterns.cftOffAnnouncement.empty()) -+ { -+ ERROR("CftOffAnnouncement file not set\n"); -+ return -1; -+ } -+ m_patterns.cfnaOnAnnouncement = cfg.getParameter("cfna_on_announcement", ""); -+ if (m_patterns.cfnaOnAnnouncement.empty()) -+ { -+ ERROR("CfnaOnAnnouncement file not set\n"); -+ return -1; -+ } -+ m_patterns.cfnaOffAnnouncement = cfg.getParameter("cfna_off_announcement", ""); -+ if (m_patterns.cfnaOffAnnouncement.empty()) -+ { -+ ERROR("CfnaOffAnnouncement file not set\n"); -+ return -1; -+ } -+ m_patterns.speedDialAnnouncement = cfg.getParameter("speed_dial_announcement", ""); -+ if (m_patterns.speedDialAnnouncement.empty()) -+ { -+ ERROR("SpeedDialAnnouncement file not set\n"); -+ return -1; -+ } -+ m_patterns.reminderOnAnnouncement = cfg.getParameter("reminder_on_announcement", ""); -+ if (m_patterns.reminderOnAnnouncement.empty()) -+ { -+ ERROR("ReminderOnAnnouncement file not set\n"); -+ return -1; -+ } -+ m_patterns.reminderOffAnnouncement = cfg.getParameter("reminder_off_announcement", ""); -+ if (m_patterns.reminderOffAnnouncement.empty()) -+ { -+ ERROR("ReminderOffAnnouncement file not set\n"); -+ return -1; -+ } -+ -+ -+ m_patterns.voicemailNumber = cfg.getParameter("voicemail_number", ""); -+ if (m_patterns.voicemailNumber.empty()) -+ { -+ ERROR("voicemailNumber is empty\n"); -+ return -1; -+ } -+ -+ cfuOnPattern = cfg.getParameter("cfu_on_pattern", ""); -+ if (cfuOnPattern.empty()) -+ { -+ ERROR("CfuOnPattern is empty\n"); -+ return -1; -+ } -+ if (regcomp(&m_patterns.cfuOnPattern, cfuOnPattern.c_str(), REG_EXTENDED | REG_NOSUB)) -+ { -+ ERROR("CfuOnPattern failed to compile ('%s'): %s\n", -+ cfuOnPattern.c_str(), -+ strerror(errno)); -+ return -1; -+ } -+ -+ cfuOffPattern = cfg.getParameter("cfu_off_pattern", ""); -+ if (cfuOffPattern.empty()) -+ { -+ ERROR("CfuOffPattern is empty\n"); -+ return -1; -+ } -+ if (regcomp(&m_patterns.cfuOffPattern, cfuOffPattern.c_str(), REG_EXTENDED | REG_NOSUB)) -+ { -+ ERROR("CfuOffPattern failed to compile ('%s'): %s\n", -+ cfuOffPattern.c_str(), -+ strerror(errno)); -+ return -1; -+ } -+ -+ cfbOnPattern = cfg.getParameter("cfb_on_pattern", ""); -+ if (cfbOnPattern.empty()) -+ { -+ ERROR("CfbOnPattern is empty\n"); -+ return -1; -+ } -+ if (regcomp(&m_patterns.cfbOnPattern, cfbOnPattern.c_str(), REG_EXTENDED | REG_NOSUB)) -+ { -+ ERROR("CfbOnPattern failed to compile ('%s'): %s\n", -+ cfbOnPattern.c_str(), -+ strerror(errno)); -+ return -1; -+ } -+ -+ cfbOffPattern = cfg.getParameter("cfb_off_pattern", ""); -+ if (cfbOffPattern.empty()) -+ { -+ ERROR("CfbOffPattern is empty\n"); -+ return -1; -+ } -+ if (regcomp(&m_patterns.cfbOffPattern, cfbOffPattern.c_str(), REG_EXTENDED | REG_NOSUB)) -+ { -+ ERROR("CfbOffPattern 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; -+ } -+ if (regcomp(&m_patterns.cftOnPattern, cftOnPattern.c_str(), REG_EXTENDED | REG_NOSUB)) -+ { -+ ERROR("CftOnPattern failed to compile ('%s'): %s\n", -+ cftOnPattern.c_str(), -+ strerror(errno)); -+ return -1; -+ } -+ -+ cftOffPattern = cfg.getParameter("cft_off_pattern", ""); -+ if (cftOffPattern.empty()) -+ { -+ ERROR("CftOffPattern is empty\n"); -+ return -1; -+ } -+ if (regcomp(&m_patterns.cftOffPattern, cftOffPattern.c_str(), REG_EXTENDED | REG_NOSUB)) -+ { -+ ERROR("CftOffPattern failed to compile ('%s'): %s\n", -+ cftOffPattern.c_str(), -+ strerror(errno)); -+ return -1; -+ } -+ -+ cfnaOnPattern = cfg.getParameter("cfna_on_pattern", ""); -+ if (cfnaOnPattern.empty()) -+ { -+ ERROR("CfnaOnPattern is empty\n"); -+ return -1; -+ } -+ if (regcomp(&m_patterns.cfnaOnPattern, cfnaOnPattern.c_str(), REG_EXTENDED | REG_NOSUB)) -+ { -+ ERROR("CfnaOnPattern failed to compile ('%s'): %s\n", -+ cfnaOnPattern.c_str(), -+ strerror(errno)); -+ return -1; -+ } -+ -+ cfnaOffPattern = cfg.getParameter("cfna_off_pattern", ""); -+ if (cfnaOffPattern.empty()) -+ { -+ ERROR("CfnaOffPattern is empty\n"); -+ return -1; -+ } -+ if (regcomp(&m_patterns.cfnaOffPattern, cfnaOffPattern.c_str(), REG_EXTENDED | REG_NOSUB)) -+ { -+ ERROR("CfnaOffPattern failed to compile ('%s'): %s\n", -+ cfnaOffPattern.c_str(), -+ strerror(errno)); -+ return -1; -+ } -+ -+ speedDialPattern = cfg.getParameter("speed_dial_pattern", ""); -+ if (speedDialPattern.empty()) -+ { -+ ERROR("SpeedDialPattern is empty\n"); -+ return -1; -+ } -+ if (regcomp(&m_patterns.speedDialPattern, speedDialPattern.c_str(), REG_EXTENDED | REG_NOSUB)) -+ { -+ ERROR("SpeedDialPattern 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; -+ } -+ if (regcomp(&m_patterns.reminderOnPattern, reminderOnPattern.c_str(), REG_EXTENDED | REG_NOSUB)) -+ { -+ ERROR("ReminderOnPattern 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; -+ } -+ if (regcomp(&m_patterns.reminderOffPattern, reminderOffPattern.c_str(), -+ REG_EXTENDED | REG_NOSUB)) -+ { -+ ERROR("ReminderOffPattern failed to compile ('%s'): %s\n", -+ reminderOffPattern.c_str(), -+ strerror(errno)); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+AmSession *SW_VscFactory::onInvite(const AmSipRequest &req, -+ const string &app_name, -+ const map &app_params) -+{ -+ return new SW_VscDialog(&m_patterns, NULL); -+} -+ -+AmSession *SW_VscFactory::onInvite(const AmSipRequest &req, -+ const string &app_name, -+ AmArg &session_params) -+{ -+ UACAuthCred *cred = AmUACAuth::unpackCredentials(session_params); -+ AmSession *s = new SW_VscDialog(&m_patterns, cred); -+ -+ if (NULL == cred) -+ { -+ WARN("discarding unknown session parameters.\n"); -+ } -+ else -+ { -+ AmUACAuth::enable(s); -+ } -+ -+ return s; -+} -+ -+SW_VscDialog::SW_VscDialog(sw_vsc_patterns_t *patterns, -+ UACAuthCred *credentials) -+ : m_patterns(patterns), cred(credentials) -+{ -+} -+ -+SW_VscDialog::~SW_VscDialog() -+{ -+} -+ -+void SW_VscDialog::onSessionStart() -+{ -+ DBG("SW_VscDialog::onSessionStart()...\n"); -+ AmSession::onSessionStart(); -+} -+ -+void SW_VscDialog::onStart() { -+} -+ -+u_int64_t SW_VscDialog::getAttributeId(MYSQL *my_handler, const char *attribute) -+{ -+ MYSQL_RES *res; -+ MYSQL_ROW row; -+ char query[1024] = ""; -+ u_int64_t id; -+ -+ snprintf(query, sizeof(query), SW_VSC_GET_ATTRIBUTE_ID, attribute); -+ -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error fetching id for attribute '%s': %s", attribute, -+ mysql_error(my_handler)); -+ return 0; -+ } -+ -+ res = mysql_store_result(my_handler); -+ if (mysql_num_rows(res) != 1) -+ { -+ ERROR("Found invalid number of id entries for attribute '%s': %llu", -+ attribute, mysql_num_rows(res)); -+ return 0; -+ } -+ -+ row = mysql_fetch_row(res); -+ if (row == NULL || row[0] == NULL) -+ { -+ ERROR("Failed to fetch row for attribute id: %s\n", -+ mysql_error(my_handler)); -+ return 0; -+ } -+ -+ id = atoll(row[0]); -+ mysql_free_result(res); -+ return id; -+} -+ -+int SW_VscDialog::checkSubscriberProfile(MYSQL *my_handler, u_int64_t profileId, u_int64_t attributeId) -+{ -+ MYSQL_RES *res; -+ MYSQL_ROW row; -+ char query[1024] = ""; -+ int ret = 0; -+ -+ // if no profile is set, allow by default -+ if(profileId == 0) -+ { -+ INFO("Allow preference due to unset subscriber profile"); -+ return 1; -+ } -+ -+ snprintf(query, sizeof(query), SW_VSC_GET_SUBPROFILE_ATTRIBUTE, -+ (unsigned long long int) profileId, (unsigned long long int) attributeId); -+ -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error checking profile attributes for profile '%llu' and attribute %llu: %s", -+ (unsigned long long int) profileId, (unsigned long long int) attributeId, -+ mysql_error(my_handler)); -+ return 0; -+ } -+ -+ res = mysql_store_result(my_handler); -+ if (mysql_num_rows(res) >= 1) -+ { -+ INFO("Allow preference attribute %llu as it is in profile %llu", -+ (unsigned long long int) attributeId, (unsigned long long int) profileId); -+ ret = 1; -+ } -+ else -+ { -+ INFO("Reject preference attribute %llu as it is not in profile %llu", -+ (unsigned long long int) attributeId, (unsigned long long int) profileId); -+ ret = 0; -+ } -+ return ret; -+} -+ -+u_int64_t SW_VscDialog::getSubscriberId(MYSQL *my_handler, const char *uuid, -+ string *domain, u_int64_t &domain_id, -+ u_int64_t &profile_id, string *username) -+{ -+ MYSQL_RES *res; -+ MYSQL_ROW row; -+ char query[1024] = ""; -+ u_int64_t id; -+ -+ snprintf(query, sizeof(query), SW_VSC_GET_SUBSCRIBER_ID, uuid); -+ -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error fetching id for subscriber '%s': %s", uuid, -+ mysql_error(my_handler)); -+ return 0; -+ } -+ -+ res = mysql_store_result(my_handler); -+ if (mysql_num_rows(res) != 1) -+ { -+ ERROR("Found invalid number of id entries for uuid '%s': %llu", -+ uuid , mysql_num_rows(res)); -+ return 0; -+ } -+ -+ row = mysql_fetch_row(res); if (row == NULL || row[0] == NULL || row[1] == -+ NULL || row[2] == NULL) -+ { -+ ERROR("Failed to fetch row for uuid id: %s\n", -+ mysql_error(my_handler)); return 0; -+ } -+ -+ id = atoll(row[0]); -+ domain->clear(); -+ *domain += string(row[1]); -+ domain_id = atoll(row[2]); -+ profile_id = row[3] == NULL ? 0 : atoll(row[3]); -+ username->clear(); -+ *username += string(row[4]); -+ mysql_free_result(res); -+ return id; -+} -+ -+u_int64_t SW_VscDialog::getPreference(MYSQL *my_handler, u_int64_t subscriberId, -+ u_int64_t attributeId, int *foundPref, -+ string *value) -+{ -+ 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, -+ (unsigned long long int)attributeId); -+ -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error fetching preference id for subscriber id '%llu' and attribute id '%llu': %s", -+ (unsigned long long int)subscriberId, -+ (unsigned long long int)attributeId, mysql_error(my_handler)); -+ return 0; -+ } -+ -+ res = mysql_store_result(my_handler); -+ if (mysql_num_rows(res) == 0) -+ { -+ mysql_free_result(res); -+ return 1; -+ } -+ if (mysql_num_rows(res) != 1) -+ { -+ ERROR("Found invalid number of id entries for subscriber id '%llu' and attribute id '%llu': %llu", -+ (unsigned long long int)subscriberId, -+ (unsigned long long int)attributeId, mysql_num_rows(res)); -+ mysql_free_result(res); -+ return 0; -+ } -+ -+ row = mysql_fetch_row(res); -+ if (row == NULL || row[0] == NULL) -+ { -+ ERROR("Failed to fetch row for preference id: %s\n", -+ mysql_error(my_handler)); -+ mysql_free_result(res); -+ return 0; -+ } -+ id = atoll(row[0]); -+ value->clear(); -+ *value += row[1]; -+ mysql_free_result(res); -+ *foundPref = 1; -+ return id; -+} -+ -+int SW_VscDialog::deletePreferenceId(MYSQL *my_handler, u_int64_t preferenceId) -+{ -+ char query[1024] = ""; -+ -+ snprintf(query, sizeof(query), SW_VSC_DELETE_PREFERENCE_ID, -+ (unsigned long long int)preferenceId); -+ -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error deleting preference id '%llu': %s", -+ (unsigned long long int)preferenceId, mysql_error(my_handler)); -+ return 0; -+ } -+ return 1; -+} -+ -+int SW_VscDialog::insertPreference(MYSQL *my_handler, u_int64_t subscriberId, -+ u_int64_t attributeId, string &uri) -+{ -+ char query[1024] = ""; -+ -+ snprintf(query, sizeof(query), SW_VSC_INSERT_PREFERENCE, -+ (unsigned long long int)subscriberId, -+ (unsigned long long int)attributeId, uri.c_str()); -+ -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error inserting preference for subscriber id '%llu': %s", -+ (unsigned long long int)subscriberId, mysql_error(my_handler)); -+ return 0; -+ } -+ return 1; -+} -+ -+int SW_VscDialog::updatePreferenceId(MYSQL *my_handler, -+ u_int64_t preferenceId, string &uri) -+{ -+ char query[1024] = ""; -+ -+ snprintf(query, sizeof(query), SW_VSC_UPDATE_PREFERENCE_ID, -+ uri.c_str(), (unsigned long long int)preferenceId); -+ -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error updating preference id '%llu': %s", -+ (unsigned long long int)preferenceId, mysql_error(my_handler)); -+ return 0; -+ } -+ return 1; -+} -+ -+int SW_VscDialog::insertReminder(MYSQL *my_handler, u_int64_t subscriberId, -+ string &repeat, string &tim) -+{ -+ char query[1024] = ""; -+ -+ snprintf(query, sizeof(query), SW_VSC_INSERT_REMINDER, -+ (unsigned long long int)subscriberId, -+ tim.c_str(), repeat.c_str()); -+ -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error setting reminder for subscriber id '%llu': %s", -+ (unsigned long long int)subscriberId, mysql_error(my_handler)); -+ return 0; -+ } -+ return 1; -+} -+ -+int SW_VscDialog::deleteReminder(MYSQL *my_handler, u_int64_t subscriberId) -+{ -+ char query[1024] = ""; -+ -+ snprintf(query, sizeof(query), SW_VSC_DELETE_REMINDER, -+ (unsigned long long int)subscriberId); -+ -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error deleting reminder for subscriber id '%llu': %s", -+ (unsigned long long int)subscriberId, mysql_error(my_handler)); -+ return 0; -+ } -+ return 1; -+} -+ -+int SW_VscDialog::insertSpeedDialSlot(MYSQL *my_handler, -+ u_int64_t subscriberId, -+ string &slot, string &uri) -+{ -+ char query[1024] = ""; -+ -+ snprintf(query, sizeof(query), SW_VSC_INSERT_SPEEDDIAL, -+ (unsigned long long int)subscriberId, slot.c_str(), uri.c_str()); -+ -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error inserting speed-dial slot '%s' for subscriber id '%llu': %s", -+ slot.c_str(), (unsigned long long int)subscriberId, -+ mysql_error(my_handler)); -+ return 0; -+ } -+ return 1; -+} -+ -+ -+int SW_VscDialog::number2uri(const AmSipRequest &req, MYSQL *my_handler, -+ string &uuid, u_int64_t subId, -+ string &domain, u_int64_t domId, -+ int offset, string &uri, string &username) -+{ -+ string num = "", acStr = "", ccStr = ""; -+ u_int64_t acAttId, ccAttId; -+ int foundPref; -+ char query[1024] = ""; -+ my_ulonglong num_rows; -+ MYSQL_RES *res; -+ MYSQL_ROW row; -+ RE *re; -+ -+ if (req.user.compare(0, 1, "*", 1) == 0) -+ { -+ num = req.user.substr(offset); -+ -+ if (m_patterns->voicemailNumber == num) -+ { -+ snprintf(query, sizeof(query), -+ SW_VSC_GET_PRIMARY_NUMBER, -+ username.c_str(), domain.c_str()); -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error fetching primary number for username '%s'" -+ " at domain '%s': %s", -+ username.c_str(), domain.c_str(), -+ mysql_error(my_handler)); -+ return 0; -+ } -+ res = mysql_store_result(my_handler); -+ row = mysql_fetch_row(res); -+ if (row == NULL || row[0] == NULL) -+ { -+ INFO("no primary number for username '%s'" -+ " at domain '%s' found. Use uuid: %s", -+ username.c_str(), domain.c_str(), -+ uuid.c_str()); -+ uri = string("sip:vmu") + uuid + "@voicebox.local"; -+ } -+ else { -+ uri = string("sip:vmu") + row[0] + "@voicebox.local"; -+ } -+ INFO("Normalized '%s' to voicemail uri '%s' for uuid '%s'", -+ num.c_str(), uri.c_str(), uuid.c_str()); -+ mysql_free_result(res); -+ return 1; -+ } -+ -+ snprintf(query, sizeof(query), -+ SW_VSC_GET_USER_CALLEE_REWRITE_DPID, -+ (unsigned long long int)subId); -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error fetching rewrite rule dpid for subscriber uuid '%s' (id %llu): %s", -+ uuid.c_str(), (unsigned long long int)subId, -+ mysql_error(my_handler)); -+ return 0; -+ } -+ res = mysql_store_result(my_handler); -+ if ((num_rows = mysql_num_rows(res)) != 0) -+ { -+ row = mysql_fetch_row(res); -+ if (row == NULL || row[0] == NULL) -+ { -+ ERROR("Failed to fetch row for user callee rewrite rule: %s\n", mysql_error(my_handler)); -+ mysql_free_result(res); -+ return 0; -+ } -+ u_int64_t dpid = atoll(row[0]); -+ INFO("Found user rewrite rule dpid '%llu' for subscriber uuid '%s' (id %llu)", -+ (unsigned long long int)dpid, uuid.c_str(), -+ (unsigned long long int)subId); -+ mysql_free_result(res); -+ snprintf(query, sizeof(query), SW_VSC_GET_USER_CALLEE_REWRITES, -+ (unsigned long long int)dpid); -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error fetching user callee rewrite rules for dpid '%llu' for subscriber uuid '%s': %s", -+ (unsigned long long int)dpid, uuid.c_str(), -+ mysql_error(my_handler)); -+ return 0; -+ } -+ res = mysql_store_result(my_handler); -+ if ((num_rows = mysql_num_rows(res)) == 0) -+ { -+ mysql_free_result(res); -+ uri = string("sip:+") + num + "@" + domain; -+ INFO("No user callee rewrite rules for subscriber uuid '%s' (id '%llu')", -+ uuid.c_str(), (unsigned long long int)subId); -+ return 1; -+ } -+ } -+ else -+ { -+ mysql_free_result(res); -+ INFO("No user rewrite rule for subscriber uuid '%s' (id %llu), falling back to domain '%s' (id %llu)", -+ uuid.c_str(), (unsigned long long int)subId, -+ domain.c_str(), (unsigned long long int)domId); -+ -+ snprintf(query, sizeof(query), SW_VSC_GET_DOMAIN_CALLEE_REWRITES, -+ (unsigned long long int)domId); -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error fetching domain callee rewrite rules for domain id '%llu' (domain '%s') for subscriber uuid '%s': %s", -+ (unsigned long long int)domId, domain.c_str(), -+ uuid.c_str(), mysql_error(my_handler)); -+ return 0; -+ } -+ res = mysql_store_result(my_handler); -+ if ((num_rows = mysql_num_rows(res)) == 0) -+ { -+ mysql_free_result(res); -+ uri = string("sip:+") + num + "@" + domain; -+ INFO("No domain callee rewrite rules for domain id '%llu' (domain '%s') for subscriber uuid '%s'", -+ (unsigned long long int)domId, domain.c_str(), -+ uuid.c_str()); -+ return 1; -+ } -+ } -+ -+ for (my_ulonglong i = 0; i < num_rows; ++i) -+ { -+ row = mysql_fetch_row(res); -+ if (row == NULL || row[0] == NULL || row[1] == NULL) -+ { -+ ERROR("Failed to fetch row for callee rewrite rule: %s\n", -+ mysql_error(my_handler)); -+ mysql_free_result(res); -+ return 0; -+ } -+ -+ re = new RE(row[0]); -+ if (re == NULL || re->error().length() > 0) -+ { -+ ERROR("A callee rewrite rule match pattern ('%s') failed to compile: %s\n", -+ row[0], (re ? re->error().c_str() : "unknown")); -+ if (re) delete re; -+ mysql_free_result(res); -+ return 0; -+ } -+ if (re->Replace(row[1], &num)) -+ { -+ INFO("The callee rewrite rule pattern ('%s' and '%s') for subscriber id %llu and domain id %llu matched, result is '%s'\n", -+ row[0], row[1], (unsigned long long int)subId, -+ (unsigned long long int)domId, num.c_str()); -+ delete re; -+ break; -+ } -+ delete re; -+ } -+ -+ mysql_free_result(res); -+ -+ // we need to replace $avp(s:caller_ac) and $avp(s:caller_cc) -+ // with the actual values here -+ -+ acAttId = getAttributeId(my_handler, "ac"); -+ if (!acAttId) -+ return 0; -+ ccAttId = getAttributeId(my_handler, "cc"); -+ if (!ccAttId) -+ return 0; -+ if (!getPreference(my_handler, subId, acAttId, &foundPref, &acStr)) -+ return 0; -+ if (!getPreference(my_handler, subId, ccAttId, &foundPref, &ccStr)) -+ return 0; -+ -+ re = new RE("\\$avp\\(s:caller_ac\\)"); -+ if (re->GlobalReplace(acStr, &num)) -+ { -+ INFO("Successfully replaced $avp(s:caller_ac) by preference value '%s' for subscriber id %llu and domain id %llu", -+ acStr.c_str(), (unsigned long long int)subId, -+ (unsigned long long int)domId); -+ } -+ delete re; -+ re = new RE("\\$avp\\(s:caller_cc\\)"); -+ if (re->GlobalReplace(ccStr, &num)) -+ { -+ INFO("Successfully replaced $avp(s:caller_cc) by preference value '%s' for subscriber id %llu and domain id %llu", -+ ccStr.c_str(), (unsigned long long int)subId, -+ (unsigned long long int)domId); -+ } -+ delete re; -+ -+ INFO("Final normalized number is '%s' for subscriber id %llu and domain id %llu", -+ num.c_str(), (unsigned long long int)subId, -+ (unsigned long long int)domId); -+ uri = string("sip:+") + num + "@" + domain; -+ } -+ return 1; -+} -+ -+u_int64_t SW_VscDialog::createCFMap(MYSQL *my_handler, u_int64_t subscriberId, -+ string &uri, const char *mapName, -+ const char *type) -+{ -+ u_int64_t dsetId; -+ u_int64_t mapId; -+ char query[1024] = ""; -+ -+ // first, delete potentially existing vsc destination set for subscriber -+ snprintf(query, sizeof(query), SW_VSC_DELETE_VSC_DESTSET, -+ (unsigned long long int)subscriberId, mapName); -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error deleting existing CF destination set '%s' for subscriber id '%llu': %s", -+ mapName, (unsigned long long int)subscriberId, -+ mysql_error(my_handler)); -+ return 0; -+ } -+ -+ // create a new destination set -+ snprintf(query, sizeof(query), SW_VSC_CREATE_VSC_DESTSET, -+ (unsigned long long int)subscriberId, mapName); -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error creating new CF destination set '%s' for subscriber id '%llu': %s", -+ mapName, (unsigned long long int)subscriberId, -+ mysql_error(my_handler)); -+ return 0; -+ } -+ dsetId = mysql_insert_id(my_handler); -+ if (!dsetId) -+ { -+ ERROR("Error fetching last insert id of CF destination set for subscriber id '%llu'", -+ (unsigned long long int)subscriberId); -+ return 0; -+ } -+ -+ // create new destination entry -+ snprintf(query, sizeof(query), SW_VSC_CREATE_VSC_DEST, -+ (unsigned long long int)dsetId, -+ uri.c_str(), 1); -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error creating new CF destination '%s' for destination set id '%llu': %s", -+ uri.c_str(), (unsigned long long int)dsetId, -+ mysql_error(my_handler)); -+ return 0; -+ } -+ -+ // delete existing mapping -+ snprintf(query, sizeof(query), SW_VSC_DELETE_VSC_CFMAP, -+ (unsigned long long int)subscriberId, type); -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error deleting existing CF destination mapping for subscriber id '%llu' and type '%s': %s", -+ (unsigned long long int)subscriberId, type, -+ mysql_error(my_handler)); -+ return 0; -+ } -+ -+ // create new mapping -+ snprintf(query, sizeof(query), SW_VSC_CREATE_VSC_CFMAP, -+ (unsigned long long int)subscriberId, -+ type, (unsigned long long int)dsetId); -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error creating CF destination mapping for subscriber id '%llu' and type '%s' to destination set id '%llu': %s", -+ (unsigned long long int)subscriberId, type, -+ (unsigned long long int)dsetId, mysql_error(my_handler)); -+ return 0; -+ } -+ mapId = mysql_insert_id(my_handler); -+ if (!mapId) -+ { -+ ERROR("Error fetching last insert id of CF mapping for subscriber id '%llu' and type '%s'", -+ (unsigned long long int)subscriberId, type); -+ return 0; -+ } -+ -+ return mapId; -+ -+} -+ -+u_int64_t SW_VscDialog::deleteCFMap(MYSQL *my_handler, u_int64_t subscriberId, -+ const char *mapName, const char *type) -+{ -+ char query[1024] = ""; -+ -+ // first, delete potentially existing vsc destination set for subscriber -+ snprintf(query, sizeof(query), SW_VSC_DELETE_VSC_DESTSET, -+ (unsigned long long int)subscriberId, mapName); -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error deleting existing CF destination set '%s' for subscriber id '%llu': %s", -+ mapName, (unsigned long long int)subscriberId, -+ mysql_error(my_handler)); -+ return 0; -+ } -+ -+ // delete existing mapping -+ snprintf(query, sizeof(query), SW_VSC_DELETE_VSC_CFMAP, -+ (unsigned long long int)subscriberId, type); -+ if (mysql_real_query(my_handler, query, strlen(query)) != 0) -+ { -+ ERROR("Error deleting existing CF destination mapping for subscriber id '%llu' and type '%s': %s", -+ (unsigned long long int)subscriberId, type, -+ mysql_error(my_handler)); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+void SW_VscDialog::onInvite(const AmSipRequest &req) -+{ -+ /// fooooo -+ if(dlg->getStatus() == AmSipDialog::Connected){ -+ AmSession::onInvite(req); -+ return; -+ } -+ -+ int ret; -+ string filename; -+ MYSQL *my_handler = NULL; -+ my_bool recon = 1; -+ -+ u_int64_t subId, domId, profId; -+ string domain, uri, username; -+ char map_str[128] = ""; -+ string mapStr, prefStr; -+ int foundPref = 0; -+ -+ string failAnnouncement; -+ string unknownAnnouncement; -+ string cfuOnAnnouncement; -+ string cfuOffAnnouncement; -+ string cfbOnAnnouncement; -+ string cfbOffAnnouncement; -+ string cftOnAnnouncement; -+ string cftOffAnnouncement; -+ string cfnaOnAnnouncement; -+ string cfnaOffAnnouncement; -+ string speedDialAnnouncement; -+ string reminderOnAnnouncement; -+ string reminderOffAnnouncement; -+ -+ string uuid = getHeader(req.hdrs, "P-Caller-UUID"); -+ if (!uuid.length()) -+ { -+ ERROR("Application header P-Caller-UUID not found\n"); -+ throw AmSession::Exception(500, "could not get UUID parameter"); -+ } -+ string lang = getHeader(req.hdrs, "P-Language"); -+ if (!lang.length()) -+ { -+ lang = "en"; -+ } -+ lang += "/"; -+ -+ -+ failAnnouncement = m_patterns->audioPath + lang + m_patterns->failAnnouncement; -+ if (!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)) -+ { -+ 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; -+ } -+ -+ my_handler = mysql_init(NULL); -+ if (!mysql_real_connect(my_handler, -+ m_patterns->mysqlHost.c_str(), -+ m_patterns->mysqlUser.c_str(), -+ m_patterns->mysqlPass.c_str(), -+ SW_VSC_DATABASE, m_patterns->mysqlPort, NULL, 0)) -+ { -+ ERROR("Error connecting to provisioning db: %s", -+ mysql_error(my_handler)); -+ filename = failAnnouncement; -+ goto out; -+ } -+ if (mysql_options(my_handler, MYSQL_OPT_RECONNECT, &recon) != 0) -+ { -+ ERROR("Error setting reconnect-option for provisioning db: %s", -+ mysql_error(my_handler)); -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ subId = getSubscriberId(my_handler, uuid.c_str(), -+ &domain, domId, profId, &username); -+ if (!subId) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ DBG("Trigger VSC for uuid '%s' (sid='%llu')\n", -+ uuid.c_str(), (unsigned long long int)subId); -+ -+ setReceiving(false); -+ -+ 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)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ 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 attId = getAttributeId(my_handler, "cfu"); -+ 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) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ else if (!foundPref) -+ { -+ if (!insertPreference(my_handler, subId, attId, mapStr)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ INFO("Successfully set VSC CFU to '%s' using mapping id '%llu' for uuid '%s'", -+ uri.c_str(), (unsigned long long int)mapId, uuid.c_str()); -+ } -+ else -+ { -+ if (!updatePreferenceId(my_handler, prefId, mapStr)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ INFO("Successfully updated VSC CFU to '%s' using mapping id '%llu' for uuid '%s'", -+ uri.c_str(), (unsigned long long int)mapId, uuid.c_str()); -+ } -+ -+ filename = cfuOnAnnouncement; -+ goto out; -+ } -+ else if (ret != REG_NOMATCH) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ if ((ret = regexec(&m_patterns->cfuOffPattern, -+ req.user.c_str(), 0, 0, 0)) == 0) -+ { -+ if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFU, "cfu")) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ u_int64_t attId = getAttributeId(my_handler, "cfu"); -+ 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 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; -+ } -+ else if (ret != REG_NOMATCH) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ 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)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ 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 attId = getAttributeId(my_handler, "cfb"); -+ 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) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ else if (!foundPref) -+ { -+ if (!insertPreference(my_handler, subId, attId, mapStr)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ INFO("Successfully set VSC CFB to '%s' for uuid '%s'", -+ uri.c_str(), uuid.c_str()); -+ } -+ else -+ { -+ if (!updatePreferenceId(my_handler, prefId, mapStr)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ INFO("Successfully updated VSC CFB to '%s' for uuid '%s'", -+ uri.c_str(), uuid.c_str()); -+ } -+ -+ filename = cfbOnAnnouncement; -+ goto out; -+ } -+ else if (ret != REG_NOMATCH) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ if ((ret = regexec(&m_patterns->cfbOffPattern, -+ req.user.c_str(), 0, 0, 0)) == 0) -+ { -+ if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFB, "cfb")) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ u_int64_t attId = getAttributeId(my_handler, "cfb"); -+ 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 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; -+ } -+ else if (ret != REG_NOMATCH) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ if ((ret = regexec(&m_patterns->cftOnPattern, -+ req.user.c_str(), 0, 0, 0)) == 0) -+ { -+ 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'", -+ tim.c_str(), req.user.c_str(), uuid.c_str()); -+ -+ if (!number2uri(req, my_handler, uuid, subId, domain, -+ domId, timend + 1, uri, username)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ u_int64_t mapId = createCFMap(my_handler, subId, uri, -+ SW_VSC_DESTSET_CFT, "cft"); -+ if (!mapId) -+ { -+ 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, "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) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ else if (!foundPref) -+ { -+ if (!insertPreference(my_handler, subId, attId, mapStr)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ INFO("Successfully set VSC CFT to '%s' for uuid '%s'", -+ uri.c_str(), uuid.c_str()); -+ } -+ else -+ { -+ if (!updatePreferenceId(my_handler, prefId, mapStr)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ INFO("Successfully updated VSC CFT to '%s' for uuid '%s'", -+ uri.c_str(), uuid.c_str()); -+ } -+ -+ 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) -+ { -+ if (!insertPreference(my_handler, subId, attId, tim)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ INFO("Successfully set VSC ringtimeout to '%s' for uuid '%s'", -+ tim.c_str(), uuid.c_str()); -+ } -+ else -+ { -+ if (!updatePreferenceId(my_handler, prefId, tim)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ INFO("Successfully updated VSC ringtimeout to '%s' for uuid '%s'", -+ tim.c_str(), uuid.c_str()); -+ } -+ -+ filename = cftOnAnnouncement; -+ goto out; -+ } -+ else if (ret != REG_NOMATCH) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ if ((ret = regexec(&m_patterns->cftOffPattern, -+ req.user.c_str(), 0, 0, 0)) == 0) -+ { -+ 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) -+ { -+ 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"); -+ 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()); -+ } -+ -+ -+ filename = cftOffAnnouncement; -+ goto out; -+ } -+ else if (ret != REG_NOMATCH) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ 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)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ 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 attId = getAttributeId(my_handler, "cfna"); -+ 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) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ else if (!foundPref) -+ { -+ if (!insertPreference(my_handler, subId, attId, mapStr)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ INFO("Successfully set VSC CFNA to '%s' for uuid '%s'", -+ uri.c_str(), uuid.c_str()); -+ } -+ else -+ { -+ if (!updatePreferenceId(my_handler, prefId, mapStr)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ INFO("Successfully updated VSC CFNA to '%s' for uuid '%s'", -+ uri.c_str(), uuid.c_str()); -+ } -+ -+ filename = cfnaOnAnnouncement; -+ goto out; -+ } -+ else if (ret != REG_NOMATCH) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ if ((ret = regexec(&m_patterns->cfnaOffPattern, -+ req.user.c_str(), 0, 0, 0)) == 0) -+ { -+ if (!deleteCFMap(my_handler, subId, SW_VSC_DESTSET_CFNA, "cfna")) -+ { -+ 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; -+ } -+ else if (ret != REG_NOMATCH) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ if ((ret = regexec(&m_patterns->speedDialPattern, -+ req.user.c_str(), 0, 0, 0)) == 0) -+ { -+ string slot = string("*") + req.user.substr(4, 1); -+ if (!number2uri(req, my_handler, uuid, subId, domain, domId, 5, -+ uri, username)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ if (!insertSpeedDialSlot(my_handler, subId, slot, uri)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ else -+ { -+ INFO("Successfully set speed-dial slot '%s' for uuid '%s'", -+ slot.c_str(), uuid.c_str()); -+ } -+ -+ filename = speedDialAnnouncement; -+ goto out; -+ } -+ else if (ret != REG_NOMATCH) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ if ((ret = regexec(&m_patterns->reminderOnPattern, -+ req.user.c_str(), 0, 0, 0)) == 0) -+ { -+ int hour, min; -+ string tim; char c_tim[6] = ""; -+ hour = atoi(req.user.substr(4, 2).c_str()); -+ min = atoi(req.user.substr(6, 2).c_str()); -+ -+ if (hour < 0 || hour > 23) -+ { -+ filename = failAnnouncement; -+ INFO("Invalid hour '%s' in reminder data for uuid '%s'", -+ req.user.substr(4, 2).c_str(), uuid.c_str()); -+ goto out; -+ } -+ if (min < 0 || min > 59) -+ { -+ filename = failAnnouncement; -+ INFO("Invalid minute '%s' in reminder data for uuid '%s'", -+ req.user.substr(6, 2).c_str(), uuid.c_str()); -+ goto out; -+ } -+ snprintf(c_tim, sizeof(c_tim), "%02d:%02d", hour, min); -+ tim = string(c_tim); -+ string recur("never"); -+ -+ if (!insertReminder(my_handler, subId, recur, tim)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ else -+ { -+ INFO("Successfully set reminder at '%s' for uuid '%s'", -+ c_tim, uuid.c_str()); -+ } -+ -+ filename = reminderOnAnnouncement; -+ goto out; -+ } -+ else if (ret != REG_NOMATCH) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ if ((ret = regexec(&m_patterns->reminderOffPattern, -+ req.user.c_str(), 0, 0, 0)) == 0) -+ { -+ if (!deleteReminder(my_handler, subId)) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ else -+ { -+ INFO("Successfully deleted reminder for uuid '%s'", -+ uuid.c_str()); -+ } -+ -+ filename = reminderOffAnnouncement; -+ goto out; -+ } -+ else if (ret != REG_NOMATCH) -+ { -+ filename = failAnnouncement; -+ goto out; -+ } -+ -+ -+ -+ INFO("Unkown VSC code '%s' found", req.user.c_str()); -+ filename = unknownAnnouncement; -+ -+out: -+ -+ if (my_handler != NULL) -+ { -+ mysql_close(my_handler); -+ } -+ if (m_wav_file.open(filename, AmAudioFile::Read)) -+ throw string("SW_VscDialog::onSessionStart: Cannot open file\n"); -+ -+ -+ setOutput(&m_wav_file); -+ -+ AmSession::onInvite(req); -+} -+ -+void SW_VscDialog::onBye(const AmSipRequest &req) -+{ -+ DBG("onBye: stopSession\n"); -+ AmSession::onBye(req); -+} -+ -+ -+void SW_VscDialog::process(AmEvent *event) -+{ -+ -+ AmAudioEvent *audio_event = dynamic_cast(event); -+ if (audio_event && (audio_event->event_id == AmAudioEvent::cleared)) -+ { -+ dlg->bye(); -+ setStopped(); -+ return; -+ } -+ -+ AmSession::process(event); -+} -+ -+inline UACAuthCred *SW_VscDialog::getCredentials() -+{ -+ return cred.get(); -+} ---- /dev/null -+++ b/apps/sw_vsc/SW_Vsc.h -@@ -0,0 +1,134 @@ -+#ifndef _SW_VSC_H_ -+#define _SW_VSC_H_ -+ -+#include "AmSession.h" -+#include "AmConfigReader.h" -+#include "AmAudioFile.h" -+#include "AmUACAuth.h" -+ -+#include "ampi/UACAuthAPI.h" -+#include -+using std::string; -+ -+#include -+#include -+ -+#include -+ -+typedef struct -+{ -+ -+ string mysqlHost; -+ int mysqlPort; -+ string mysqlUser; -+ string mysqlPass; -+ -+ string audioPath; -+ -+ string failAnnouncement; -+ string unknownAnnouncement; -+ string voicemailNumber; -+ -+ regex_t cfuOnPattern; -+ string cfuOnAnnouncement; -+ -+ regex_t cfuOffPattern; -+ string cfuOffAnnouncement; -+ -+ regex_t cfbOnPattern; -+ string cfbOnAnnouncement; -+ -+ regex_t cfbOffPattern; -+ string cfbOffAnnouncement; -+ -+ regex_t cftOnPattern; -+ string cftOnAnnouncement; -+ -+ regex_t cftOffPattern; -+ string cftOffAnnouncement; -+ -+ regex_t cfnaOnPattern; -+ string cfnaOnAnnouncement; -+ -+ regex_t cfnaOffPattern; -+ string cfnaOffAnnouncement; -+ -+ regex_t speedDialPattern; -+ string speedDialAnnouncement; -+ -+ regex_t reminderOnPattern; -+ string reminderOnAnnouncement; -+ -+ regex_t reminderOffPattern; -+ string reminderOffAnnouncement; -+} sw_vsc_patterns_t; -+ -+class SW_VscFactory: public AmSessionFactory -+{ -+ inline string getAnnounceFile(const AmSipRequest &req); -+ -+ sw_vsc_patterns_t m_patterns; -+ -+public: -+ -+ SW_VscFactory(const string &_app_name); -+ virtual ~SW_VscFactory(); -+ -+ int onLoad(); -+ AmSession *onInvite(const AmSipRequest &req, const string &app_name, -+ const map &app_params); -+ AmSession *onInvite(const AmSipRequest &req, const string &app_name, -+ AmArg &session_params); -+ -+}; -+ -+class SW_VscDialog : public AmSession, -+ public CredentialHolder -+{ -+ AmAudioFile m_wav_file; -+ -+ sw_vsc_patterns_t *m_patterns; -+ -+ std::auto_ptr cred; -+ -+ u_int64_t getAttributeId(MYSQL *my_handler, const char *attribute); -+ u_int64_t getSubscriberId(MYSQL *my_handler, const char *uuid, -+ string *domain, u_int64_t &domain_id, -+ u_int64_t &profile_id, string *username); -+ u_int64_t getPreference(MYSQL *my_handler, u_int64_t subscriberId, u_int64_t attributeId, -+ int *foundPref, string *value); -+ int deletePreferenceId(MYSQL *my_handler, u_int64_t preferenceId); -+ int insertPreference(MYSQL *my_handler, u_int64_t subscriberId, -+ u_int64_t attributeId, string &uri); -+ int updatePreferenceId(MYSQL *my_handler, u_int64_t preferenceId, string &uri); -+ int insertSpeedDialSlot(MYSQL *my_handler, u_int64_t subscriberId, string &slot, string &uri); -+ int insertReminder(MYSQL *my_handler, u_int64_t subscriberId, string &repeat, string &tim); -+ int deleteReminder(MYSQL *my_handler, u_int64_t subscriberId); -+ int number2uri(const AmSipRequest &req, MYSQL *my_handler, string &uuid, u_int64_t subId, -+ string &domain, u_int64_t domId, int offset, string &uri, -+ string &username); -+ int checkSubscriberProfile(MYSQL *my_handler, u_int64_t profileId, u_int64_t attributeId); -+ u_int64_t createCFMap(MYSQL *my_handler, u_int64_t subscriberId, string &uri, -+ const char *mapName, const char *type); -+ u_int64_t deleteCFMap(MYSQL *my_handler, u_int64_t subscriberId, -+ const char *mapName, const char *type); -+ -+ -+ -+public: -+ SW_VscDialog(sw_vsc_patterns_t *patterns, -+ UACAuthCred *credentials = NULL); -+ ~SW_VscDialog(); -+ -+ void onSessionStart(); -+ void onStart(); -+ void onInvite(const AmSipRequest &req); -+ void onBye(const AmSipRequest &req); -+ void onDtmf(int event, int duration_msec) {} -+ -+ void process(AmEvent *event); -+ -+ UACAuthCred *getCredentials(); -+}; -+ -+#endif ---- /dev/null -+++ b/apps/sw_vsc/etc/sw_vsc.conf -@@ -0,0 +1,40 @@ -+mysql_host = 127.0.0.1 -+mysql_port = 3306 -+mysql_user = soap -+mysql_pass = s:wMP4Si -+ -+announce_path = /usr/lib/sems/audio/ -+ -+error_announcement = sw_vsc_error.wav -+unknown_announcement = sw_vsc_unavailable.wav -+ -+voicemail_number = 2000 -+ -+cfu_on_pattern = ^\*72\*[0-9]+$ -+cfu_on_announcement = sw_vsc_activated.wav -+cfu_off_pattern = ^(\%23)72(\%23)?.*$ -+cfu_off_announcement = sw_vsc_deactivated.wav -+ -+cfb_on_pattern = ^\*90\*[0-9]+$ -+cfb_on_announcement = sw_vsc_activated.wav -+cfb_off_pattern = ^(\%23)90(\%23)?.*$ -+cfb_off_announcement = sw_vsc_deactivated.wav -+ -+cft_on_pattern = ^\*92\*[0-9]+\*[0-9]+$ -+cft_on_announcement = sw_vsc_activated.wav -+cft_off_pattern = ^(\%23)92(\%23)?.*$ -+cft_off_announcement = sw_vsc_deactivated.wav -+ -+cfna_on_pattern = ^\*93\*[0-9]+$ -+cfna_on_announcement = sw_vsc_activated.wav -+cfna_off_pattern = ^(\%23)93(\%23)?.*$ -+cfna_off_announcement = sw_vsc_deactivated.wav -+ -+speed_dial_pattern = ^\*50\*[0-9]+$ -+speed_dial_announcement = sw_vsc_activated.wav -+ -+reminder_on_pattern = ^\*55\*[0-9]+$ -+reminder_on_announcement = sw_vsc_activated.wav -+reminder_off_pattern = ^(\%23)55(\%23)?.*$ -+reminder_off_announcement = sw_vsc_deactivated.wav -+ diff --git a/debian/patches/sipwise/tt52455.patch b/debian/patches/sipwise/tt52455.patch deleted file mode 100644 index a8b0f924..00000000 --- a/debian/patches/sipwise/tt52455.patch +++ /dev/null @@ -1,46 +0,0 @@ -From d7bce5145bb852a9cf439326bb33e5a142b6a2e1 Mon Sep 17 00:00:00 2001 -From: Roman Romanchenko -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(); - diff --git a/debian/patches/sipwise/upgrade_to_bullseye.patch b/debian/patches/sipwise/upgrade_to_bullseye.patch deleted file mode 100644 index 1fabfa70..00000000 --- a/debian/patches/sipwise/upgrade_to_bullseye.patch +++ /dev/null @@ -1,19 +0,0 @@ -From 1619876f76da9ac3530b3524795ba06ddcfdab09 Mon Sep 17 00:00:00 2001 -From: Roman Romanchenko -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) - # diff --git a/debian/patches/sipwise/usage-reporting.patch b/debian/patches/sipwise/usage-reporting.patch deleted file mode 100644 index 3000f88f..00000000 --- a/debian/patches/sipwise/usage-reporting.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 944cf94dcd2ad44e66b895682329ead001c72546 Mon Sep 17 00:00:00 2001 -From: Richard Fuchs -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 - #include - #include -+#include -+#include -+#include - - 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() { diff --git a/debian/patches/upstream/0000-b-f-sbc-fixed-reading-encoding-param-in-readPayload.patch b/debian/patches/upstream/0000-b-f-sbc-fixed-reading-encoding-param-in-readPayload.patch deleted file mode 100644 index 24b1ec80..00000000 --- a/debian/patches/upstream/0000-b-f-sbc-fixed-reading-encoding-param-in-readPayload.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 09dca94aa38c3e9ec5efc9b3c119fa97ce404bed Mon Sep 17 00:00:00 2001 -From: Raphael Coeffic -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 - diff --git a/debian/patches/upstream/0001-b-f-sbc-codecs-compare-encoding_param-only-if-both-0.patch b/debian/patches/upstream/0001-b-f-sbc-codecs-compare-encoding_param-only-if-both-0.patch deleted file mode 100644 index 8ebd0eed..00000000 --- a/debian/patches/upstream/0001-b-f-sbc-codecs-compare-encoding_param-only-if-both-0.patch +++ /dev/null @@ -1,27 +0,0 @@ -From b722a91680499851990c192a7023cecb0ef04609 Mon Sep 17 00:00:00 2001 -From: Stefan Sayer -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& 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 - diff --git a/debian/patches/upstream/0002-core-codec-init-support-for-fmt-params-negotiation-f.patch b/debian/patches/upstream/0002-core-codec-init-support-for-fmt-params-negotiation-f.patch deleted file mode 100644 index 8ee249f6..00000000 --- a/debian/patches/upstream/0002-core-codec-init-support-for-fmt-params-negotiation-f.patch +++ /dev/null @@ -1,773 +0,0 @@ -From 03cd08e1f0f05d5477e797d5184cec61544b0e55 Mon Sep 17 00:00:00 2001 -From: Stefan Sayer -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 &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::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 - * - * - * -@@ -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 - diff --git a/debian/patches/upstream/0003-core-amci-call-codec-module-init-function-with-mod_c.patch b/debian/patches/upstream/0003-core-amci-call-codec-module-init-function-with-mod_c.patch deleted file mode 100644 index 701d76c1..00000000 --- a/debian/patches/upstream/0003-core-amci-call-codec-module-init-function-with-mod_c.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 42df04a7b48e5a98ad73e003affebc77a10697d5 Mon Sep 17 00:00:00 2001 -From: Stefan Sayer -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 - diff --git a/debian/patches/upstream/0004-core-rtp-stream-take-fmt-params-in-payload-initializ.patch b/debian/patches/upstream/0004-core-rtp-stream-take-fmt-params-in-payload-initializ.patch deleted file mode 100644 index 644eee66..00000000 --- a/debian/patches/upstream/0004-core-rtp-stream-take-fmt-params-in-payload-initializ.patch +++ /dev/null @@ -1,63 +0,0 @@ -From c7800eabce5aeb190dc57484d1b550a81035f409 Mon Sep 17 00:00:00 2001 -From: Stefan Sayer -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 - diff --git a/debian/patches/upstream/0005-opus-configurable-codec-settings-for-OPUS-codec.patch b/debian/patches/upstream/0005-opus-configurable-codec-settings-for-OPUS-codec.patch deleted file mode 100644 index 62570b56..00000000 --- a/debian/patches/upstream/0005-opus-configurable-codec-settings-for-OPUS-codec.patch +++ /dev/null @@ -1,258 +0,0 @@ -From bbb13a13954da9e566b664f7916362dd0313e4d1 Mon Sep 17 00:00:00 2001 -From: Stefan Sayer -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 -+#include - - #define _OPUS_APPLICATION_ OPUS_APPLICATION_VOIP - /* Allowed values: -@@ -88,6 +89,10 @@ static long opus_create(const char* format_parameters, const char** format_param - amci_codec_fmt_info_t** format_description); - static void opus_destroy(long h_inst); - -+static int opus_negotiate_fmt(int is_offer, const char* params_in, char* params_out, unsigned int params_out_len); -+ -+static int opus_load(const char* ModConfigPath); -+ - #if SYSTEM_SAMPLECLOCK_RATE >= 48000 - #define _OPUS_RATE 48000 - #elif SYSTEM_SAMPLECLOCK_RATE >= 24000 -@@ -103,13 +108,14 @@ static void opus_destroy(long h_inst); - static amci_codec_fmt_info_t opus_fmt_description[] = { {AMCI_FMT_FRAME_LENGTH, 20}, - {AMCI_FMT_FRAME_SIZE, 20 * _OPUS_RATE / 1000}, {0,0}}; - --BEGIN_EXPORTS( "opus" , AMCI_NO_MODULEINIT, AMCI_NO_MODULEDESTROY ) -+BEGIN_EXPORTS( "opus" , opus_load, AMCI_NO_MODULEDESTROY ) - - BEGIN_CODECS -- CODEC( CODEC_OPUS, pcm16_2_opus, opus_2_pcm16, opus_plc, -+ CODEC_WITH_FMT( CODEC_OPUS, pcm16_2_opus, opus_2_pcm16, opus_plc, - opus_create, - opus_destroy, -- NULL, NULL ) -+ NULL, NULL , -+ opus_negotiate_fmt) - END_CODECS - - BEGIN_PAYLOADS -@@ -126,13 +132,155 @@ typedef struct { - OpusDecoder* opus_dec; - } opus_state_t; - -+/* e.g. "maxplaybackrate=8000; stereo=0; useinbandfec=1" */ -+char default_format_parameters[80]; -+ -+int opus_load(const char* ModConfigPath) { -+ default_format_parameters[0]='\0'; -+ char conf_file[256]; -+ if (NULL != ModConfigPath) { -+ sprintf(conf_file, "%sopus.conf",ModConfigPath); -+ FILE* fp = fopen(conf_file, "rt"); -+ if (fp) { -+ char line[80]; -+ while(fgets(line, 80, fp) != NULL) { -+ if (!line[0] ||line[0]=='#') -+ continue; -+ strcpy(default_format_parameters, line); -+ break; -+ } -+ DBG("initialized default format parameters as '%s'\n", default_format_parameters); -+ fclose(fp); -+ } -+ } -+ DBG("OPUS: initialized\n"); -+ return 0; -+} -+ -+int opus_negotiate_fmt(int is_offer, const char* params_in, char* params_out, unsigned int params_out_len) { -+ // todo: properly negotiating features -+ strncpy(params_out, default_format_parameters, params_out_len); -+ return 0; -+} -+ -+/* -+ Search for a parameter assignement in input string. -+ If it's not found *param_value is null, otherwise *param_value points to the -+ right hand term. -+ In both cases a pointer suitable for a new search is returned -+*/ -+static char* read_param(char* input, const char *param, char** param_value) -+{ -+ int param_size; -+ -+ /* Eat spaces and semi-colons */ -+ while (*input && (*input==' ' || *input==';' || *input=='"')) -+ input++; -+ -+ *param_value = NULL; -+ param_size = strlen(param); -+ if (strncmp(input, param, param_size)) -+ return input; -+ if (*(input+param_size) != '=') -+ return input; -+ input+=param_size+1; -+ -+ /* Found and discarded a matching parameter */ -+ *param_value = input; -+ while (*input && *input!=' ' && *input!=';' && *input!='"') -+ input++; -+ if (*input=='"') -+ { -+ *param_value = *param_value+1; /* remove " */ -+ /* string will end after next: " */ -+ while (*input && *input!='"' && *input!='\r' && *input!='\n') -+ input++; -+ if (*input=='"') -+ input--; /* remove " */ -+ } -+ if (*input) -+ *input++ = 0; -+ -+ return input; -+} -+ -+#define BLEN 63 -+ -+void decode_format_parameters(const char* format_parameters, unsigned int* maxbandwidth, int* useinbandfec, int* stereo) { -+ if (format_parameters && strlen(format_parameters)<=BLEN){ -+ -+ char buffer2[BLEN+1]; -+ char *buffer = buffer2; -+ -+ strcpy(buffer, format_parameters); -+ -+ while (*buffer) { -+ char *param_value; -+ -+ /* maxplaybackrate */ -+ buffer=read_param(buffer, "maxplaybackrate", ¶m_value); -+ if (param_value) { -+ *maxbandwidth = atoi(param_value); -+ if (!*maxbandwidth) { -+ *maxbandwidth = _OPUS_RATE; -+ DBG("wrong maxbandwidth value '%s'\n", param_value); -+ } -+ continue; -+ } -+ -+ /* stereo */ -+ buffer=read_param(buffer, "stereo", ¶m_value); -+ if (param_value) { -+ if (*param_value == '1') -+ *stereo = 1; -+ else -+ *stereo = 0; -+ -+ continue; -+ } -+ -+ /* useinbandfec */ -+ buffer=read_param(buffer, "useinbandfec", ¶m_value); -+ if (param_value) { -+ if (*param_value == '1') -+ *useinbandfec = 1; -+ else -+ *useinbandfec = 0; -+ -+ continue; -+ } -+ -+ /* Unknown parameter */ -+ if (*buffer) { -+ param_value = buffer; -+ while (*buffer && *buffer!=';') -+ buffer++; -+ -+ if (*buffer) -+ *buffer++ = 0; -+ -+ DBG("OPUS: SDP parameter fmtp: %s ignored in creating encoder.\n", param_value); -+ } -+ } -+ } -+} -+ -+ - long opus_create(const char* format_parameters, const char** format_parameters_out, - amci_codec_fmt_info_t** format_description) { - opus_state_t* codec_inst; - int error; -- -+ -+ unsigned int maxbandwidth = _OPUS_RATE; -+ int useinbandfec = _OPUS_INBAND_FEC_; -+ int stereo = 0; -+ - if (format_parameters) { -+ DBG("\n\n\n"); - DBG("OPUS params: >>%s<<.\n", format_parameters); -+ DBG("\n\n\n"); -+ -+ decode_format_parameters(format_parameters, &maxbandwidth, &useinbandfec, &stereo); - } - - codec_inst = (opus_state_t*)malloc(sizeof(opus_state_t)); -@@ -140,17 +288,34 @@ long opus_create(const char* format_parameters, const char** format_parameters_o - if (!codec_inst) - return -1; - -+ DBG("OPUS: creating encoder with maxbandwidth=%u, stereo=%s, useinbandfec=%s\n", -+ maxbandwidth, stereo?"true":"false", useinbandfec?"true":"false"); -+ - codec_inst->opus_enc = opus_encoder_create(_OPUS_RATE,1,_OPUS_APPLICATION_,&error); - if (error) { - DBG("OPUS: error %d while creating encoder state.\n", error); - return -1; - } - -- opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_FORCE_CHANNELS(1)); -- opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_MAX_BANDWIDTH(_OPUS_MAX_BANDWIDTH_)); -+ opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_FORCE_CHANNELS(stereo ? 2:1)); -+ -+ unsigned int opus_set_bw = _OPUS_RATE; -+ if (maxbandwidth <= 8000) { -+ opus_set_bw = OPUS_BANDWIDTH_NARROWBAND; -+ } else if (maxbandwidth <= 12000) { -+ opus_set_bw = OPUS_BANDWIDTH_MEDIUMBAND; -+ } else if (maxbandwidth <= 16000) { -+ opus_set_bw = OPUS_BANDWIDTH_WIDEBAND; -+ } else if (maxbandwidth <= 24000) { -+ opus_set_bw = OPUS_BANDWIDTH_SUPERWIDEBAND; -+ } else { -+ opus_set_bw = OPUS_BANDWIDTH_FULLBAND; -+ } -+ opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_MAX_BANDWIDTH(opus_set_bw)); -+ - opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_PACKET_LOSS_PERC(_OPUS_PKT_LOSS_PCT_)); - opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_COMPLEXITY(_OPUS_COMPLEXITY_)); -- opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_INBAND_FEC(_OPUS_INBAND_FEC_)); -+ opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_INBAND_FEC(useinbandfec ? 1:0)); - opus_encoder_ctl(codec_inst->opus_enc, OPUS_SET_DTX(_OPUS_DTX_)); - - codec_inst->opus_dec = opus_decoder_create(_OPUS_RATE,1,&error); --- -2.1.4 - diff --git a/debian/patches/upstream/0006-b-f-fixes-c7800ea-remove-leftover-stacktrace-in-setC.patch b/debian/patches/upstream/0006-b-f-fixes-c7800ea-remove-leftover-stacktrace-in-setC.patch deleted file mode 100644 index 8740b26e..00000000 --- a/debian/patches/upstream/0006-b-f-fixes-c7800ea-remove-leftover-stacktrace-in-setC.patch +++ /dev/null @@ -1,27 +0,0 @@ -From f407e4dfec0f9e011db94b847c9f6f4b9156af93 Mon Sep 17 00:00:00 2001 -From: Stefan Sayer -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 - diff --git a/debian/patches/upstream/0007-b-f-fix-bbb13a1-remove-excessive-debug-info.patch b/debian/patches/upstream/0007-b-f-fix-bbb13a1-remove-excessive-debug-info.patch deleted file mode 100644 index f329f058..00000000 --- a/debian/patches/upstream/0007-b-f-fix-bbb13a1-remove-excessive-debug-info.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0843bee8ae90a8d3cb35efa8485332b088e49183 Mon Sep 17 00:00:00 2001 -From: Stefan Sayer -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 - diff --git a/debian/patches/upstream/0008-fix-for-c++11.patch b/debian/patches/upstream/0008-fix-for-c++11.patch deleted file mode 100644 index 5c3c2205..00000000 --- a/debian/patches/upstream/0008-fix-for-c++11.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 4b2fc5d117242c659e4df0395c6e12f4fcb75edc Mon Sep 17 00:00:00 2001 -From: Peter Lemenkov -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(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(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 res = -- insert(make_pair(key,e)); -+ insert(make_pair(key,e)); - - if(res.second) { - inc_ref(e); diff --git a/debian/source/format b/debian/source/format index 163aaf8d..89ae9db8 100644 --- a/debian/source/format +++ b/debian/source/format @@ -1 +1 @@ -3.0 (quilt) +3.0 (native)
keyvalue
AMCI_FMT_FRAME_LENGTH (1) frame length in ms (for framed codecs; must be multiple of 10)
AMCI_FMT_FRAME_SIZE (2) frame size in samples